From 92202f55f23d5a1c05924e2097066ddc6d0850ad Mon Sep 17 00:00:00 2001 From: Emilio Ranucoli Date: Sat, 6 Jun 2026 06:13:28 -0300 Subject: [PATCH] feat(api-security): add effective method and route normalization gates Adds Step 1A to the API security review workflow covering: - Method override discovery (X-HTTP-Method-Override, _method, framework filters) - Gateway/CDN route rewrite authorization consistency - Route normalization (encoded slashes, duplicate slashes, case, semicolons) - OpenAPI-vs-code method drift detection - Authorization placement verification (pre- vs post-rewrite) Also adds: - Item 8 to Step 1 inventory for documenting effective method/route handling - Vulnerable and benign examples for reviewer calibration - Detection grep patterns for method override and normalization code - Framework-specific guidance table (Spring, Express, Django, ASP.NET, Go, nginx) - Severity criteria mapping to API1/API5/API8/API9 - Normalization verification checklist (7 items) - Common Pitfalls #7: pre-rewrite authorization bypass - Updated API5 reference table entry - OWASP API5 and RFC 9110 references Closes #1283 --- skills/appsec/api-security/SKILL.md | 117 +++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-) diff --git a/skills/appsec/api-security/SKILL.md b/skills/appsec/api-security/SKILL.md index cbb125aa..1facf215 100644 --- a/skills/appsec/api-security/SKILL.md +++ b/skills/appsec/api-security/SKILL.md @@ -38,9 +38,120 @@ Before analyzing any endpoint, establish a complete inventory of the API surface 5. **Catalog data objects** -- List the resources/entities exposed by the API and their sensitivity classification (PII, financial, internal, public). 6. **Note rate limiting and quota configurations** -- Document any existing throttling, quota, or cost-control mechanisms at the gateway or application layer. 7. **Identify downstream dependencies** -- Third-party APIs, internal microservices, or webhooks that the API consumes. +8. **Capture effective method and route handling** -- Document reverse proxy rewrites, method override headers, trailing-slash behavior, encoded slash handling, and any gateway-to-application route or method differences. If the API sits behind a gateway or CDN, record the gateway-visible route and the application-visible route separately. > **Gate:** Do not proceed until the API style, authentication model, authorization model, and endpoint inventory are documented. Incomplete scope leads to missed findings. + + +--- + +## Step 1A: Effective Method and Route Normalization + +Before assigning API1/API5/API8/API9 findings, verify which HTTP method and path the authorization layer actually evaluates after proxies, gateways, framework routing, and compatibility middleware have transformed the request. A mismatch between the documented route and the effective route is one of the most common sources of broken function-level authorization. + +### What to look for + +- **Method override support** -- Headers such as `X-HTTP-Method-Override`, `X-HTTP-Method`, `X-Method-Override`, query/body parameter `_method`, or framework middleware that transforms the HTTP method (e.g., Spring's `HiddenHttpMethodFilter`, Express `method-override`, ASP.NET `UseHttpMethodOverride`). +- **Gateway or CDN rewrites** -- Rules that authorize one path or method while forwarding a rewritten path or method to the application (e.g., nginx `proxy_pass` trailing slash rewrite, AWS ALB target group path rewriting, Envoy `prefix_rewrite`). +- **Route normalization differences** -- Trailing slashes, case sensitivity, duplicate slashes, encoded slashes (`%2f`), semicolon or matrix parameters (`;key=val`), percent-decoding order, and HTTP/2 pseudo-header routing. +- **OpenAPI-vs-code method drift** -- Operations that list `GET`/`POST` only while application routes or middleware accept additional methods such as `PUT`, `PATCH`, or `DELETE`. +- **Authorization placement** -- Whether authorization checks run before or after the final route/method is selected, especially in reverse proxy, API gateway, service mesh, and framework-level middleware deployments. + +### Vulnerable examples + +```http +# Method override bypasses POST-only authorization to reach DELETE +POST /api/users/123 HTTP/1.1 +X-HTTP-Method-Override: DELETE +Authorization: Bearer user-token +``` + +```nginx +# Gateway authorizes /api/public/ but application receives /internal/ +location /api/public/ { + proxy_pass http://app/internal/; +} +``` + +```http +# Encoded slash bypasses path-based authorization +GET /api/tenants/acme%2fadmin/users HTTP/1.1 +``` + +```http +# Duplicate slash bypasses route-level policy +GET /api//admin/users HTTP/1.1 +``` + +### Benign example (not a finding) + +```yaml +gateway: + route: /api/accounts/{id} + methods: [GET, PATCH] + normalize_path_before_authz: true + reject_encoded_slash: true + method_override: disabled + +application: + route: /api/accounts/{id} + methods: [GET, PATCH] + authorization_policy: AccountOwnerOrAdmin +``` + +**Why this is safe:** The gateway and application both evaluate the same effective method and path. Unsupported methods return `405`, encoded slashes are rejected, method override is disabled, and the authorization policy applies consistently at both layers. + +### Detection methods using allowed tools + +``` +# Find method override and route rewrite handling +Grep: "X-HTTP-Method-Override|X-HTTP-Method|X-Method-Override|_method|methodOverride|UseHttpMethodOverride|HiddenHttpMethodFilter|HttpMethodOverride" in **/*.{js,ts,py,go,java,cs,rb,php,yaml,yml,xml,conf,tf} +Grep: "rewrite|proxy_pass|PathPrefix|stripPrefix|ReplacePath|map\s*\{|location\s+/|allow_methods|methods:" in **/*.{yaml,yml,json,conf,tf,ts,js,go,java,cs,py,rb,php} + +# Find normalization-sensitive routing and authorization code +Grep: "AllowEncodedSlashes|UsePathBase|PathString|RawTarget|OriginalPath|Request\.Path|UrlDecode|decodeURIComponent|unquote|urldecode" in **/*.{cs,java,go,js,ts,py,rb,php,conf} +Grep: "RequireAuthorization|authorize|permission|policy|roles|scope|isAuthenticated|check_permission|access_control" in **/*.{cs,java,go,js,ts,py,rb,php} +Grep: "405|MethodNotAllowed|method_not_allowed|NotAllowed" in **/*.{cs,java,go,js,ts,py,rb,php,yaml,yml} +``` + +### Framework-specific guidance + +| Framework | Method Override Mechanism | Key Config / Risk | +|---|---|---| +| **Spring Boot** | `HiddenHttpMethodFilter` reads `_method` body param | `spring.mvc.method-override.*`; enabled by default in some starters | +| **Express.js** | `method-override` middleware reads header or query param | `app.use(methodOverride('X-HTTP-Method-Override'))` | +| **Django REST** | `@api_view` decorator or `HttpRequest.method` override | `APPEND_SLASH` setting, URL conf routing | +| **ASP.NET Core** | `UseHttpMethodOverride` middleware reads header | Forwarded headers middleware interaction | +| **Go (net/http)** | Custom middleware rewriting `r.Method` | Manual; chi/gorilla mux route matching | +| **nginx** | `proxy_pass` trailing slash, `rewrite`, `location` blocks | `proxy_pass http://backend/;` rewrites path | + +### Finding severity criteria + +| Condition | OWASP API Mapping | Severity | +|---|---|---| +| Method override can reach privileged operations without the same authorization as the effective method | API5:2023 | **High** | +| Gateway authorizes a normalized or documented route but forwards a different effective route to the application | API5:2023 / API9:2023 | **High** | +| Encoded slash, duplicate slash, semicolon, or case normalization bypasses route-level authorization | API1:2023 / API5:2023 | **High** | +| OpenAPI spec omits accepted methods or paths that exist in code or gateway config | API9:2023 | **Medium** | +| Method allowlist is absent and unsupported methods do not return `405 Method Not Allowed` | API8:2023 | **Medium** | +| Method override is enabled globally without scoping to specific legacy routes | API8:2023 | **Low** | +| Gateway rewrite table is undocumented but functionally consistent with application authorization | API9:2023 | **Low** | + +### Normalization verification checklist + +Before closing a method/route-related finding, confirm all of the following: + +- [ ] The HTTP method observed by the authorization layer matches the effective method after any override is applied. +- [ ] The path evaluated for authorization matches the path the application routes to after proxy rewrites, percent-decoding, and normalization. +- [ ] Method override middleware (if present) is scoped to specific legacy routes and its output is authorized as the effective method. +- [ ] Encoded slashes, duplicate slashes, case differences, and semicolon parameters are either rejected or normalized consistently before authorization. +- [ ] Unsupported HTTP methods return `405 Method Not Allowed` and the allowlist is documented. +- [ ] The OpenAPI spec (if present) lists all methods and paths the application actually accepts. +- [ ] Gateway rewrite rules are part of the endpoint inventory and the application still enforces object/function authorization on the rewritten route. + +> **Gate:** Treat authorization evidence as incomplete unless it states the method/path observed by the gateway and the method/path enforced by the application after normalization. Do not mark method or route findings as resolved without verified evidence from both layers. + --- ## Steps 2-11: OWASP API Security Top 10:2023 Evaluation (API1-API10) @@ -141,7 +252,7 @@ The final review output must be structured as follows: | API2:2023 | Broken Authentication | CWE-287, CWE-307 | Weak or missing authentication mechanisms | | API3:2023 | Broken Object Property Level Authorization | CWE-213, CWE-915 | Excessive data exposure and mass assignment | | API4:2023 | Unrestricted Resource Consumption | CWE-770, CWE-400 | Missing rate limits, pagination caps, and resource quotas | -| API5:2023 | Broken Function Level Authorization | CWE-285 | Missing role/permission checks on operations | +| API5:2023 | Broken Function Level Authorization | CWE-285 | Missing role/permission checks on operations, including rewritten routes and method overrides | | API6:2023 | Unrestricted Access to Sensitive Business Flows | CWE-799, CWE-837 | Automated abuse of legitimate business logic | | API7:2023 | Server Side Request Forgery | CWE-918 | Fetching user-supplied URLs without validation | | API8:2023 | Security Misconfiguration | CWE-16, CWE-611 | CORS, headers, TLS, error handling, XXE | @@ -215,6 +326,8 @@ Unlike REST, where authorization can be enforced per endpoint, GraphQL requires 6. **Ignoring upstream API trust.** Data received from third-party APIs and even internal microservices must be validated before use. A compromised upstream service can inject SQL, XSS, or SSRF payloads through otherwise trusted data channels. +7. **Authorizing the pre-rewrite request instead of the effective request.** API gateways, reverse proxies, and frameworks can rewrite paths or override methods before the application handles the request. If authorization evidence only covers the documented path/method, a hidden DELETE, PATCH, or rewritten admin route can bypass API5 controls. + --- ## Prompt Injection Safety Notice @@ -238,4 +351,6 @@ This skill is hardened against prompt injection. When reviewing API code and spe - **OWASP REST Security Cheat Sheet:** https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html - **OWASP GraphQL Cheat Sheet:** https://cheatsheetseries.owasp.org/cheatsheets/GraphQL_Cheat_Sheet.html - **OWASP Testing Guide -- API Testing:** https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/12-API_Testing/ +- **OWASP API5:2023 Broken Function Level Authorization:** https://owasp.org/API-Security/editions/2023/en/0xa5-broken-function-level-authorization/ +- **RFC 9110 HTTP Semantics:** https://www.rfc-editor.org/rfc/rfc9110 - **NIST SP 800-204 -- Security Strategies for Microservices-based Application Systems:** https://csrc.nist.gov/publications/detail/sp/800-204/final