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,126 @@
|
|
|
1
|
+
<nextjs_security_testing_guide>
|
|
2
|
+
<title>NEXT.JS — ADVERSARIAL TESTING PLAYBOOK</title>
|
|
3
|
+
|
|
4
|
+
<critical>Modern Next.js combines multiple execution contexts (Edge, Node, RSC, client) with smart caching (ISR/RSC fetch cache), middleware, and server actions. Authorization and cache boundaries must be enforced consistently across all paths or attackers will cross tenants, leak data, or invoke privileged actions.</critical>
|
|
5
|
+
|
|
6
|
+
<surface_map>
|
|
7
|
+
- Routers: App Router (`app/`) and Pages Router (`pages/`) coexist; test both
|
|
8
|
+
- Runtimes: Node.js vs Edge (V8 isolates with restricted APIs)
|
|
9
|
+
- Data paths: RSC (server components), Client components, Route Handlers (`app/api/**`), API routes (`pages/api/**`)
|
|
10
|
+
- Middleware: `middleware.ts`/`_middleware.ts`
|
|
11
|
+
- Rendering modes: SSR, SSG, ISR, on-demand revalidation, draft/preview mode
|
|
12
|
+
- Images: `next/image` optimization and remote loader
|
|
13
|
+
- Auth: NextAuth.js (callbacks, CSRF/state, callbackUrl), custom JWT/session bridges
|
|
14
|
+
- Server Actions: streamed POST with `Next-Action` header and action IDs
|
|
15
|
+
</surface_map>
|
|
16
|
+
|
|
17
|
+
<methodology>
|
|
18
|
+
1. Inventory routes (pages + app), static vs dynamic segments, and params. Map middleware coverage and runtime per path.
|
|
19
|
+
2. Capture baseline for each role (unauth, user, admin) across SSR, API routes, Route Handlers, Server Actions, and streaming data.
|
|
20
|
+
3. Diff responses while toggling runtime (Edge/Node), content-type, fetch cache directives, and preview/draft mode.
|
|
21
|
+
4. Probe caching and revalidation boundaries (ISR, RSC fetch, CDN) for cross-user/tenant leaks.
|
|
22
|
+
</methodology>
|
|
23
|
+
|
|
24
|
+
<high_value_targets>
|
|
25
|
+
- Middleware-protected routes (auth, geo, A/B)
|
|
26
|
+
- Admin/staff paths, draft/preview content, on-demand revalidate endpoints
|
|
27
|
+
- RSC payloads and flight data, streamed responses (server actions)
|
|
28
|
+
- Image optimizer and custom loaders, remotePatterns/domains
|
|
29
|
+
- NextAuth callbacks (`/api/auth/callback/*`), sign-in providers, CSRF/state handling
|
|
30
|
+
- Edge-only features (bot protection, IP gates) and their Node equivalents
|
|
31
|
+
</high_value_targets>
|
|
32
|
+
|
|
33
|
+
<advanced_techniques>
|
|
34
|
+
<middleware_bypass>
|
|
35
|
+
- Test for CVE-class middleware bypass via `x-middleware-subrequest` crafting and `x-nextjs-data` probing. Look for 307 + `x-middleware-rewrite`/`x-nextjs-redirect` headers and attempt bypass on protected routes.
|
|
36
|
+
- Attempt direct route access on Node vs Edge runtimes; confirm protection parity.
|
|
37
|
+
</middleware_bypass>
|
|
38
|
+
|
|
39
|
+
<server_actions>
|
|
40
|
+
- Capture streamed POSTs containing `Next-Action` headers. Map hashed action IDs via source maps or specialized tooling to discover hidden actions.
|
|
41
|
+
- Invoke actions out of UI flow and with alternate content-types; verify server-side authorization is enforced per action and not assumed from client state.
|
|
42
|
+
- Try cross-tenant/object references within action payloads to expose BOLA/IDOR via server actions.
|
|
43
|
+
</server_actions>
|
|
44
|
+
|
|
45
|
+
<rsc_and_cache>
|
|
46
|
+
- RSC fetch cache: probe `fetch` cache modes (force-cache, default, no-store) and revalidate tags/paths. Look for user-bound data cached without identity keys (ETag/Set-Cookie unaware).
|
|
47
|
+
- Confirm that personalized data is rendered via `no-store` or properly keyed; attempt cross-user content via shared caches/CDN.
|
|
48
|
+
- Inspect Flight data streams for serialized sensitive fields leaking through props.
|
|
49
|
+
</rsc_and_cache>
|
|
50
|
+
|
|
51
|
+
<isr_and_revalidation>
|
|
52
|
+
- Identify ISR pages (stale-while-revalidate). Check if responses may include user-bound fragments or tenant-dependent content.
|
|
53
|
+
- On-demand revalidation endpoints: look for weak secrets in URLs, referer-disclosed tokens, or unvalidated hosts triggering `revalidatePath`/`revalidateTag`.
|
|
54
|
+
- Attempt header-smuggling or method variations to trigger revalidation flows.
|
|
55
|
+
</isr_and_revalidation>
|
|
56
|
+
|
|
57
|
+
<draft_preview_mode>
|
|
58
|
+
- Draft/preview mode toggles via secret URLs/cookies; search for preview enable endpoints and secrets in client bundles/env leaks.
|
|
59
|
+
- Try setting preview cookies from subdomains, alternate paths, or through open redirects; observe content differences and persistence.
|
|
60
|
+
</draft_preview_mode>
|
|
61
|
+
|
|
62
|
+
<next_image_ssrf>
|
|
63
|
+
- Review `images.domains`/`remotePatterns` in `next.config.js`; test SSRF to internal hosts (IPv4/IPv6 variants, DNS rebinding) if patterns are broad.
|
|
64
|
+
- Custom loader functions may fetch with arbitrary URLs; test protocol smuggling and redirection chains.
|
|
65
|
+
- Attempt cache poisoning: craft same URL with different normalization to affect other users.
|
|
66
|
+
</next_image_ssrf>
|
|
67
|
+
|
|
68
|
+
<nextauth_pitfalls>
|
|
69
|
+
- State/nonce/PKCE: validate per-provider correctness; attempt missing/relaxed checks leading to login CSRF or token mix-up.
|
|
70
|
+
- Callback URL restrictions: open redirect in `callbackUrl` or mis-scoped allowed hosts; hijack sessions by forcing callbacks.
|
|
71
|
+
- JWT/session bridges: audience/issuer not enforced across API routes/Route Handlers; attempt cross-service token reuse.
|
|
72
|
+
</nextauth_pitfalls>
|
|
73
|
+
|
|
74
|
+
<edge_runtime_diffs>
|
|
75
|
+
- Edge runtime lacks certain Node APIs; defenses relying on Node-only modules may be skipped. Compare behavior of the same route in Edge vs Node.
|
|
76
|
+
- Header trust and IP determination can differ at the edge; test auth decisions tied to `x-forwarded-*` variance.
|
|
77
|
+
</edge_runtime_diffs>
|
|
78
|
+
|
|
79
|
+
<client_and_dom>
|
|
80
|
+
- Identify `dangerouslySetInnerHTML`, Markdown renderers, and user-controlled href/src attributes. Validate CSP/Trusted Types coverage for SSR/CSR/hydration.
|
|
81
|
+
- Attack hydration boundaries: server vs client render mismatches can enable gadget-based XSS.
|
|
82
|
+
</client_and_dom>
|
|
83
|
+
</advanced_techniques>
|
|
84
|
+
|
|
85
|
+
<bypass_techniques>
|
|
86
|
+
- Content-type switching: `application/json` ↔ `multipart/form-data` ↔ `application/x-www-form-urlencoded` to traverse alternate code paths.
|
|
87
|
+
- Method override/tunneling: `_method`, `X-HTTP-Method-Override`, GET on endpoints unexpectedly accepting writes.
|
|
88
|
+
- Case/param aliasing and query duplication affecting middleware vs handler parsing.
|
|
89
|
+
- Cache key confusion at CDN/proxy (lack of Vary on auth cookies/headers) to leak personalized SSR/ISR content.
|
|
90
|
+
</bypass_techniques>
|
|
91
|
+
|
|
92
|
+
<special_contexts>
|
|
93
|
+
<uploads_and_files>
|
|
94
|
+
- API routes and Route Handlers handling file uploads: check MIME sniffing, Content-Disposition, stored path traversal, and public serving of user files.
|
|
95
|
+
- Validate signing/scoping of any generated file URLs (short TTL, audience-bound).
|
|
96
|
+
</uploads_and_files>
|
|
97
|
+
|
|
98
|
+
<integrations_and_webhooks>
|
|
99
|
+
- Webhooks that trigger revalidation/imports: require HMAC verification; test with replay and cross-tenant object IDs.
|
|
100
|
+
- Analytics/AB testing flags controlled via cookies/headers; ensure they do not unlock privileged server paths.
|
|
101
|
+
</integrations_and_webhooks>
|
|
102
|
+
</special_contexts>
|
|
103
|
+
|
|
104
|
+
<validation>
|
|
105
|
+
1. Provide side-by-side requests for different principals showing cross-user/tenant content or actions.
|
|
106
|
+
2. Prove cache boundary failure (RSC/ISR/CDN) with response diffs or ETag collisions.
|
|
107
|
+
3. Demonstrate server action invocation outside UI with insufficient authorization checks.
|
|
108
|
+
4. Show middleware bypass (where applicable) with explicit headers and resulting protected content.
|
|
109
|
+
5. Include runtime parity checks (Edge vs Node) proving inconsistent enforcement.
|
|
110
|
+
</validation>
|
|
111
|
+
|
|
112
|
+
<pro_tips>
|
|
113
|
+
1. Enumerate with both App and Pages routers: many apps ship a hybrid surface.
|
|
114
|
+
2. Treat caching as an identity boundary—test with cookies stripped, altered, and with Vary/ETag diffs.
|
|
115
|
+
3. Decode client bundles for preview/revalidate secrets, action IDs, and hidden routes.
|
|
116
|
+
4. Use streaming-aware tooling to capture server actions and RSC payloads; diff flight data.
|
|
117
|
+
5. For NextAuth, fuzz provider params (state, nonce, scope, callbackUrl) and verify strictness.
|
|
118
|
+
6. Always retest under Edge and Node; misconfigurations often exist in only one runtime.
|
|
119
|
+
7. Probe `next/image` aggressively but safely—test IPv6/obscure encodings and redirect behavior.
|
|
120
|
+
8. Validate negative paths: other-user IDs, other-tenant headers/subdomains, lower roles.
|
|
121
|
+
9. Focus on export/report/download endpoints; they often bypass resolver-level checks.
|
|
122
|
+
10. Document minimal, reproducible PoCs; avoid noisy payloads—prefer precise diffs.
|
|
123
|
+
</pro_tips>
|
|
124
|
+
|
|
125
|
+
<remember>Next.js security breaks where identity, authorization, and caching diverge across routers, runtimes, and data paths. Bind subject, action, and object on every path, and key caches to identity and tenant explicitly.</remember>
|
|
126
|
+
</nextjs_security_testing_guide>
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
<graphql_protocol_guide>
|
|
2
|
+
<title>GRAPHQL — ADVANCED TESTING AND EXPLOITATION</title>
|
|
3
|
+
|
|
4
|
+
<critical>GraphQL’s flexibility enables powerful data access, but also unique failures: field- and edge-level authorization drift, schema exposure (even with introspection off), alias/batch abuse, resolver injection, federated trust gaps, and complexity/fragment bombs. Bind subject→action→object at resolver boundaries and validate across every transport and feature flag.</critical>
|
|
5
|
+
|
|
6
|
+
<scope>
|
|
7
|
+
- Queries, mutations, subscriptions (graphql-ws, graphql-transport-ws)
|
|
8
|
+
- Persisted queries/Automatic Persisted Queries (APQ)
|
|
9
|
+
- Federation (Apollo/GraphQL Mesh): _service SDL and _entities
|
|
10
|
+
- File uploads (GraphQL multipart request spec)
|
|
11
|
+
- Relay conventions: global node IDs, connections/cursors
|
|
12
|
+
</scope>
|
|
13
|
+
|
|
14
|
+
<methodology>
|
|
15
|
+
1. Fingerprint endpoint(s), transport(s), and stack (framework, plugins, gateway). Note GraphiQL/Playground exposure and CORS/credentials.
|
|
16
|
+
2. Obtain multiple principals (unauth, basic, premium, admin/staff) and capture at least one valid object ID per subject.
|
|
17
|
+
3. Acquire schema via introspection; if disabled, infer iteratively from errors, field suggestions, __typename probes, vocabulary brute-force.
|
|
18
|
+
4. Build an Actor × Operation × Type/Field matrix. Exercise each resolver path with swapped IDs, roles, tenants, and channels (REST proxies, GraphQL HTTP, WS).
|
|
19
|
+
5. Validate consistency: same authorization and validation across queries, mutations, subscriptions, batch/alias, persisted queries, and federation.
|
|
20
|
+
</methodology>
|
|
21
|
+
|
|
22
|
+
<discovery_techniques>
|
|
23
|
+
<endpoint_finding>
|
|
24
|
+
- Common paths: /graphql, /api/graphql, /v1/graphql, /gql
|
|
25
|
+
- Probe with minimal canary:
|
|
26
|
+
{% raw %}
|
|
27
|
+
POST /graphql {"query":"{__typename}"}
|
|
28
|
+
GET /graphql?query={__typename}
|
|
29
|
+
{% endraw %}
|
|
30
|
+
- Detect GraphiQL/Playground; note if accessible cross-origin and with credentials.
|
|
31
|
+
</endpoint_finding>
|
|
32
|
+
|
|
33
|
+
<introspection_and_inference>
|
|
34
|
+
- If enabled, dump full schema; otherwise:
|
|
35
|
+
- Use __typename on candidate fields to confirm types
|
|
36
|
+
- Abuse field suggestions and error shapes to enumerate names/args
|
|
37
|
+
- Infer enums from “expected one of” errors; coerce types by providing wrong shapes
|
|
38
|
+
- Reconstruct edges from pagination and connection hints (pageInfo, edges/node)
|
|
39
|
+
</introspection_and_inference>
|
|
40
|
+
|
|
41
|
+
<schema_construction>
|
|
42
|
+
- Map root operations, object types, interfaces/unions, directives (@auth, @defer, @stream), and custom scalars (Upload, JSON, DateTime)
|
|
43
|
+
- Identify sensitive fields: email, tokens, roles, billing, file keys, admin flags
|
|
44
|
+
- Note cascade paths where child resolvers may skip auth under parent assumptions
|
|
45
|
+
</schema_construction>
|
|
46
|
+
</discovery_techniques>
|
|
47
|
+
|
|
48
|
+
<exploitation_techniques>
|
|
49
|
+
<authorization_and_idor>
|
|
50
|
+
- Test field-level and edge-level checks, not just top-level gates. Pair owned vs foreign IDs within the same request via aliases to diff responses.
|
|
51
|
+
{% raw %}
|
|
52
|
+
query {
|
|
53
|
+
me { id }
|
|
54
|
+
a: order(id:"A_OWNER") { id total owner { id email } }
|
|
55
|
+
b: order(id:"B_FOREIGN") { id total owner { id email } }
|
|
56
|
+
}
|
|
57
|
+
{% endraw %}
|
|
58
|
+
- Probe mutations for partial updates that bypass validation (JSON Merge Patch semantics in inputs).
|
|
59
|
+
- Validate node/global ID resolvers (Relay) bind to the caller; decode/replace base64 IDs and compare access.
|
|
60
|
+
</authorization_and_idor>
|
|
61
|
+
|
|
62
|
+
<batching_and_alias>
|
|
63
|
+
- Alias to perform many logically separate reads in one operation; watch for per-request vs per-field auth discrepancies
|
|
64
|
+
- If array batching is supported (non-standard), submit multiple operations to bypass rate limits and achieve partial failures
|
|
65
|
+
{% raw %}
|
|
66
|
+
query {
|
|
67
|
+
u1:user(id:"1"){email}
|
|
68
|
+
u2:user(id:"2"){email}
|
|
69
|
+
u3:user(id:"3"){email}
|
|
70
|
+
}
|
|
71
|
+
{% endraw %}
|
|
72
|
+
</batching_and_alias>
|
|
73
|
+
|
|
74
|
+
<variable_and_shape_abuse>
|
|
75
|
+
- Scalars vs objects vs arrays: {% raw %}{id:123}{% endraw} vs {% raw %}{id:"123"}{% endraw} vs {% raw %}{id:[123]}{% endraw}; send null/empty/0/-1 and extra object keys retained by backend
|
|
76
|
+
- Duplicate keys in JSON variables: {% raw %}{"id":1,"id":2}{% endraw} (parser precedence), default argument values, coercion errors leaking field names
|
|
77
|
+
</variable_and_shape_abuse>
|
|
78
|
+
|
|
79
|
+
<cursor_and_projection>
|
|
80
|
+
- Decode cursors (often base64) to manipulate offsets/IDs and skip filters
|
|
81
|
+
- Abuse selection sets and fragments to force overfetching of sensitive subfields
|
|
82
|
+
</cursor_and_projection>
|
|
83
|
+
|
|
84
|
+
<file_uploads>
|
|
85
|
+
- GraphQL multipart: test multiple Upload scalars, filename/path tricks, unexpected content-types, oversize chunks; verify server-side ownership/scoping for returned URLs
|
|
86
|
+
</file_uploads>
|
|
87
|
+
</exploitation_techniques>
|
|
88
|
+
|
|
89
|
+
<advanced_techniques>
|
|
90
|
+
<introspection_bypass>
|
|
91
|
+
- Field suggestion leakage: submit near-miss names to harvest suggestions
|
|
92
|
+
- Error taxonomy: different codes/messages for unknown field vs unauthorized field reveal existence
|
|
93
|
+
- __typename sprinkling on edges to confirm types without schema
|
|
94
|
+
</introspection_bypass>
|
|
95
|
+
|
|
96
|
+
<defer_and_stream>
|
|
97
|
+
- Use @defer and @stream to obtain partial results or subtrees hidden by parent checks; confirm server supports incremental delivery
|
|
98
|
+
{% raw %}
|
|
99
|
+
query @defer {
|
|
100
|
+
me { id }
|
|
101
|
+
... @defer { adminPanel { secrets } }
|
|
102
|
+
}
|
|
103
|
+
{% endraw %}
|
|
104
|
+
</defer_and_stream>
|
|
105
|
+
|
|
106
|
+
<fragment_and_complexity_bombs>
|
|
107
|
+
- Recursive fragment spreads and wide selection sets cause CPU/memory spikes; craft minimal reproducible bombs to validate cost limits
|
|
108
|
+
{% raw %}
|
|
109
|
+
fragment x on User { friends { ...x } }
|
|
110
|
+
query { me { ...x } }
|
|
111
|
+
{% endraw %}
|
|
112
|
+
- Validate depth/complexity limiting, query cost analyzers, and timeouts
|
|
113
|
+
</fragment_and_complexity_bombs>
|
|
114
|
+
|
|
115
|
+
<federation>
|
|
116
|
+
- Apollo Federation: query _service { sdl } if exposed; target _entities to materialize foreign objects by key without proper auth in subgraphs
|
|
117
|
+
{% raw %}
|
|
118
|
+
query {
|
|
119
|
+
_entities(representations:[
|
|
120
|
+
{__typename:"User", id:"TARGET"}
|
|
121
|
+
]) { ... on User { email roles } }
|
|
122
|
+
}
|
|
123
|
+
{% endraw %}
|
|
124
|
+
- Look for auth done at gateway but skipped in subgraph resolvers; cross-subgraph IDOR via inconsistent ownership checks
|
|
125
|
+
</federation>
|
|
126
|
+
|
|
127
|
+
<subscriptions>
|
|
128
|
+
- Check message-level authorization, not only handshake; attempt to subscribe to channels for other users/tenants; test cross-tenant event leakage
|
|
129
|
+
- Abuse filter args in subscription resolvers to reference foreign IDs
|
|
130
|
+
</subscriptions>
|
|
131
|
+
|
|
132
|
+
<persisted_queries>
|
|
133
|
+
- APQ hashes can be guessed/bruteforced or leaked from clients; replay privileged operations by supplying known hashes with attacker variables
|
|
134
|
+
- Validate that hash→operation mapping enforces principal and operation allowlists
|
|
135
|
+
</persisted_queries>
|
|
136
|
+
|
|
137
|
+
<csrf_and_cors>
|
|
138
|
+
- If cookie-auth is used and GET is accepted, test CSRF on mutations via query parameters; verify SameSite and origin checks
|
|
139
|
+
- Cross-origin GraphiQL/Playground exposure with credentials can leak data via postMessage bridges
|
|
140
|
+
</csrf_and_cors>
|
|
141
|
+
|
|
142
|
+
<waf_evasion>
|
|
143
|
+
- Reshape queries: comments, block strings, Unicode escapes, alias/fragment indirection, JSON variables vs inline args, GET vs POST vs application/graphql
|
|
144
|
+
- Split fields across fragments and inline spreads to avoid naive signatures
|
|
145
|
+
</waf_evasion>
|
|
146
|
+
</advanced_techniques>
|
|
147
|
+
|
|
148
|
+
<bypass_techniques>
|
|
149
|
+
<transport_and_parsers>
|
|
150
|
+
- Toggle content-types: application/json, application/graphql, multipart/form-data; try GET with query and variables params
|
|
151
|
+
- HTTP/2 multiplexing and connection reuse to widen timing windows and rate limits
|
|
152
|
+
</transport_and_parsers>
|
|
153
|
+
|
|
154
|
+
<naming_and_aliasing>
|
|
155
|
+
- Case/underscore variations, Unicode homoglyphs (server-dependent), aliases masking sensitive field names
|
|
156
|
+
</naming_and_aliasing>
|
|
157
|
+
|
|
158
|
+
<gateway_and_cache>
|
|
159
|
+
- CDN/key confusion: responses cached without considering Authorization or variables; manipulate Vary and Accept headers
|
|
160
|
+
- Redirects and 304/206 behaviors leaking partially cached GraphQL responses
|
|
161
|
+
</gateway_and_cache>
|
|
162
|
+
</bypass_techniques>
|
|
163
|
+
|
|
164
|
+
<special_contexts>
|
|
165
|
+
<relay>
|
|
166
|
+
- node(id:…) global resolution: decode base64, swap type/id pairs, ensure per-type authorization is enforced inside resolvers
|
|
167
|
+
- Connections: verify that filters (owner/tenant) apply before pagination; cursor tampering should not cross ownership boundaries
|
|
168
|
+
</relay>
|
|
169
|
+
|
|
170
|
+
<server_plugins>
|
|
171
|
+
- Custom directives (@auth, @private) and plugins often annotate intent but do not enforce; verify actual checks in each resolver path
|
|
172
|
+
</server_plugins>
|
|
173
|
+
</special_contexts>
|
|
174
|
+
|
|
175
|
+
<chaining_attacks>
|
|
176
|
+
- GraphQL + IDOR: enumerate IDs via list fields, then fetch or mutate foreign objects
|
|
177
|
+
- GraphQL + CSRF: trigger mutations cross-origin when cookies/auth are accepted without proper checks
|
|
178
|
+
- GraphQL + SSRF: resolvers that fetch URLs (webhooks, metadata) abused to reach internal services
|
|
179
|
+
</chaining_attacks>
|
|
180
|
+
|
|
181
|
+
<validation>
|
|
182
|
+
1. Provide paired requests (owner vs non-owner) differing only in identifiers/roles that demonstrate unauthorized access or mutation.
|
|
183
|
+
2. Prove resolver-level bypass: show top-level checks present but child field/edge exposes data.
|
|
184
|
+
3. Demonstrate transport parity: reproduce via HTTP and WS (subscriptions) or via persisted queries.
|
|
185
|
+
4. Minimize payloads; document exact selection sets and variable shapes used.
|
|
186
|
+
</validation>
|
|
187
|
+
|
|
188
|
+
<false_positives>
|
|
189
|
+
- Introspection available only on non-production/stub endpoints
|
|
190
|
+
- Public fields by design with documented scopes
|
|
191
|
+
- Aggregations or counts without sensitive attributes
|
|
192
|
+
- Properly enforced depth/complexity and per-resolver authorization across transports
|
|
193
|
+
</false_positives>
|
|
194
|
+
|
|
195
|
+
<impact>
|
|
196
|
+
- Cross-account/tenant data exposure and unauthorized state changes
|
|
197
|
+
- Bypass of federation boundaries enabling lateral access across services
|
|
198
|
+
- Credential/session leakage via lax CORS/CSRF around GraphiQL/Playground
|
|
199
|
+
</impact>
|
|
200
|
+
|
|
201
|
+
<pro_tips>
|
|
202
|
+
1. Always diff the same operation under multiple principals with aliases in one request.
|
|
203
|
+
2. Sprinkle __typename to map types quickly when schema is hidden.
|
|
204
|
+
3. Attack edges: child resolvers often skip auth compared to parents.
|
|
205
|
+
4. Try @defer/@stream and subscriptions to slip gated data in incremental events.
|
|
206
|
+
5. Decode cursors and node IDs; assume base64 unless proven otherwise.
|
|
207
|
+
6. Federation: exercise _entities with crafted representations; subgraphs frequently trust gateway auth.
|
|
208
|
+
7. Persisted queries: extract hashes from clients; replay with attacker variables.
|
|
209
|
+
8. Keep payloads small and structured; restructure rather than enlarge to evade WAFs.
|
|
210
|
+
9. Validate defenses by code/config review where possible; don’t trust directives alone.
|
|
211
|
+
10. Prove impact with role-separated, transport-separated, minimal PoCs.
|
|
212
|
+
</pro_tips>
|
|
213
|
+
|
|
214
|
+
<remember>GraphQL security is resolver security. If any resolver on the path to a field fails to bind subject, object, and action, the graph leaks. Validate every path, every transport, every environment.</remember>
|
|
215
|
+
</graphql_protocol_guide>
|
|
File without changes
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
<firebase_firestore_security_guide>
|
|
2
|
+
<title>FIREBASE / FIRESTORE — ADVERSARIAL TESTING AND EXPLOITATION</title>
|
|
3
|
+
|
|
4
|
+
<critical>Most impactful findings in Firebase apps arise from weak Firestore/Realtime Database rules, Cloud Storage exposure, callable/onRequest Functions trusting client input, incorrect ID token validation, and over-trusted App Check. Treat every client-supplied field and token as untrusted. Bind subject/tenant on the server, not in the client.</critical>
|
|
5
|
+
|
|
6
|
+
<scope>
|
|
7
|
+
- Firestore (documents/collections, rules, REST/SDK)
|
|
8
|
+
- Realtime Database (JSON tree, rules)
|
|
9
|
+
- Cloud Storage (rules, signed URLs)
|
|
10
|
+
- Auth (ID tokens, custom claims, anonymous/sign-in providers)
|
|
11
|
+
- Cloud Functions (onCall/onRequest, triggers)
|
|
12
|
+
- Hosting rewrites, CDN/caching, CORS
|
|
13
|
+
- App Check (attestation) and its limits
|
|
14
|
+
</scope>
|
|
15
|
+
|
|
16
|
+
<methodology>
|
|
17
|
+
1. Extract project config from client (apiKey, authDomain, projectId, appId, storageBucket, messagingSenderId). Identify all used Firebase products.
|
|
18
|
+
2. Obtain multiple principals: unauth, anonymous (if enabled), basic user A, user B, and any staff/admin if available. Capture their ID tokens.
|
|
19
|
+
3. Build Resource × Action × Principal matrix across Firestore/Realtime/Storage/Functions. Exercise every action via SDK and raw REST (googleapis) to detect parity gaps.
|
|
20
|
+
4. Start from list/query paths (where allowed) to seed IDs; then swap document paths, tenants, and user IDs across principals and transports.
|
|
21
|
+
</methodology>
|
|
22
|
+
|
|
23
|
+
<architecture>
|
|
24
|
+
- Firestore REST: https://firestore.googleapis.com/v1/projects/<project>/databases/(default)/documents/<path>
|
|
25
|
+
- Storage REST: https://storage.googleapis.com/storage/v1/b/<bucket>
|
|
26
|
+
- Auth: Google-signed ID tokens (iss accounts.google.com/securetoken.google.com/<project>), aud <project/app-id>; identity is in sub/uid.
|
|
27
|
+
- Rules engines: separate for Firestore, Realtime DB, and Storage; Functions bypass rules when using Admin SDK.
|
|
28
|
+
</architecture>
|
|
29
|
+
|
|
30
|
+
<auth_and_tokens>
|
|
31
|
+
- ID token verification must enforce issuer, audience (project), signature (Google JWKS), expiration, and optionally App Check binding when used.
|
|
32
|
+
- Custom claims are appended by Admin SDK; client-supplied claims are ignored by Auth but may be trusted by app code if copied into docs.
|
|
33
|
+
- Pitfalls:
|
|
34
|
+
- Accepting any JWT with valid signature but wrong audience/project.
|
|
35
|
+
- Trusting uid/account IDs from request body instead of context.auth.uid in Functions.
|
|
36
|
+
- Mixing session cookies and ID tokens without verifying both paths equivalently.
|
|
37
|
+
- Tests:
|
|
38
|
+
- Replay tokens across environments/projects; expect strict aud/iss rejection server-side.
|
|
39
|
+
- Call Functions with and without Authorization; verify identical checks on both onCall and onRequest variants.
|
|
40
|
+
</auth_and_tokens>
|
|
41
|
+
|
|
42
|
+
<firestore_rules>
|
|
43
|
+
- Rules are not filters: a query must include constraints that make the rule true for all returned documents; otherwise reads fail. Do not rely on client to include where clauses correctly.
|
|
44
|
+
- Prefer ownership derived from request.auth.uid and server data, not from client payload fields.
|
|
45
|
+
- Common gaps:
|
|
46
|
+
- allow read: if request.auth != null (any user reads all data)
|
|
47
|
+
- allow write: if request.auth != null (mass write)
|
|
48
|
+
- Missing per-field validation (adds isAdmin/role/tenantId fields).
|
|
49
|
+
- Using client-supplied ownerId/orgId instead of enforcing doc.ownerId == request.auth.uid or membership in org.
|
|
50
|
+
- Over-broad list rules on root collections; per-doc checks exist but list still leaks via queries.
|
|
51
|
+
- Validation patterns:
|
|
52
|
+
- Restrict writes: request.resource.data.keys().hasOnly([...]) and forbid privilege fields.
|
|
53
|
+
- Enforce ownership: resource.data.ownerId == request.auth.uid && request.resource.data.ownerId == request.auth.uid
|
|
54
|
+
- Org membership: exists(/databases/(default)/documents/orgs/$(org)/members/$(request.auth.uid))
|
|
55
|
+
- Tests:
|
|
56
|
+
- Compare results for users A/B on identical queries; diff counts and IDs.
|
|
57
|
+
- Attempt cross-tenant reads: where orgId == otherOrg; try queries without org filter to confirm denial.
|
|
58
|
+
- Write-path: set/patch with foreign ownerId/orgId; attempt to flip privilege flags.
|
|
59
|
+
</firestore_rules>
|
|
60
|
+
|
|
61
|
+
<firestore_queries>
|
|
62
|
+
- Enumerate via REST to avoid SDK client-side constraints; try structured and REST filters.
|
|
63
|
+
- Probe composite index requirements: UI-driven queries may hide missing rule coverage when indexes are enabled but rules are broad.
|
|
64
|
+
- Explore collection group queries (collectionGroup) that may bypass per-collection rules if not mirrored.
|
|
65
|
+
- Use startAt/endAt/in/array-contains to probe rule edges and pagination cursors for cross-tenant bleed.
|
|
66
|
+
</firestore_queries>
|
|
67
|
+
|
|
68
|
+
<realtime_database>
|
|
69
|
+
- Misconfigured rules frequently expose entire JSON trees. Probe https://<project>.firebaseio.com/.json with and without auth.
|
|
70
|
+
- Confirm rules for read/write use auth.uid and granular path checks; avoid .read/.write: true or auth != null at high-level nodes.
|
|
71
|
+
- Attempt to write privilege-bearing nodes (roles, org membership) and observe downstream effects (e.g., Cloud Functions triggers).
|
|
72
|
+
</realtime_database>
|
|
73
|
+
|
|
74
|
+
<cloud_storage>
|
|
75
|
+
- Rules parallel Firestore but apply to object paths. Common issues:
|
|
76
|
+
- Public reads on sensitive buckets/paths.
|
|
77
|
+
- Signed URLs with long TTL, no content-disposition controls; replayable across tenants.
|
|
78
|
+
- List operations exposed: /o?prefix= enumerates object keys.
|
|
79
|
+
- Tests:
|
|
80
|
+
- GET gs:// paths via https endpoints without auth; verify content-type and Content-Disposition: attachment.
|
|
81
|
+
- Generate and reuse signed URLs across accounts and paths; try case/URL-encoding variants.
|
|
82
|
+
- Upload HTML/SVG and verify X-Content-Type-Options: nosniff; check for script execution.
|
|
83
|
+
</cloud_storage>
|
|
84
|
+
|
|
85
|
+
<cloud_functions>
|
|
86
|
+
- onCall provides context.auth automatically; onRequest must verify ID tokens explicitly. Admin SDK bypasses rules; all ownership/tenant checks must be enforced in code.
|
|
87
|
+
- Common gaps:
|
|
88
|
+
- Trusting client uid/orgId from request body instead of context.auth.
|
|
89
|
+
- Missing aud/iss verification when manually parsing tokens.
|
|
90
|
+
- Over-broad CORS allowing credentialed cross-origin requests; echoing Authorization in responses.
|
|
91
|
+
- Triggers (onCreate/onWrite) granting roles or issuing signed URLs solely based on document content controlled by the client.
|
|
92
|
+
- Tests:
|
|
93
|
+
- Call both onCall and equivalent onRequest endpoints with varied tokens and bodies; expect identical decisions.
|
|
94
|
+
- Create crafted docs to trigger privilege-granting functions; verify that server re-derives subject/tenant before acting.
|
|
95
|
+
- Attempt internal fetches (SSRF) via Functions to project/metadata endpoints.
|
|
96
|
+
</cloud_functions>
|
|
97
|
+
|
|
98
|
+
<app_check>
|
|
99
|
+
- App Check is not a substitute for authorization. Many apps enable App Check enforcement on client SDKs but do not verify on custom backends.
|
|
100
|
+
- Bypasses:
|
|
101
|
+
- Unenforced paths: REST calls directly to googleapis endpoints with ID token succeed regardless of App Check.
|
|
102
|
+
- Mobile reverse engineering: hook client and reuse ID token flows without attestation.
|
|
103
|
+
- Tests:
|
|
104
|
+
- Compare SDK vs REST behavior with/without App Check headers; confirm no elevated authorization via App Check alone.
|
|
105
|
+
</app_check>
|
|
106
|
+
|
|
107
|
+
<tenant_isolation>
|
|
108
|
+
- Apps often implement multi-tenant data models (orgs/<orgId>/...). Bind tenant from server context (membership doc or custom claim), not from client payload.
|
|
109
|
+
- Tests:
|
|
110
|
+
- Vary org header/subdomain/query while keeping token fixed; verify server denies cross-tenant access.
|
|
111
|
+
- Export/report Functions: ensure queries execute under caller scope; signed outputs must encode tenant and short TTL.
|
|
112
|
+
</tenant_isolation>
|
|
113
|
+
|
|
114
|
+
<bypass_techniques>
|
|
115
|
+
- Content-type switching: JSON vs form vs multipart to hit alternate code paths in onRequest Functions.
|
|
116
|
+
- Parameter/field pollution: duplicate JSON keys; last-one-wins in many parsers; attempt to sneak privilege fields.
|
|
117
|
+
- Caching/CDN: Hosting rewrites or proxies that key responses without Authorization or tenant headers.
|
|
118
|
+
- Race windows: write then read before background enforcements (e.g., post-write claim synchronizations) complete.
|
|
119
|
+
</bypass_techniques>
|
|
120
|
+
|
|
121
|
+
<blind_channels>
|
|
122
|
+
- Firestore: use error shape, document count, and ETag/length to infer existence under partial denial.
|
|
123
|
+
- Storage: length/timing differences on signed URL attempts leak validity.
|
|
124
|
+
- Functions: constant-time comparisons vs variable messages reveal authorization branches.
|
|
125
|
+
</blind_channels>
|
|
126
|
+
|
|
127
|
+
<tooling_and_automation>
|
|
128
|
+
- SDK + REST: httpie/curl + jq for REST; Firebase emulator and Rules Playground for rapid iteration.
|
|
129
|
+
- Mobile: apktool/objection/frida to extract config and hook SDK calls; inspect network logs for endpoints and tokens.
|
|
130
|
+
- Rules analysis: script rule probes for common patterns (auth != null, missing field validation, list vs get parity).
|
|
131
|
+
- Functions: fuzz onRequest endpoints with varied content-types and missing/forged Authorization; verify CORS and token handling.
|
|
132
|
+
- Storage: enumerate prefixes; test signed URL generation and reuse patterns.
|
|
133
|
+
</tooling_and_automation>
|
|
134
|
+
|
|
135
|
+
<reviewer_checklist>
|
|
136
|
+
- Do Firestore/Realtime/Storage rules derive subject and tenant from auth, not client fields?
|
|
137
|
+
- Are list/query rules aligned with per-doc checks (no broad list leaks)?
|
|
138
|
+
- Are privilege-bearing fields immutable or server-only (forbidden in writes)?
|
|
139
|
+
- Do Functions verify ID tokens (iss/aud/exp/signature) and re-derive identity before acting?
|
|
140
|
+
- Are Admin SDK operations scoped by server-side checks (ownership/tenant)?
|
|
141
|
+
- Is App Check treated as advisory, not authorization, across all paths?
|
|
142
|
+
- Are Hosting/CDN cache keys bound to Authorization/tenant to prevent leaks?
|
|
143
|
+
</reviewer_checklist>
|
|
144
|
+
|
|
145
|
+
<validation>
|
|
146
|
+
1. Provide owner vs non-owner Firestore queries showing unauthorized access or metadata leak.
|
|
147
|
+
2. Demonstrate Cloud Storage read/write beyond intended scope (public object, signed URL reuse, or list exposure).
|
|
148
|
+
3. Show a Function accepting forged/foreign identity (wrong aud/iss) or trusting client uid/orgId.
|
|
149
|
+
4. Document minimal reproducible requests with roles/tokens used and observed deltas.
|
|
150
|
+
</validation>
|
|
151
|
+
|
|
152
|
+
<false_positives>
|
|
153
|
+
- Public collections/objects documented and intended.
|
|
154
|
+
- Rules that correctly enforce per-doc checks with matching query constraints.
|
|
155
|
+
- Functions verifying tokens and ignoring client-supplied identifiers.
|
|
156
|
+
- App Check enforced but not relied upon for authorization.
|
|
157
|
+
</false_positives>
|
|
158
|
+
|
|
159
|
+
<impact>
|
|
160
|
+
- Cross-account and cross-tenant data exposure.
|
|
161
|
+
- Unauthorized state changes via Functions or direct writes.
|
|
162
|
+
- Exfiltration of PII/PHI and private files from Storage.
|
|
163
|
+
- Durable privilege escalation via misused custom claims or triggers.
|
|
164
|
+
</impact>
|
|
165
|
+
|
|
166
|
+
<pro_tips>
|
|
167
|
+
1. Treat apiKey as project identifier only; identity must come from verified ID tokens.
|
|
168
|
+
2. Start from rules: read them, then prove gaps with diffed owner/non-owner requests.
|
|
169
|
+
3. Prefer REST for parity checks; SDKs can mask errors via client-side filters.
|
|
170
|
+
4. Hunt privilege fields in docs and forbid them via rules; verify immutability.
|
|
171
|
+
5. Probe collectionGroup queries and list rules; many leaks live there.
|
|
172
|
+
6. Functions are the authority boundary—enforce subject/tenant there even if rules exist.
|
|
173
|
+
7. Keep concise PoCs: one owner vs non-owner request per surface that clearly demonstrates the unauthorized delta.
|
|
174
|
+
</pro_tips>
|
|
175
|
+
|
|
176
|
+
<remember>Authorization must hold at every layer: rules, Functions, and Storage. Bind subject and tenant from verified tokens and server data, never from client payload or UI assumptions. Any gap becomes a cross-account or cross-tenant vulnerability.</remember>
|
|
177
|
+
</firebase_firestore_security_guide>
|