You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Chef Automate is a platform for infrastructure automation, compliance, and application delivery. It exposes a web UI (often Angular) that talks to backend gRPC services via a gRPC-Gateway, providing REST-like endpoints under paths such as /api/v0/.
8
+
9
+
- Common backend components: gRPC services, PostgreSQL (often visible via pq: error prefixes), data-collector ingest service
10
+
- Auth mechanisms: user/API tokens and a data collector token header x-data-collector-token
This page collects practical techniques to enumerate and attack Chef Automate instances, with emphasis on:
8
+
- Discovering gRPC-Gateway-backed REST endpoints and inferring request schemas via validation/error responses
9
+
- Abusing the x-data-collector-token authentication header when defaults are present
10
+
- Time-based blind SQL injection in the Compliance API (CVE-2025-8868) affecting the filters[].type field in /api/v0/compliance/profiles/search
11
+
12
+
> Note: Backend responses that include header grpc-metadata-content-type: application/grpc typically indicate a gRPC-Gateway bridging REST calls to gRPC services.
13
+
14
+
## Recon: Architecture and Fingerprints
15
+
16
+
- Front-end: Often Angular. Static bundles can hint at REST paths (e.g., /api/v0/...)
17
+
- API transport: REST to gRPC via gRPC-Gateway
18
+
- Responses may include grpc-metadata-content-type: application/grpc
19
+
- Database/driver fingerprints:
20
+
- Error bodies starting with pq: strongly suggest PostgreSQL with the Go pq driver
If present, this token can be used to call Compliance API endpoints otherwise gated by auth. Always attempt to rotate/disable defaults during hardening.
34
+
35
+
## API Schema Inference via Error-Driven Discovery
36
+
37
+
gRPC-Gateway-backed endpoints often leak useful validation errors that describe the expected request model.
38
+
39
+
For /api/v0/compliance/profiles/search, the backend expects a body with a filters array, where each element is an object with:
40
+
41
+
- type: string (filter field identifier)
42
+
- values: array of strings
43
+
44
+
Example request shape:
45
+
46
+
```json
47
+
{
48
+
"filters": [
49
+
{ "type": "name", "values": ["test"] }
50
+
]
51
+
}
52
+
```
53
+
54
+
Malformed JSON or wrong field types typically trigger 4xx/5xx with hints, and headers indicate the gRPC-Gateway behavior. Use these to map fields and localize injection surfaces.
55
+
56
+
## Compliance API SQL Injection (CVE-2025-8868)
57
+
58
+
- Affected endpoint: POST /api/v0/compliance/profiles/search
59
+
- Injection point: filters[].type
60
+
- Vulnerability class: time-based blind SQL injection in PostgreSQL
61
+
- Root cause: Lack of proper parameterization/whitelisting when interpolating the type field into a dynamic SQL fragment (likely used to construct identifiers/WHERE clauses). Crafted values in type are evaluated by PostgreSQL.
- HTTP 500 responses may include pq: details during probing, confirming SQL execution paths
103
+
104
+
> Tip: Use a timing validator (e.g., multiple trials with statistical comparison) to reduce noise and false positives.
105
+
106
+
### Impact
107
+
108
+
Authenticated users—or unauthenticated actors abusing a default x-data-collector-token—can execute arbitrary SQL within Chef Automate’s PostgreSQL context, risking confidentiality and integrity of compliance profiles, configuration, and telemetry.
109
+
110
+
### Affected versions / Fix
111
+
112
+
- CVE: CVE-2025-8868
113
+
- Upgrade guidance: Chef Automate 4.13.295 or later (Linux x86) per vendor advisories
114
+
115
+
## Detection and Forensics
116
+
117
+
- API layer:
118
+
- Monitor 500s on /api/v0/compliance/profiles/search where filters[].type contains quotes ('), concatenation (||), or function references like pg_sleep
119
+
- Inspect response headers for grpc-metadata-content-type to identify gRPC-Gateway flows
120
+
- Database layer (PostgreSQL):
121
+
- Audit for pg_sleep calls and malformed identifier errors (often surfaced with pq: prefixes coming from the Go pq driver)
122
+
- Authentication:
123
+
- Log and alert on usage of x-data-collector-token, especially known default values, across API paths
124
+
125
+
## Mitigations and Hardening
126
+
127
+
- Immediate:
128
+
- Rotate/disable default data collector tokens
129
+
- Restrict ingress to data collector endpoints; enforce strong, unique tokens
130
+
- Code-level:
131
+
- Parameterize queries; never string-concatenate SQL fragments
132
+
- Strictly whitelist allowed type values on the server (enum)
133
+
- Avoid dynamic SQL assembly for identifiers/clauses; if dynamic behavior is required, use safe identifier quoting and explicit whitelists
134
+
135
+
## Practical Testing Checklist
136
+
137
+
- Check if x-data-collector-token is accepted and whether the known default works
138
+
- Map the Compliance API request schema by inducing validation errors and reading error messages/headers
139
+
- Test for SQLi in less obvious “identifier-like” fields (e.g., filters[].type), not just values arrays or top-level text fields
140
+
- Use time-based techniques with concatenation to keep SQL syntactically valid across contexts
141
+
142
+
## References
143
+
144
+
-[Cooking an SQL Injection Vulnerability in Chef Automate (XBOW blog)](https://xbow.com/blog/cooking-an-sql-injection-vulnerability-in-chef-automate)
Hiding the signup button in the frontend is not enough. If the **Auth server still allows signups**, an attacker can call the API directly with the public `anon` key and create arbitrary users.
- Disable email/password signups in the Dashboard: Authentication → Providers → Email → Disable sign ups (invite-only), or set the equivalent GoTrue setting.
147
+
- Verify the API now returns 4xx to the previous call and no new user is created.
148
+
- If you rely on invites or SSO, ensure all other providers are disabled unless explicitly needed.
149
+
150
+
## RLS and Views: Write bypass via PostgREST
151
+
152
+
Using a Postgres VIEW to “hide” sensitive columns and exposing it via PostgREST can change how privileges are evaluated. In PostgreSQL:
153
+
- Ordinary views execute with the privileges of the view owner by default (definer semantics). In PG ≥15 you can opt into `security_invoker`.
154
+
- Row Level Security (RLS) applies on base tables. Table owners bypass RLS unless `FORCE ROW LEVEL SECURITY` is set on the table.
155
+
- Updatable views can accept INSERT/UPDATE/DELETE that are then applied to the base table. Without `WITH CHECK OPTION`, writes that don’t match the view predicate may still succeed.
156
+
157
+
Risk pattern observed in the wild:
158
+
- A reduced-column view is exposed through Supabase REST and granted to `anon`/`authenticated`.
159
+
- PostgREST allows DML on the updatable view and the operation is evaluated with the view owner’s privileges, effectively bypassing the intended RLS policies on the base table.
160
+
- Result: low-privileged clients can mass-edit rows (e.g., profile bios/avatars) they should not be able to modify.
161
+
162
+
Illustrative write via view (attempted from a public client):
- Prefer exposing base tables with explicit, least-privilege grants and precise RLS policies.
176
+
- If you must expose a view:
177
+
- Make it non-updatable (e.g., include expressions/joins) or deny `INSERT/UPDATE/DELETE` on the view to all untrusted roles.
178
+
- Enforce `ALTER VIEW <v> SET (security_invoker = on)` so the invoker’s privileges are used instead of the owner’s.
179
+
- On base tables, use `ALTER TABLE <t> FORCE ROW LEVEL SECURITY;` so even owners are subject to RLS.
180
+
- If allowing writes via an updatable view, add `WITH [LOCAL|CASCADED] CHECK OPTION` and complementary RLS on base tables to ensure only allowed rows can be written/changed.
181
+
- In Supabase, avoid granting `anon`/`authenticated` any write privileges on views unless you have verified end-to-end behavior with tests.
182
+
183
+
Detection tip:
184
+
- From `anon` and an `authenticated` test user, attempt all CRUD operations against every exposed table/view. Any successful write where you expected denial indicates a misconfiguration.
185
+
186
+
### OpenAPI-driven CRUD probing from anon/auth roles
187
+
188
+
PostgREST exposes an OpenAPI document that you can use to enumerate all REST resources, then automatically probe allowed operations from low-privileged roles.
189
+
190
+
Fetch the OpenAPI (works with the public anon key):
- Automate the previous probes for both `anon` and a minimally `authenticated` user and integrate them in CI to catch regressions.
236
+
- Treat every exposed table/view/function as a first-class surface. Don’t assume a view “inherits” the same RLS posture as its base tables.
237
+
130
238
### Passwords & sessions
131
239
132
240
It's possible to indicate the minimum password length (by default), requirements (no by default) and disallow to use leaked passwords.\
@@ -160,7 +268,13 @@ It's possible to set an SMTP to send emails.
160
268
161
269
It's possible to **store secrets** in supabase also which will be **accessible by edge functions** (the can be created and deleted from the web, but it's not possible to access their value directly).
162
270
163
-
{{#include ../banners/hacktricks-training.md}}
164
-
271
+
## References
165
272
273
+
-[Building Hacker Communities: Bug Bounty Village, getDisclosed’s Supabase Misconfig, and the LHE Squad (Ep. 133) – YouTube](https://youtu.be/NI-eXMlXma4)
AWS IAM RolesAnywhere allows workloads outside AWS to assume IAM roles using X.509 certificates. But when trust policies aren't properly scoped, they can be abused for privilege escalation.
102
102
103
+
To understand this attack, it is necessary to explain what a trust anchor is. A trust anchor in AWS IAM Roles Anywhere is the root of trust entity, it contains the public certificate of a Certificate Authority (CA) that is registered in the account so that AWS can validate the presented X.509 certificates. In this way, if the client certificate was issued by that CA and the trust anchor is active, AWS recognizes it as valid.
104
+
105
+
In addition, a profile is the configuration that defines which attributes of the X.509 certificate (such as CN, OU, or SAN) will be transformed into session tags, and these tags will later be compared against the conditions of the trust policy.
106
+
103
107
This policy lacks restrictions on which trust anchor or certificate attributes are allowed. As a result, any certificate tied to any trust anchor in the account can be used to assume this role.
The trust anchor validates that the client certificate `readonly.pem` comes from its authorized CA, when the trust anchor was created the CA’s public certificate was included (and now used to validate `readonly.pem`). Inside `readonly.pem`is the public key, which AWS uses to verify that the signature was made with its corresponding private key `readonly.key`.
142
+
The trust anchor validates that the client’s `readonly.pem`certificate comes from its authorized CA, and within this `readonly.pem` certificate is the public key that AWS uses to verify that the signature was made with its corresponding private key `readonly.key`.
139
143
140
-
The certificate also proves identity and provides attributes (such as CN or OU) that the `default` profile transforms into tags, which the role’s trust policy can use to decide whether to authorize access, if there are no conditions in the trust policy, those tags are ignored and anyone with a valid certificate is allowed through.
144
+
The certificate also provides attributes (such as CN or OU) that the `default` profile transforms into tags, which the role’s trust policy can use to decide whether to authorize access. If there are no conditions in the trust policy, those tags have no use, and access is granted to anyone with a valid certificate.
141
145
142
-
For this attack to be possible, both the trust anchor and the default profile must be active.
146
+
For this attack to be possible, both the trust anchor and the `default` profile must be active.
0 commit comments