# Prefix and substring allowlist bypass

Allowlist checks using prefix, suffix, substring, or unanchored glob instead of exact normalized equality

_Area: Web access control and IDOR. Seen in 8 disclosed reports; 3 confirmed bounties, median $1,000, range $600-$6,000; latest 2026-10-19. Updated 2026-10-23._

## How it works
An access check decides whether a requested value is trusted by asking whether it *starts with*, *ends with*, *contains*, or *glob-matches* an allowed value, instead of comparing the whole value for exact equality. Any string that merely embeds the trusted value then passes. The broken assumption is that "contains the allowed name" equals "is the allowed name." It does not: `footer.php` starts with `foo`, `attacker.zoom.us` ends with `zoom.us`, and any URI containing a privileged path substring satisfies a `strings.Contains` gate [E4](https://bugbountylibrary.com/r/h1%3A214001.md)[E2](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-zoom-zero-day-followup-getting-the-rce.md)[E7](https://bugbountylibrary.com/r/blog%3Andevtk-github-io-writeups-2024-08-02-chromiuminfra.md).

## Where it shows up
- Path or filename checks using `startsWith`/prefix compare against a shared resource name [E4](https://bugbountylibrary.com/r/h1%3A214001.md)[E5](https://bugbountylibrary.com/r/blog%3Aembracethered-com-blog-posts-2025-anthropic-filesystem-mcp-server-bypass.md).
- Domain checks using `hasSuffix`/`endsWith`, or hand-rolled URL regexes that disagree with the browser parser on authority terminators [E2](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-zoom-zero-day-followup-getting-the-rce.md)[E1](https://bugbountylibrary.com/r/blog%3Abugs-xdavidhu-me-google-2020-03-08-the-unexpected-google-wide-domain-check-bypass.md).
- Auth gates keyed on `strings.Contains(requestURI, ...)` rather than exact path equality [E7](https://bugbountylibrary.com/r/blog%3Andevtk-github-io-writeups-2024-08-02-chromiuminfra.md).
- Unanchored glob rules (`/*/membership/*`) satisfied by appending the segment to any URL [E6](https://bugbountylibrary.com/r/h1%3A703058.md).
- Double-decoding where the ACL matcher and the parser normalize differently [E3](https://bugbountylibrary.com/r/h1%3A824203.md).

## How to review
Find every allowlist and confirm the comparison is exact equality on a normalized value, not prefix/suffix/substring/unanchored glob. The invariant: the value that passed the check must be byte-identical (after canonicalization) to the value actually used downstream. Enumerate all call sites of the comparison helper and diff the normalizer used for validation against the one used for the action. For paths, require a separator boundary or realpath containment, not a bare prefix [E5](https://bugbountylibrary.com/r/blog%3Aembracethered-com-blog-posts-2025-anthropic-filesystem-mcp-server-bypass.md). For domains, reject embedded trusted names in path or subdomain position [E2](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-zoom-zero-day-followup-getting-the-rce.md). For globs, confirm anchoring [E6](https://bugbountylibrary.com/r/h1%3A703058.md). Note the inverse risk: exact-match on unnormalized values also breaks (trailing slash, case, encoding), so normalize once and compare once [E3](https://bugbountylibrary.com/r/h1%3A824203.md).

## Variants seen
- Prefix match on file path: shared `foo` exposes `footer.php` and `foobar/` [E4](https://bugbountylibrary.com/r/h1%3A214001.md).
- Prefix match on directory: sibling `data-archived` passes a `data` allowlist [E5](https://bugbountylibrary.com/r/blog%3Aembracethered-com-blog-posts-2025-anthropic-filesystem-mcp-server-bypass.md).
- Suffix match on domain: `attacker.zoom.us` and `evil.com/.zoom.us` pass [E2](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-zoom-zero-day-followup-getting-the-rce.md).
- Parser differential: regex authority terminator set differs from browser, bypassing domain whitelist [E1](https://bugbountylibrary.com/r/blog%3Abugs-xdavidhu-me-google-2020-03-08-the-unexpected-google-wide-domain-check-bypass.md).
- Substring match on request URI for an auth gate [E7](https://bugbountylibrary.com/r/blog%3Andevtk-github-io-writeups-2024-08-02-chromiuminfra.md).
- Unanchored glob rule plus framework path-after-extension quirk [E6](https://bugbountylibrary.com/r/h1%3A703058.md).
- Double-decoding mismatch between ACL matcher and URL parser [E3](https://bugbountylibrary.com/r/h1%3A824203.md).

## Why fixes fail
Fixes that patch one comparison site leave sibling checks (other endpoints, other parsers) using the same weak match; enforcement must be centralized and tested per code path [E6](https://bugbountylibrary.com/r/h1%3A703058.md)[E3](https://bugbountylibrary.com/r/h1%3A824203.md).

## Impact and severity
Ranged from cross-tenant file read [E4](https://bugbountylibrary.com/r/h1%3A214001.md)[E5](https://bugbountylibrary.com/r/blog%3Aembracethered-com-blog-posts-2025-anthropic-filesystem-mcp-server-bypass.md) and ban bypass [E6](https://bugbountylibrary.com/r/h1%3A703058.md) to auth-database read [E7](https://bugbountylibrary.com/r/blog%3Andevtk-github-io-writeups-2024-08-02-chromiuminfra.md), API key theft [E1](https://bugbountylibrary.com/r/blog%3Abugs-xdavidhu-me-google-2020-03-08-the-unexpected-google-wide-domain-check-bypass.md), macOS RCE [E2](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-zoom-zero-day-followup-getting-the-rce.md), and proxy ACL bypass [E3](https://bugbountylibrary.com/r/h1%3A824203.md). Severity rises when the bypassed check guards a privileged or cross-tenant action, and when the trusted value is easy to embed (short names, common domains).

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Abugs-xdavidhu-me-google-2020-03-08-the-unexpected-google-wide-domain-check-bypass.md
- E2: https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-zoom-zero-day-followup-getting-the-rce.md
- E3: https://bugbountylibrary.com/r/h1%3A824203.md
- E4: https://bugbountylibrary.com/r/h1%3A214001.md
- E5: https://bugbountylibrary.com/r/blog%3Aembracethered-com-blog-posts-2025-anthropic-filesystem-mcp-server-bypass.md
- E6: https://bugbountylibrary.com/r/h1%3A703058.md
- E7: https://bugbountylibrary.com/r/blog%3Andevtk-github-io-writeups-2024-08-02-chromiuminfra.md
