Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions src/pentesting-web/proxy-waf-protections-bypass.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,40 @@ A compact review workflow is to log and compare the original URI, normalized URI

When this bypass exposes a dangerous internal handler, assess the reached primitive rather than repeating it here: [SQL injection](sql-injection/README.md), [command injection](command-injection.md), [JWT secret compromise](hacking-jwt-json-web-tokens.md), or [sudo command abuse](../linux-hardening/main-system-information/sudo-command-abuse.md).<sup>[[15]](#references)</sup>

### Semicolon path parameters + `Forwarded` quoted-pair differential

A useful variant exists when the edge applies a raw prefix denylist but a Java servlet container removes semicolon path parameters before dispatch. For example, an edge rule blocking `/dms/services` does not match `/dms;/services/ServerUI`, while Jetty can derive `/dms/services/ServerUI` and dispatch it to the protected servlet. Insert `;` at several segment boundaries and compare the protected baseline with each mutated path; also try mappings whose protected prefix begins later in the URI.<sup>[[16]](#references)</sup>

A second differential may be required when the reached handler trusts only loopback clients. In this request, an RFC-style quoted-string parser consumes `\1` as a quoted-pair and obtains `127.0.0.1`, but an independent application parser can retain the backslash and obtain the invalid address `127.0.0.\1`:<sup>[[16]](#references)</sup>

```http
POST /dms;/services/ServerUI HTTP/1.1
Host: target
Forwarded: for="127.0.0.\1"
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
```

This becomes exploitable if the container installs its parsed value as the request's remote address while the authorization filter reparses the original header. A filter that rejects only values positively recognized as loopback **fails open** on the malformed representation; a later `isLocalhost(request)` check then sees the container's normalized `127.0.0.1` and grants local-only access. The path and identity discrepancies can be interdependent: the semicolon alone reaches the backend as a remote client, whereas the header alone is stopped by the edge path rule.<sup>[[16]](#references)</sup>

Use a small differential matrix rather than testing only the combined payload: protected path/no header, semicolon path/no header, protected path/quoted-pair header, and semicolon path/quoted-pair header. Capture the raw request target, edge-selected route, backend decoded/servlet path, socket peer, container remote address, and application-parsed forwarding values for every case. Reject malformed forwarding values, strip client-supplied forwarding headers at the trusted edge, and make authorization and routing consume the same canonical path and client-identity object.<sup>[[16]](#references)</sup>

### Exception paths that retain a pre-login identity binding

After a routing differential exposes an internal [SOAP/API endpoint](../network-services-pentesting/pentesting-web/web-api-pentesting.md), inspect whether a session-initialization method issues a usable **pre-login** session. Then review every authentication method for state changes made before credential/MFA verification. A dangerous sequence is `bindUser(session, requestedUser)` followed by authentication, with session invalidation only in the ordinary rejection branch: an exception or SOAP fault skips cleanup and leaves the chosen identity attached to the session.<sup>[[16]](#references)</sup>

```java
bindUser(sessionId, requestedUserId); // privileged state change
try {
result = authenticate(user, suppliedSecret);
if (!result.isSuccess()) invalidate(sessionId);
} catch (Exception ex) {
throw soapFault(ex); // identity remains bound
}
```

Test deterministic exceptional states such as a missing optional legacy MFA/provider profile, especially for built-in identities with predictable IDs. After receiving the expected fault, replay a harmless authenticated operation with the same session ID; success demonstrates persisted authentication state rather than a mere error. Continue the broader assessment using the [login-bypass methodology](login-bypass/README.md). Fix the flow by binding the identity only after all factors succeed, or by rolling back/invalidation on **every** failure and exception path.<sup>[[16]](#references)</sup>

## Bypass Mod Security Rules <a href="#heading-bypassing-aws-waf-acl" id="heading-bypassing-aws-waf-acl"></a>

### Path Confusion
Expand Down Expand Up @@ -372,5 +406,6 @@ data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+ #base64 encoding the javascri
- [13] [PortSwigger Bypass Bot Detection extension](https://github.com/PortSwigger/bypass-bot-detection)
- [14] [When a Web App Detects Burp Suite via TLS Fingerprinting](https://kecman.co/blog/burp-suite-tls-fingerprint-bot-detection-bypass.html)
- [15] [Pre-Auth RCE in UniFi OS — One Request to Root Behind Seven Products](https://catchify.sa/post/pre-auth-rce-unifi-os-one-request-to-root)
- [16] [CVE-2026-86206, CVE-2026-86207: N-able N-central Authentication Bypass](https://www.rapid7.com/blog/post/ve-cve-2026-86206-cve-2026-86207-n-able-n-central-authentication-bypass-fixed/)

{{#include ../banners/hacktricks-training.md}}