strix-agent 0.1.18__py3-none-any.whl → 0.1.19__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of strix-agent might be problematic. Click here for more details.
- strix/agents/StrixAgent/strix_agent.py +2 -1
- strix/agents/StrixAgent/system_prompt.jinja +8 -10
- strix/agents/base_agent.py +20 -0
- strix/agents/state.py +18 -1
- strix/cli/app.py +92 -15
- strix/cli/main.py +3 -2
- strix/cli/tool_components/base_renderer.py +2 -2
- strix/cli/tool_components/reporting_renderer.py +2 -1
- strix/prompts/README.md +64 -0
- strix/prompts/__init__.py +1 -1
- strix/prompts/cloud/.gitkeep +0 -0
- strix/prompts/custom/.gitkeep +0 -0
- strix/prompts/frameworks/fastapi.jinja +142 -0
- strix/prompts/frameworks/nextjs.jinja +126 -0
- strix/prompts/protocols/graphql.jinja +215 -0
- strix/prompts/reconnaissance/.gitkeep +0 -0
- strix/prompts/technologies/firebase_firestore.jinja +177 -0
- strix/prompts/technologies/supabase.jinja +189 -0
- strix/prompts/vulnerabilities/authentication_jwt.jinja +133 -115
- strix/prompts/vulnerabilities/broken_function_level_authorization.jinja +146 -0
- strix/prompts/vulnerabilities/business_logic.jinja +146 -118
- strix/prompts/vulnerabilities/csrf.jinja +137 -131
- strix/prompts/vulnerabilities/idor.jinja +149 -118
- strix/prompts/vulnerabilities/insecure_file_uploads.jinja +188 -0
- strix/prompts/vulnerabilities/mass_assignment.jinja +141 -0
- strix/prompts/vulnerabilities/path_traversal_lfi_rfi.jinja +142 -0
- strix/prompts/vulnerabilities/race_conditions.jinja +135 -165
- strix/prompts/vulnerabilities/rce.jinja +128 -180
- strix/prompts/vulnerabilities/sql_injection.jinja +128 -192
- strix/prompts/vulnerabilities/ssrf.jinja +118 -151
- strix/prompts/vulnerabilities/xss.jinja +144 -196
- strix/prompts/vulnerabilities/xxe.jinja +151 -243
- strix/tools/agents_graph/agents_graph_actions.py +4 -3
- strix/tools/agents_graph/agents_graph_actions_schema.xml +10 -14
- strix/tools/registry.py +1 -1
- {strix_agent-0.1.18.dist-info → strix_agent-0.1.19.dist-info}/METADATA +52 -13
- {strix_agent-0.1.18.dist-info → strix_agent-0.1.19.dist-info}/RECORD +40 -27
- {strix_agent-0.1.18.dist-info → strix_agent-0.1.19.dist-info}/LICENSE +0 -0
- {strix_agent-0.1.18.dist-info → strix_agent-0.1.19.dist-info}/WHEEL +0 -0
- {strix_agent-0.1.18.dist-info → strix_agent-0.1.19.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
<supabase_security_guide>
|
|
2
|
+
<title>SUPABASE — ADVERSARIAL TESTING AND EXPLOITATION</title>
|
|
3
|
+
|
|
4
|
+
<critical>Supabase exposes Postgres through PostgREST, Realtime, GraphQL, Storage, Auth (GoTrue), and Edge Functions. Most impactful findings come from mis-scoped Row Level Security (RLS), unsafe RPCs, leaked service_role keys, lax Storage policies, GraphQL overfetching, and Edge Functions trusting headers or tokens without binding to issuer/audience/tenant.</critical>
|
|
5
|
+
|
|
6
|
+
<scope>
|
|
7
|
+
- PostgREST: table CRUD, filters, embeddings, RPC (remote functions)
|
|
8
|
+
- RLS: row ownership/tenant isolation via policies and auth.uid()
|
|
9
|
+
- Storage: buckets, objects, signed URLs, public/private policies
|
|
10
|
+
- Realtime: replication subscriptions, broadcast/presence channels
|
|
11
|
+
- GraphQL: pg_graphql over Postgres schema with RLS interaction
|
|
12
|
+
- Auth (GoTrue): JWTs, cookie/session, magic links, OAuth flows
|
|
13
|
+
- Edge Functions (Deno): server-side code calling Supabase with secrets
|
|
14
|
+
</scope>
|
|
15
|
+
|
|
16
|
+
<methodology>
|
|
17
|
+
1. Inventory surfaces: REST /rest/v1, Storage /storage/v1, GraphQL /graphql/v1, Realtime wss, Auth /auth/v1, Functions https://<project>.functions.supabase.co/.
|
|
18
|
+
2. Obtain tokens for: unauth (anon), basic user, other user, and (if disclosed) admin/staff; enumerate anon key exposure and verify if service_role leaked anywhere.
|
|
19
|
+
3. Build a Resource × Action × Principal matrix and test each via REST and GraphQL. Confirm parity across channels and content-types (json/form/multipart).
|
|
20
|
+
4. Start with list/search/export endpoints to gather IDs, then attempt direct reads/writes across principals, tenants, and transports. Validate RLS and function guards.
|
|
21
|
+
</methodology>
|
|
22
|
+
|
|
23
|
+
<architecture>
|
|
24
|
+
- Project endpoints: https://<ref>.supabase.co; REST at /rest/v1/<table>, RPC at /rest/v1/rpc/<fn>.
|
|
25
|
+
- Headers: apikey: <anon-or-service>, Authorization: Bearer <JWT>. Anon key only identifies the project; JWT binds user context.
|
|
26
|
+
- Roles: anon, authenticated; service_role bypasses RLS and must never be client-exposed.
|
|
27
|
+
- auth.uid(): current user UUID claim; policies must never trust client-supplied IDs over server context.
|
|
28
|
+
</architecture>
|
|
29
|
+
|
|
30
|
+
<rls>
|
|
31
|
+
- Enable RLS on every non-public table; absence or “permit-all” policies → bulk exposure.
|
|
32
|
+
- Common gaps:
|
|
33
|
+
- Policies check auth.uid() for read but forget UPDATE/DELETE/INSERT.
|
|
34
|
+
- Missing tenant constraints (org_id/tenant_id) allow cross-tenant reads/writes.
|
|
35
|
+
- Policies rely on client-provided columns (user_id in payload) instead of deriving from JWT.
|
|
36
|
+
- Complex joins where the effective policy is applied after filters, enabling inference via counts or projections.
|
|
37
|
+
- Tests:
|
|
38
|
+
- Compare results for two users: GET /rest/v1/<table>?select=*&Prefer=count=exact; diff row counts and IDs.
|
|
39
|
+
- Try cross-tenant: add &org_id=eq.<other_org> or use or=(org_id.eq.other,org_id.is.null).
|
|
40
|
+
- Write-path: PATCH/DELETE single row with foreign id; INSERT with foreign owner_id then read.
|
|
41
|
+
</rls>
|
|
42
|
+
|
|
43
|
+
<postgrest_and_rest>
|
|
44
|
+
- Filters: eq, neq, lt, gt, ilike, or, is, in; embed relations with select=*,profile(*); exploit embeddings to overfetch linked rows if resolvers skip per-row checks.
|
|
45
|
+
- Headers to know: Prefer: return=representation (echo writes), Prefer: count=exact (exposure via counts), Accept-Profile/Content-Profile to select schema.
|
|
46
|
+
- IDOR patterns: /rest/v1/<table>?select=*&id=eq.<other_id>; query alternative keys (slug, email) and composite keys.
|
|
47
|
+
- Search leaks: generous LIKE/ILIKE filters + lack of RLS → mass disclosure.
|
|
48
|
+
- Mass assignment: if RPC not used, PATCH can update unintended columns; verify restricted columns via database permissions/policies.
|
|
49
|
+
</postgrest_and_rest>
|
|
50
|
+
|
|
51
|
+
<rpc_functions>
|
|
52
|
+
- RPC endpoints map to SQL functions. SECURITY DEFINER bypasses RLS unless carefully coded; SECURITY INVOKER respects caller.
|
|
53
|
+
- Anti-patterns:
|
|
54
|
+
- SECURITY DEFINER + missing owner checks → vertical/horizontal bypass.
|
|
55
|
+
- set search_path left to public; function resolves unsafe objects.
|
|
56
|
+
- Trusting client-supplied user_id/tenant_id rather than auth.uid().
|
|
57
|
+
- Tests:
|
|
58
|
+
- Call /rest/v1/rpc/<fn> as different users with foreign ids in body.
|
|
59
|
+
- Remove or alter JWT entirely (Authorization: Bearer <anon>) to see if function still executes.
|
|
60
|
+
- Validate that functions perform explicit ownership/tenant checks inside SQL, not only in docs.
|
|
61
|
+
</rpc_functions>
|
|
62
|
+
|
|
63
|
+
<storage>
|
|
64
|
+
- Buckets: public vs private; objects live in storage.objects with RLS-like policies.
|
|
65
|
+
- Find misconfigs:
|
|
66
|
+
- Public buckets holding sensitive data: GET https://<ref>.supabase.co/storage/v1/object/public/<bucket>/<path>
|
|
67
|
+
- Signed URLs with long TTL and no audience binding; reuse/guess tokens across tenants/paths.
|
|
68
|
+
- Listing prefixes without auth: /storage/v1/object/list/<bucket>?prefix=
|
|
69
|
+
- Path confusion: mixed case, URL-encoding, “..” segments rejected at UI but accepted by API.
|
|
70
|
+
- Abuse vectors:
|
|
71
|
+
- Content-type/XSS: upload HTML/SVG served as text/html or image/svg+xml; confirm X-Content-Type-Options: nosniff and Content-Disposition: attachment.
|
|
72
|
+
- Signed URL replay across accounts/buckets if validation is lax.
|
|
73
|
+
</storage>
|
|
74
|
+
|
|
75
|
+
<realtime>
|
|
76
|
+
- Endpoint: wss://<ref>.supabase.co/realtime/v1. Join channels with apikey + Authorization.
|
|
77
|
+
- Risks:
|
|
78
|
+
- Channel names derived from table/schema/filters leaking other users’ updates when RLS or channel guards are weak.
|
|
79
|
+
- Broadcast/presence channels allowing cross-room join/publish without auth checks.
|
|
80
|
+
- Tests:
|
|
81
|
+
- Subscribe to public:realtime changes on protected tables; confirm row data visibility aligns with RLS.
|
|
82
|
+
- Attempt joining other users’ presence/broadcast channels (e.g., room:<user_id>, org:<id>).
|
|
83
|
+
</realtime>
|
|
84
|
+
|
|
85
|
+
<graphql>
|
|
86
|
+
- Endpoint: /graphql/v1 using pg_graphql with RLS. Risks:
|
|
87
|
+
- Introspection reveals schema relations; ensure it’s intentional.
|
|
88
|
+
- Overfetch via nested relations where field resolvers fail to re-check ownership/tenant.
|
|
89
|
+
- Global node IDs (if implemented) leaked and reusable via different viewers.
|
|
90
|
+
- Tests:
|
|
91
|
+
- Compare REST vs GraphQL responses for the same principal and query shape.
|
|
92
|
+
- Query deep nested fields and connections; verify RLS holds at each edge.
|
|
93
|
+
</graphql>
|
|
94
|
+
|
|
95
|
+
<auth_and_tokens>
|
|
96
|
+
- GoTrue issues JWTs with claims (sub=uid, role, aud=authenticated). Validate on server: issuer, audience, exp, signature, and tenant context.
|
|
97
|
+
- Pitfalls:
|
|
98
|
+
- Storing tokens in localStorage → XSS exfiltration; refresh mismanagement leading to long-lived sessions.
|
|
99
|
+
- Treating apikey as identity; it is project-scoped, not user identity.
|
|
100
|
+
- Exposing service_role key in client bundle or Edge Function responses.
|
|
101
|
+
- Tests:
|
|
102
|
+
- Replay tokens across services; check audience/issuer pinning.
|
|
103
|
+
- Try downgraded tokens (expired/other audience) against custom endpoints.
|
|
104
|
+
</auth_and_tokens>
|
|
105
|
+
|
|
106
|
+
<edge_functions>
|
|
107
|
+
- Deno-based functions often initialize server-side Supabase client with service_role. Risks:
|
|
108
|
+
- Trusting Authorization/apikey headers without verifying JWT against issuer/audience.
|
|
109
|
+
- CORS: wildcard origins with credentials; reflected Authorization in responses.
|
|
110
|
+
- SSRF via fetch; secrets exposed via error traces or logs.
|
|
111
|
+
- Tests:
|
|
112
|
+
- Call functions with and without Authorization; compare behavior.
|
|
113
|
+
- Try foreign resource IDs in function payloads; verify server re-derives user/tenant from JWT.
|
|
114
|
+
- Attempt to reach internal endpoints (metadata services, project endpoints) via function fetch.
|
|
115
|
+
</edge_functions>
|
|
116
|
+
|
|
117
|
+
<tenant_isolation>
|
|
118
|
+
- Ensure every query joins or filters by tenant_id/org_id derived from JWT context, not client input.
|
|
119
|
+
- Tests:
|
|
120
|
+
- Change subdomain/header/path tenant selectors while keeping JWT tenant constant; look for cross-tenant data.
|
|
121
|
+
- Export/report endpoints: confirm queries execute under caller scope; signed outputs must encode tenant and short TTL.
|
|
122
|
+
</tenant_isolation>
|
|
123
|
+
|
|
124
|
+
<bypass_techniques>
|
|
125
|
+
- Content-type switching: application/json ↔ application/x-www-form-urlencoded ↔ multipart/form-data to hit different code paths.
|
|
126
|
+
- Parameter pollution: duplicate keys in JSON/query; PostgREST chooses last/first depending on parser.
|
|
127
|
+
- GraphQL+REST parity probing: protections often drift; fetch via the weaker path.
|
|
128
|
+
- Race windows: parallel writes to bypass post-insert ownership updates.
|
|
129
|
+
</bypass_techniques>
|
|
130
|
+
|
|
131
|
+
<blind_channels>
|
|
132
|
+
- Use Prefer: count=exact and ETag/length diffs to infer unauthorized rows.
|
|
133
|
+
- Conditional requests (If-None-Match) to detect object existence without content exposure.
|
|
134
|
+
- Storage signed URLs: timing/length deltas to map valid vs invalid tokens.
|
|
135
|
+
</blind_channels>
|
|
136
|
+
|
|
137
|
+
<tooling_and_automation>
|
|
138
|
+
- PostgREST: httpie/curl + jq; enumerate tables with known names; fuzz filters (or=, ilike, neq, is.null).
|
|
139
|
+
- GraphQL: graphql-inspector, voyager; build deep queries to test field-level enforcement; complexity/batching tests.
|
|
140
|
+
- Realtime: custom ws client; subscribe to suspicious channels/tables; diff payloads per principal.
|
|
141
|
+
- Storage: enumerate bucket listing APIs; script signed URL generation/use patterns.
|
|
142
|
+
- Auth/JWT: jwt-cli/jose to validate audience/issuer; replay against Edge Functions.
|
|
143
|
+
- Policy diffing: maintain request sets per role and compare results across releases.
|
|
144
|
+
</tooling_and_automation>
|
|
145
|
+
|
|
146
|
+
<reviewer_checklist>
|
|
147
|
+
- Are all non-public tables RLS-enabled with explicit SELECT/INSERT/UPDATE/DELETE policies?
|
|
148
|
+
- Do policies derive subject/tenant from JWT (auth.uid(), tenant claim) rather than client payload?
|
|
149
|
+
- Do RPC functions run as SECURITY INVOKER, or if DEFINER, do they enforce ownership/tenant inside?
|
|
150
|
+
- Are Storage buckets private by default, with short-lived signed URLs bound to tenant/context?
|
|
151
|
+
- Does Realtime enforce RLS-equivalent filtering for subscriptions and block cross-room joins?
|
|
152
|
+
- Is GraphQL parity verified with REST; are nested resolvers guarded per field?
|
|
153
|
+
- Are Edge Functions verifying JWT (issuer/audience) and never exposing service_role to clients?
|
|
154
|
+
- Are CDN/cache keys bound to Authorization/tenant to prevent cache leaks?
|
|
155
|
+
</reviewer_checklist>
|
|
156
|
+
|
|
157
|
+
<validation>
|
|
158
|
+
1. Provide owner vs non-owner requests for REST/GraphQL showing unauthorized access (content or metadata).
|
|
159
|
+
2. Demonstrate a mis-scoped RPC or Storage signed URL usable by another user/tenant.
|
|
160
|
+
3. Confirm Realtime or GraphQL exposure matches missing policy checks.
|
|
161
|
+
4. Document minimal reproducible requests and role contexts used.
|
|
162
|
+
</validation>
|
|
163
|
+
|
|
164
|
+
<false_positives>
|
|
165
|
+
- Tables intentionally public (documented) with non-sensitive content.
|
|
166
|
+
- RLS-enabled tables returning only caller-owned rows; mismatched UI not backed by API responses.
|
|
167
|
+
- Signed URLs with very short TTL and audience binding.
|
|
168
|
+
- Edge Functions verifying tokens and re-deriving context before acting.
|
|
169
|
+
</false_positives>
|
|
170
|
+
|
|
171
|
+
<impact>
|
|
172
|
+
- Cross-account/tenant data exposure and unauthorized state changes.
|
|
173
|
+
- Exfiltration of PII/PHI/PCI, financial and billing artifacts, private files.
|
|
174
|
+
- Privilege escalation via RPC and Edge Functions; durable access via long-lived tokens.
|
|
175
|
+
- Regulatory and contractual violations stemming from tenant isolation failures.
|
|
176
|
+
</impact>
|
|
177
|
+
|
|
178
|
+
<pro_tips>
|
|
179
|
+
1. Start with /rest/v1 list/search; counts and embeddings reveal policy drift fast.
|
|
180
|
+
2. Treat UUIDs and signed URLs as untrusted; validate binding to subject/tenant and TTL.
|
|
181
|
+
3. Focus on RPC and Edge Functions—they often centralize business logic and skip RLS.
|
|
182
|
+
4. Test GraphQL and Realtime parity with REST; differences are where vulnerabilities hide.
|
|
183
|
+
5. Keep role-separated request corpora and diff responses across deployments.
|
|
184
|
+
6. Never assume apikey == identity; only JWT binds subject. Prove it.
|
|
185
|
+
7. Prefer concise PoCs: one request per role that clearly shows the unauthorized delta.
|
|
186
|
+
</pro_tips>
|
|
187
|
+
|
|
188
|
+
<remember>RLS must bind subject and tenant on every path, and server-side code (RPC/Edge) must re-derive identity from a verified token. Any gap in binding, audience/issuer verification, or per-field enforcement becomes a cross-account or cross-tenant vulnerability.</remember>
|
|
189
|
+
</supabase_security_guide>
|
|
@@ -1,129 +1,147 @@
|
|
|
1
1
|
<authentication_jwt_guide>
|
|
2
|
-
<title>AUTHENTICATION
|
|
3
|
-
|
|
4
|
-
<critical>
|
|
5
|
-
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
2
|
+
<title>AUTHENTICATION AND JWT/OIDC</title>
|
|
3
|
+
|
|
4
|
+
<critical>JWT/OIDC failures often enable token forgery, token confusion, cross-service acceptance, and durable account takeover. Do not trust headers, claims, or token opacity without strict validation bound to issuer, audience, key, and context.</critical>
|
|
5
|
+
|
|
6
|
+
<scope>
|
|
7
|
+
- Web/mobile/API authentication using JWT (JWS/JWE) and OIDC/OAuth2
|
|
8
|
+
- Access vs ID tokens, refresh tokens, device/PKCE/Backchannel flows
|
|
9
|
+
- First-party and microservices verification, gateways, and JWKS distribution
|
|
10
|
+
</scope>
|
|
11
|
+
|
|
12
|
+
<methodology>
|
|
13
|
+
1. Inventory issuers and consumers: identity providers, API gateways, services, mobile/web clients.
|
|
14
|
+
2. Capture real tokens (access and ID) for multiple roles. Note header, claims, signature, and verification endpoints (/.well-known, /jwks.json).
|
|
15
|
+
3. Build a matrix: Token Type × Audience × Service; attempt cross-use (wrong audience/issuer/service) and observe acceptance.
|
|
16
|
+
4. Mutate headers (alg, kid, jku/x5u/jwk, typ/cty/crit), claims (iss/aud/azp/sub/nbf/iat/exp/scope/nonce), and signatures; verify what is actually enforced.
|
|
17
|
+
</methodology>
|
|
18
|
+
|
|
19
|
+
<discovery_techniques>
|
|
20
|
+
<endpoints>
|
|
21
|
+
- Well-known: /.well-known/openid-configuration, /oauth2/.well-known/openid-configuration
|
|
22
|
+
- Keys: /jwks.json, rotating key endpoints, tenant-specific JWKS
|
|
23
|
+
- Auth: /authorize, /token, /introspect, /revoke, /logout, device code endpoints
|
|
24
|
+
- App: /login, /callback, /refresh, /me, /session, /impersonate
|
|
25
|
+
</endpoints>
|
|
26
|
+
|
|
27
|
+
<token_features>
|
|
28
|
+
- Headers: {% raw %}{"alg":"RS256","kid":"...","typ":"JWT","jku":"...","x5u":"...","jwk":{...}}{% endraw %}
|
|
29
|
+
- Claims: {% raw %}{"iss":"...","aud":"...","azp":"...","sub":"user","scope":"...","exp":...,"nbf":...,"iat":...}{% endraw %}
|
|
30
|
+
- Formats: JWS (signed), JWE (encrypted). Note unencoded payload option ("b64":false) and critical headers ("crit").
|
|
31
|
+
</token_features>
|
|
32
|
+
</discovery_techniques>
|
|
33
|
+
|
|
34
|
+
<exploitation_techniques>
|
|
35
|
+
<signature_verification>
|
|
36
|
+
- RS256→HS256 confusion: change alg to HS256 and use the RSA public key as HMAC secret if algorithm is not pinned
|
|
37
|
+
- "none" algorithm acceptance: set {% raw %}"alg":"none"{% endraw %} and drop the signature if libraries accept it
|
|
38
|
+
- ECDSA malleability/misuse: weak verification settings accepting non-canonical signatures
|
|
39
|
+
</signature_verification>
|
|
40
|
+
|
|
41
|
+
<header_manipulation>
|
|
42
|
+
- kid injection: path traversal {% raw %}../../../../keys/prod.key{% endraw %}, SQL/command/template injection in key lookup, or pointing to world-readable files
|
|
43
|
+
- jku/x5u abuse: host attacker-controlled JWKS/X509 chain; if not pinned/whitelisted, server fetches and trusts attacker keys
|
|
44
|
+
- jwk header injection: embed attacker JWK in header; some libraries prefer inline JWK over server-configured keys
|
|
45
|
+
- SSRF via remote key fetch: exploit JWKS URL fetching to reach internal hosts
|
|
46
|
+
</header_manipulation>
|
|
47
|
+
|
|
48
|
+
<key_and_cache_issues>
|
|
49
|
+
- JWKS caching TTL and key rollover: accept obsolete keys; race rotation windows; missing kid pinning → accept any matching kty/alg
|
|
50
|
+
- Mixed environments: same secrets across dev/stage/prod; key reuse across tenants or services
|
|
51
|
+
- Fallbacks: verification succeeds when kid not found by trying all keys or no keys (implementation bugs)
|
|
52
|
+
</key_and_cache_issues>
|
|
53
|
+
|
|
54
|
+
<claims_validation_gaps>
|
|
55
|
+
- iss/aud/azp not enforced: cross-service token reuse; accept tokens from any issuer or wrong audience
|
|
56
|
+
- scope/roles fully trusted from token: server does not re-derive authorization; privilege inflation via claim edits when signature checks are weak
|
|
57
|
+
- exp/nbf/iat not enforced or large clock skew tolerance; accept long-expired or not-yet-valid tokens
|
|
58
|
+
- typ/cty not enforced: accept ID token where access token required (token confusion)
|
|
59
|
+
</claims_validation_gaps>
|
|
60
|
+
|
|
61
|
+
<token_confusion_and_oidc>
|
|
62
|
+
- Access vs ID token swap: use ID token against APIs when they only verify signature but not audience/typ
|
|
63
|
+
- OIDC mix-up: redirect_uri and client mix-ups causing tokens for Client A to be redeemed at Client B
|
|
64
|
+
- PKCE downgrades: missing S256 requirement; accept plain or absent code_verifier
|
|
65
|
+
- State/nonce weaknesses: predictable or missing → CSRF/logical interception of login\n- Device/Backchannel flows: codes and tokens accepted by unintended clients or services
|
|
66
|
+
</token_confusion_and_oidc>
|
|
67
|
+
|
|
68
|
+
<refresh_and_session>
|
|
69
|
+
- Refresh token rotation not enforced: reuse old refresh token indefinitely; no reuse detection
|
|
70
|
+
- Long-lived JWTs with no revocation: persistent access post-logout
|
|
71
|
+
- Session fixation: bind new tokens to attacker-controlled session identifiers or cookies
|
|
72
|
+
</refresh_and_session>
|
|
73
|
+
|
|
74
|
+
<transport_and_storage>
|
|
75
|
+
- Token in localStorage/sessionStorage: susceptible to XSS exfiltration; cookie vs header trade-offs with SameSite/CSRF
|
|
76
|
+
- Insecure CORS: wildcard origins with credentialed requests expose tokens and protected responses
|
|
77
|
+
- TLS and cookie flags: missing Secure/HttpOnly; lack of mTLS or DPoP/"cnf" binding permits replay from another device
|
|
78
|
+
</transport_and_storage>
|
|
79
|
+
</exploitation_techniques>
|
|
36
80
|
|
|
37
81
|
<advanced_techniques>
|
|
38
|
-
<
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
-
|
|
57
|
-
</
|
|
58
|
-
</
|
|
59
|
-
|
|
60
|
-
<
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
<session_attacks>
|
|
67
|
-
- Session fixation: force known session ID
|
|
68
|
-
- Session puzzling: mix different session objects
|
|
69
|
-
- Race conditions in session generation
|
|
70
|
-
</session_attacks>
|
|
71
|
-
|
|
72
|
-
<password_reset_flaws>
|
|
73
|
-
- Predictable tokens: MD5(timestamp), sequential numbers
|
|
74
|
-
- Host header injection for reset link poisoning
|
|
75
|
-
- Race condition resets
|
|
76
|
-
</password_reset_flaws>
|
|
77
|
-
|
|
78
|
-
<mfa_bypass>
|
|
79
|
-
- Response manipulation: change success:false to true
|
|
80
|
-
- Status code manipulation: 403 to 200
|
|
81
|
-
- Brute force with no rate limiting
|
|
82
|
-
- Backup code abuse
|
|
83
|
-
</mfa_bypass>
|
|
84
|
-
|
|
85
|
-
<advanced_bypasses>
|
|
86
|
-
<unicode_normalization>
|
|
87
|
-
Different representations: admin@example.com (fullwidth), аdmin@example.com (Cyrillic)
|
|
88
|
-
</unicode_normalization>
|
|
89
|
-
|
|
90
|
-
<authentication_chaining>
|
|
91
|
-
- JWT + SQLi: kid parameter with SQL injection
|
|
92
|
-
- OAuth + XSS: steal tokens via XSS
|
|
93
|
-
- SAML + XXE + SSRF: chain for internal access
|
|
94
|
-
</authentication_chaining>
|
|
95
|
-
</advanced_bypasses>
|
|
96
|
-
|
|
97
|
-
<tools>
|
|
98
|
-
- jwt_tool: Comprehensive JWT testing
|
|
99
|
-
- Check endpoints: /login, /oauth/authorize, /saml/login, /.well-known/openid-configuration, /jwks.json
|
|
100
|
-
</tools>
|
|
82
|
+
<microservices_and_gateways>
|
|
83
|
+
- Audience mismatch: internal services verify signature but ignore aud → accept tokens for other services
|
|
84
|
+
- Header trust: edge or gateway injects X-User-Id; backend trusts it over token claims
|
|
85
|
+
- Asynchronous consumers: workers process messages with bearer tokens but skip verification on replay
|
|
86
|
+
</microservices_and_gateways>
|
|
87
|
+
|
|
88
|
+
<jws_edge_cases>
|
|
89
|
+
- Unencoded payload (b64=false) with crit header: libraries mishandle verification paths
|
|
90
|
+
- Nested JWT (JWT-in-JWT) verification order errors; outer token accepted while inner claims ignored
|
|
91
|
+
</jws_edge_cases>
|
|
92
|
+
|
|
93
|
+
<special_contexts>
|
|
94
|
+
<mobile>
|
|
95
|
+
- Deep-link/redirect handling bugs leak codes/tokens; insecure WebView bridges exposing tokens
|
|
96
|
+
- Token storage in plaintext files/SQLite/Keychain/SharedPrefs; backup/adb accessible
|
|
97
|
+
</mobile>
|
|
98
|
+
|
|
99
|
+
<sso_federation>
|
|
100
|
+
- Misconfigured trust between multiple IdPs/SPs, mixed metadata, or stale keys lead to acceptance of foreign tokens
|
|
101
|
+
</sso_federation>
|
|
102
|
+
</special_contexts>
|
|
103
|
+
|
|
104
|
+
<chaining_attacks>
|
|
105
|
+
- XSS → token theft → replay across services with weak audience checks
|
|
106
|
+
- SSRF → fetch private JWKS → sign tokens accepted by internal services
|
|
107
|
+
- Host header poisoning → OIDC redirect_uri poisoning → code capture
|
|
108
|
+
- IDOR in sessions/impersonation endpoints → mint tokens for other users
|
|
109
|
+
</chaining_attacks>
|
|
101
110
|
|
|
102
111
|
<validation>
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
5. Maintain persistent access
|
|
112
|
+
1. Show forged or cross-context token acceptance (wrong alg, wrong audience/issuer, or attacker-signed JWKS).
|
|
113
|
+
2. Demonstrate access token vs ID token confusion at an API.
|
|
114
|
+
3. Prove refresh token reuse without rotation detection or revocation.
|
|
115
|
+
4. Confirm header abuse (kid/jku/x5u/jwk) leading to key selection under attacker control.
|
|
116
|
+
5. Provide owner vs non-owner evidence with identical requests differing only in token context.
|
|
109
117
|
</validation>
|
|
110
118
|
|
|
111
119
|
<false_positives>
|
|
112
|
-
|
|
113
|
-
-
|
|
114
|
-
-
|
|
115
|
-
-
|
|
116
|
-
- Token expiration enforced
|
|
117
|
-
- Rate limiting prevents brute force
|
|
120
|
+
- Token rejected due to strict audience/issuer enforcement
|
|
121
|
+
- Key pinning with JWKS whitelist and TLS validation
|
|
122
|
+
- Short-lived tokens with rotation and revocation on logout
|
|
123
|
+
- ID token not accepted by APIs that require access tokens
|
|
118
124
|
</false_positives>
|
|
119
125
|
|
|
120
126
|
<impact>
|
|
121
|
-
- Account takeover
|
|
122
|
-
- Privilege escalation
|
|
123
|
-
-
|
|
124
|
-
-
|
|
125
|
-
- Persistent access: survives logout
|
|
127
|
+
- Account takeover and durable session persistence
|
|
128
|
+
- Privilege escalation via claim manipulation or cross-service acceptance
|
|
129
|
+
- Cross-tenant or cross-application data access
|
|
130
|
+
- Token minting by attacker-controlled keys or endpoints
|
|
126
131
|
</impact>
|
|
127
132
|
|
|
128
|
-
<
|
|
133
|
+
<pro_tips>
|
|
134
|
+
1. Pin verification to issuer and audience; log and diff claim sets across services.
|
|
135
|
+
2. Attempt RS256→HS256 and "none" first only if algorithm pinning is unclear; otherwise focus on header key control (kid/jku/x5u/jwk).
|
|
136
|
+
3. Test token reuse across all services; many backends only check signature, not audience/typ.
|
|
137
|
+
4. Exploit JWKS caching and rotation races; try retired keys and missing kid fallbacks.
|
|
138
|
+
5. Exercise OIDC flows with PKCE/state/nonce variants and mixed clients; look for mix-up.
|
|
139
|
+
6. Try DPoP/mTLS absence to replay tokens from different devices.
|
|
140
|
+
7. Treat refresh as its own surface: rotation, reuse detection, and audience scoping.
|
|
141
|
+
8. Validate every acceptance path: gateway, service, worker, WebSocket, and gRPC.
|
|
142
|
+
9. Favor minimal PoCs that clearly show cross-context acceptance and durable access.
|
|
143
|
+
10. When in doubt, assume verification differs per stack (mobile vs web vs gateway) and test each.
|
|
144
|
+
</pro_tips>
|
|
145
|
+
|
|
146
|
+
<remember>Verification must bind the token to the correct issuer, audience, key, and client context on every acceptance path. Any missing binding enables forgery or confusion.</remember>
|
|
129
147
|
</authentication_jwt_guide>
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
<broken_function_level_authorization_guide>
|
|
2
|
+
<title>BROKEN FUNCTION LEVEL AUTHORIZATION (BFLA)</title>
|
|
3
|
+
|
|
4
|
+
<critical>BFLA is action-level authorization failure: callers invoke functions (endpoints, mutations, admin tools) they are not entitled to. It appears when enforcement differs across transports, gateways, roles, or when services trust client hints. Bind subject × action at the service that performs the action.</critical>
|
|
5
|
+
|
|
6
|
+
<scope>
|
|
7
|
+
- Vertical authz: privileged/admin/staff-only actions reachable by basic users
|
|
8
|
+
- Feature gates: toggles enforced at edge/UI, not at core services
|
|
9
|
+
- Transport drift: REST vs GraphQL vs gRPC vs WebSocket with inconsistent checks
|
|
10
|
+
- Gateway trust: backends trust X-User-Id/X-Role injected by proxies/edges
|
|
11
|
+
- Background workers/jobs performing actions without re-checking authz
|
|
12
|
+
</scope>
|
|
13
|
+
|
|
14
|
+
<methodology>
|
|
15
|
+
1. Build an Actor × Action matrix with at least: unauth, basic, premium, staff/admin. Enumerate actions (create/update/delete, approve/cancel, impersonate, export, invite, role-change, credit/refund).
|
|
16
|
+
2. Obtain tokens/sessions for each role. Exercise every action across all transports and encodings (JSON, form, multipart), including method overrides.
|
|
17
|
+
3. Vary headers and contextual selectors (org/tenant/project) and test behavior behind gateway vs direct-to-service.
|
|
18
|
+
4. Include background flows: job creation/finalization, webhooks, queues. Confirm re-validation of authz in consumers.
|
|
19
|
+
</methodology>
|
|
20
|
+
|
|
21
|
+
<discovery_techniques>
|
|
22
|
+
<surface_enumeration>
|
|
23
|
+
- Admin/staff consoles and APIs, support tools, internal-only endpoints exposed via gateway
|
|
24
|
+
- Hidden buttons and disabled UI paths (feature-flagged) mapped to still-live endpoints
|
|
25
|
+
- GraphQL schemas: mutations and admin-only fields/types; gRPC service descriptors (reflection)
|
|
26
|
+
- Mobile clients often reveal extra endpoints/roles in app bundles or network logs
|
|
27
|
+
</surface_enumeration>
|
|
28
|
+
|
|
29
|
+
<signals>
|
|
30
|
+
- 401/403 on UI but 200 via direct API call; differing status codes across transports
|
|
31
|
+
- Actions succeed via background jobs when direct call is denied
|
|
32
|
+
- Changing only headers (role/org) alters access without token change
|
|
33
|
+
</signals>
|
|
34
|
+
|
|
35
|
+
<high_value_actions>
|
|
36
|
+
- Role/permission changes, impersonation/sudo, invite/accept into orgs
|
|
37
|
+
- Approve/void/refund/credit issuance, price/plan overrides
|
|
38
|
+
- Export/report generation, data deletion, account suspension/reactivation
|
|
39
|
+
- Feature flag toggles, quota/grant adjustments, license/seat changes
|
|
40
|
+
- Security settings: 2FA reset, email/phone verification overrides
|
|
41
|
+
</high_value_actions>
|
|
42
|
+
|
|
43
|
+
<exploitation_techniques>
|
|
44
|
+
<verb_drift_and_aliases>
|
|
45
|
+
- Alternate methods: GET performing state change; POST vs PUT vs PATCH differences; X-HTTP-Method-Override/_method
|
|
46
|
+
- Alternate endpoints performing the same action with weaker checks (legacy vs v2, mobile vs web)
|
|
47
|
+
</verb_drift_and_aliases>
|
|
48
|
+
|
|
49
|
+
<edge_vs_core_mismatch>
|
|
50
|
+
- Edge blocks an action but core service RPC accepts it directly; call internal service via exposed API route or SSRF
|
|
51
|
+
- Gateway-injected identity headers override token claims; supply conflicting headers to test precedence
|
|
52
|
+
</edge_vs_core_mismatch>
|
|
53
|
+
|
|
54
|
+
<feature_flag_bypass>
|
|
55
|
+
- Client-checked feature gates; call backend endpoints directly
|
|
56
|
+
- Admin-only mutations exposed but hidden in UI; invoke via GraphQL or gRPC tools
|
|
57
|
+
</feature_flag_bypass>
|
|
58
|
+
|
|
59
|
+
<batch_job_paths>
|
|
60
|
+
- Create export/import jobs where creation is allowed but finalize/approve lacks authz; finalize others' jobs
|
|
61
|
+
- Replay webhooks/background tasks endpoints that perform privileged actions without verifying caller
|
|
62
|
+
</batch_job_paths>
|
|
63
|
+
|
|
64
|
+
<content_type_paths>
|
|
65
|
+
- JSON vs form vs multipart handlers using different middleware: send the action via the most permissive parser
|
|
66
|
+
</content_type_paths>
|
|
67
|
+
</exploitation_techniques>
|
|
68
|
+
|
|
69
|
+
<advanced_techniques>
|
|
70
|
+
<graphql>
|
|
71
|
+
- Resolver-level checks per mutation/field; do not assume top-level auth covers nested mutations or admin fields
|
|
72
|
+
- Abuse aliases/batching to sneak privileged fields; persisted queries sometimes bypass auth transforms
|
|
73
|
+
- Example:
|
|
74
|
+
{% raw %}
|
|
75
|
+
mutation Promote($id:ID!){
|
|
76
|
+
a: updateUser(id:$id, role: ADMIN){ id role }
|
|
77
|
+
}
|
|
78
|
+
{% endraw %}
|
|
79
|
+
</graphql>
|
|
80
|
+
|
|
81
|
+
<grpc>
|
|
82
|
+
- Method-level auth via interceptors must enforce audience/roles; probe direct gRPC with tokens of lower role
|
|
83
|
+
- Reflection lists services/methods; call admin methods that the gateway hid
|
|
84
|
+
</grpc>
|
|
85
|
+
|
|
86
|
+
<websocket>
|
|
87
|
+
- Handshake-only auth: ensure per-message authorization on privileged events (e.g., admin:impersonate)
|
|
88
|
+
- Try emitting privileged actions after joining standard channels
|
|
89
|
+
</websocket>
|
|
90
|
+
|
|
91
|
+
<multi_tenant>
|
|
92
|
+
- Actions requiring tenant admin enforced only by header/subdomain; attempt cross-tenant admin actions by switching selectors with same token
|
|
93
|
+
</multi_tenant>
|
|
94
|
+
|
|
95
|
+
<microservices>
|
|
96
|
+
- Internal RPCs trust upstream checks; reach them through exposed endpoints or SSRF; verify each service re-enforces authz
|
|
97
|
+
</microservices>
|
|
98
|
+
|
|
99
|
+
<bypass_techniques>
|
|
100
|
+
<header_trust>
|
|
101
|
+
- Supply X-User-Id/X-Role/X-Organization headers; remove or contradict token claims; observe which source wins
|
|
102
|
+
</header_trust>
|
|
103
|
+
|
|
104
|
+
<route_shadowing>
|
|
105
|
+
- Legacy/alternate routes (e.g., /admin/v1 vs /v2/admin) that skip new middleware chains
|
|
106
|
+
</route_shadowing>
|
|
107
|
+
|
|
108
|
+
<idempotency_and_retries>
|
|
109
|
+
- Retry or replay finalize/approve endpoints that apply state without checking actor on each call
|
|
110
|
+
</idempotency_and_retries>
|
|
111
|
+
|
|
112
|
+
<cache_key_confusion>
|
|
113
|
+
- Cached authorization decisions at edge leading to cross-user reuse; test with Vary and session swaps
|
|
114
|
+
</cache_key_confusion>
|
|
115
|
+
</bypass_techniques>
|
|
116
|
+
|
|
117
|
+
<validation>
|
|
118
|
+
1. Show a lower-privileged principal successfully invokes a restricted action (same inputs) while the proper role succeeds and another lower role fails.
|
|
119
|
+
2. Provide evidence across at least two transports or encodings demonstrating inconsistent enforcement.
|
|
120
|
+
3. Demonstrate that removing/altering client-side gates (buttons/flags) does not affect backend success.
|
|
121
|
+
4. Include durable state change proof: before/after snapshots, audit logs, and authoritative sources.
|
|
122
|
+
</validation>
|
|
123
|
+
|
|
124
|
+
<false_positives>
|
|
125
|
+
- Read-only endpoints mislabeled as admin but publicly documented
|
|
126
|
+
- Feature toggles intentionally open to all roles for preview/beta with clear policy
|
|
127
|
+
- Simulated environments where admin endpoints are stubbed with no side effects
|
|
128
|
+
</false_positives>
|
|
129
|
+
|
|
130
|
+
<impact>
|
|
131
|
+
- Privilege escalation to admin/staff actions
|
|
132
|
+
- Monetary/state impact: refunds/credits/approvals without authorization
|
|
133
|
+
- Tenant-wide configuration changes, impersonation, or data deletion
|
|
134
|
+
- Compliance and audit violations due to bypassed approval workflows
|
|
135
|
+
</impact>
|
|
136
|
+
|
|
137
|
+
<pro_tips>
|
|
138
|
+
1. Start from the role matrix; test every action with basic vs admin tokens across REST/GraphQL/gRPC.
|
|
139
|
+
2. Diff middleware stacks between routes; weak chains often exist on legacy or alternate encodings.
|
|
140
|
+
3. Inspect gateways for identity header injection; never trust client-provided identity.
|
|
141
|
+
4. Treat jobs/webhooks as first-class: finalize/approve must re-check the actor.
|
|
142
|
+
5. Prefer minimal PoCs: one request that flips a privileged field or invokes an admin method with a basic token.
|
|
143
|
+
</pro_tips>
|
|
144
|
+
|
|
145
|
+
<remember>Authorization must bind the actor to the specific action at the service boundary on every request and message. UI gates, gateways, or prior steps do not substitute for function-level checks.</remember>
|
|
146
|
+
</broken_function_level_authorization_guide>
|