scan

package
v0.6.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 6, 2026 License: MIT Imports: 0 Imported by: 0

Documentation

Overview

Package scan covers a whole value with bounded work.

The bug this exists to remove

Every semantic detector bounded its analysis with a constant named maxScan and implemented it as `src = src[:maxScan]`. The reasoning written beside each one was sound and is still true — "every signal is local to one command", "a payload declares itself early" — but it justifies a bounded *window*, not a bounded *prefix*. A payload does not need to be longer than the bound. It only needs to sit past it.

Measured, with the payload placed after N bytes of ordinary text:

phpi     8 KiB   missed at 16 KiB of padding
javaser  8 KiB   missed at 16 KiB
ldapi    8 KiB   missed at 16 KiB
shelli  64 KiB   missed at 128 KiB
xss     64 KiB   missed at 128 KiB
ssti    64 KiB   missed at 128 KiB

Six of seven classes, each at exactly its own constant. This is the technique the 2026 literature calls the WAF blind spot, and gwaf's answer to it — refusing to truncate an oversize body — was correct at the transaction layer and absent one level down. transaction.go's noteOversize states the rule plainly: "Inspecting the first 64 KiB of a value and reporting the request as clean is a bypass with a padding step." The detectors were doing exactly that.

Why windows rather than no bound at all

Unbounded analysis is the other failure: an attacker sends a large value and chooses how much work the firewall does. Bounded everything is not negotiable (CLAUDE.md §2). Windowing keeps the per-window bound that made the detectors affordable and pays a linear cost in the value's length, which is a cost the fuel meter already prices per byte — so a value large enough to matter exhausts the budget and the configured FailMode decides, rather than the value being silently reported clean.

Why locality makes this lossless

Overlap is what turns "scan each window" into "scan the value". A signal spanning a window boundary would be split and missed, so consecutive windows overlap by more than the longest signal any detector can produce. The detectors' own comments are the argument that such a bound exists: a command name is bounded by maxTokenLen, a serialization header declares itself in a few dozen bytes, a tag is shorter than the overlap by orders of magnitude.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Windows

func Windows(src []byte, window int, fn func(off int, w []byte) bool)

Windows calls fn with successive overlapping views of src, stopping early if fn returns false.

The int passed to fn is the window's offset within src, so a span reported against the window can be translated back to the value the caller was given. Reporting a span relative to a window would put the highlight in the wrong place in an audit log, which is the kind of detail that makes an operator stop trusting the tool.

A value that fits in one window is passed through unchanged and uncopied, so the overwhelmingly common case costs one comparison.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL