Skip to main content

UrlStrategy

Enum UrlStrategy 

Source
pub enum UrlStrategy {
    PercentEncodeAggressive,
    DoublePercentEncode,
    NonCanonicalSpaces,
    Hpp,
}
Expand description

Per-value mutation choice.

Variants§

§

PercentEncodeAggressive

Percent-encode every byte that isn’t alphanumeric. Most signatures match decoded payloads but verify by raw-byte regex — this breaks both checks at once.

§

DoublePercentEncode

Double-percent-encode (%%25, then percent-encode again). Bypasses URL-decode-then-match WAFs that decode exactly once.

§

NonCanonicalSpaces

Mix in + for spaces, 0x2F for /, etc. — non-canonical encodings that some upstream parsers normalise but signatures don’t.

§

Hpp

Insert empty PHP-style array brackets [] after the param name to force HTTP Parameter Pollution path.

Audit (2026-05-10): NOT YET IMPLEMENTED. apply_bytes only receives the value — the (name, value) pair lives one layer up in mutate_query_string. The current behaviour is a value pass-through, which is a stub. Selecting this strategy will log a tracing::warn but otherwise return the value unchanged so existing callers don’t break. Real HPP needs a query-level mutator that operates on the pair list — track via a dedicated query_pollute_pairs() function rather than as a UrlStrategy variant.

Implementations§

Source§

impl UrlStrategy

Source

pub fn apply(self, value: &str) -> String

Apply the strategy to a single decoded value, returning the mutated raw form (already URL-safe — caller does not re-encode).

Source

pub fn apply_bytes(self, value: &[u8]) -> String

Byte-clean variant of Self::apply for percent-encoding strategies. Lets callers run a non-UTF-8 byte sequence (e.g. the raw bytes from a percent-decode on %FF%FE) through the pipeline without it being silently rewritten to U+FFFD by String::from_utf8_lossy. Each strategy that only operates on bytes (PercentEncodeAggressive, DoublePercentEncode) is byte-pure here. Strategies that need character semantics (NonCanonicalSpaces) lossy-convert internally.

Source

pub fn apply_bytes_with_label(self, value: &[u8]) -> (String, &'static str)

Apply the strategy and return BOTH the encoded output AND the label that honestly describes what was done. For most strategies this is just Self::label(), but DoublePercentEncode silently downgrades to single-percent encoding above MAX_DOUBLE_ENCODE_INPUT (to avoid 9× output blowup) — pre-fix the technique log still reported url:double_percent even though only one pass ran, poisoning every WAF-decay statistic. Now the downgrade is surfaced via url:double_percent_downgraded so callers (and the gene-bank) see what actually shipped.

Audit (2026-05-10).

Source

pub fn label(self) -> &'static str

Stable name used for technique logging.

Trait Implementations§

Source§

impl Clone for UrlStrategy

Source§

fn clone(&self) -> UrlStrategy

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for UrlStrategy

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for UrlStrategy

Source§

fn eq(&self, other: &UrlStrategy) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Copy for UrlStrategy

Source§

impl Eq for UrlStrategy

Source§

impl StructuralPartialEq for UrlStrategy

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more