Cooking an SQL Injection Vulnerability in Chef Automate
How a little-known default token provided the entry point for XBOW to uncover a critical SQL injection in an unexpected API parameter.
Cooking an SQL Injection Vulnerability in Chef Automate
XBOW discovered a critical SQL injection vulnerability in Chef Automate, an open source IT automation platform. The vulnerability allows authenticated attackers to execute arbitrary SQL commands against the underlying PostgreSQL database, potentially compromising sensitive configuration and compliance data.
While XBOW initially detected this vulnerability in a specific target contained in the scope of one of the bug bounty programs it has been invited to participate in. The XBOW team later realized that this issue actually affected the upstream project: Chef Automate, so it was properly disclosed to the Chef team.
This blogpost describes XBOW’s journey from an URL to uncovering an SQL injection, with an interesting detour to a default and not very known authentication token.
Discovery Process
XBOW's investigation began with standard reconnaissance techniques against the target Chef Automate instance. Initial exploration revealed an Angular-based web application with multiple API endpoints exposed under /api/v0/. The reconnaissance phase included examining the application's JavaScript bundles to identify potential API endpoints and analyzing the overall application architecture.

During the endpoint enumeration phase, XBOW discovered several interesting API paths including compliance-related endpoints like /api/v0/compliance/profiles/search, /api/v0/compliance/scanner/jobs/search, and various data management endpoints. Most of these endpoints returned authentication errors when accessed without proper credentials.
The first interesting discovery came when XBOW tested the data collector functionality. Chef Automate includes a data collector service that ingests telemetry and configuration data from managed infrastructure. XBOW discovered that this service uses a specific authentication token transmitted via the x-data-collector-token header. Through knowledge of common Chef Automate configurations, XBOW identified a default token value: 93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9cbd1c506
.
Note that this token was not found in the target application static files whatsoever, but can be found in some GitHub repositories (if you google it, there is exactly one page of results!). XBOW had memorized this token and casually attempted to authenticate using it, having surprising success:

This token provided access to several previously protected API endpoints, including the compliance profiles search endpoint at /api/v0/compliance/profiles/search. XBOW systematically analyzed the expected JSON structure for this endpoint by observing error messages returned by the gRPC-based API. The application uses gRPC-gateway to translate REST calls to gRPC backend services, as evidenced by the grpc-metadata-content-type: application/grpc response headers.
Through careful analysis of error responses, XBOW determined that the search endpoint expects a specific JSON structure containing a filters array. Each filter object requires type and values fields, where type specifies the filter criterion and values contains an array of search terms.

Vulnerability Analysis
XBOW tested various injection points within the API request structure, initially focusing on the values array and top-level fields like name. These attempts consistently returned normal responses without exhibiting vulnerable behavior, suggesting proper input sanitization in those contexts.
However, when XBOW attempted SQL injection in the type field of the filters array, the application began returning HTTP 500 errors with revealing PostgreSQL error messages. The error prefix "pq:" indicated the application uses PostgreSQL with the pq driver, and the specific error messages showed that injected SQL syntax was being processed by the database engine.

After several attempts with different SQL injection techniques, XBOW successfully crafted a payload using PostgreSQL's string concatenation operator. The final working payload structure was:
{"filters": [{"type": "name'||(SELECT pg_sleep(5))||'", "values": ["test"]}]}
This payload works by breaking out of the string context with a single quote, concatenating a subquery that executes pg_sleep(), and then concatenating back to a string to maintain SQL syntax validity. The string concatenation approach ensures that regardless of how the type field is used in the underlying SQL query, the pg_sleep() function will execute during query processing.

Exploitation Verification
XBOW crafted two specific HTTP requests to demonstrate the vulnerability:
Request with 1-second delay:
POST /api/v0/compliance/profiles/search HTTP/1.1
Host: [REDACTED]
Content-Type: application/json
x-data-collector-token: 93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9cbd1c506
{"filters": [{"type": "name'||(SELECT pg_sleep(1))||'", "values": ["test"]}]}
Request with 5-second delay:
POST /api/v0/compliance/profiles/search HTTP/1.1
Host: [REDACTED]
Content-Type: application/json
x-data-collector-token: 93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9cbd1c506
{"filters": [{"type": "name'||(SELECT pg_sleep(5))||'", "values": ["test"]}]}
XBOW’s SQL injection validator confirmed statistically significant timing differences between the two requests, proving the successful execution of arbitrary SQL commands within the application's database context.
Aftermath
Following CVD practices, the XBOW team reported this issue to Chef as soon as it was validated. The CVE-2025-8868 was granted to XBOW. We want to thank the Progress team for their prompt response and fix of this issue.
This discovery underscores the critical importance of systematic vulnerability testing, even in widely adopted open-source projects like Chef Automate. While open-source software often benefits from community scrutiny, mission-critical platforms handling sensitive data require diligent, proactive security assessments.
Organizations using Chef Automate on Linux x86 must take immediate action, we encourage all users to upgrade to version 4.13.295 or later to or later immediately to protect their environments.