Jul 13, 2026·5 min read·13 visits
An authenticated user with low privileges can perform blind SQL injection and unauthorized administrative tasks in the DIRAC framework due to unsanitized input formatting and overly permissive default access controls.
The DIRAC PilotManager component contains combined security weaknesses: a SQL injection vulnerability (CWE-89) in the PilotAgentsDB database interaction layer, and an improper access control configuration (CWE-284) within the default authorization structure. A low-privilege authenticated attacker can bypass intended authorization checks to run administrative commands, manipulate grid job tracking records, and execute arbitrary SQL statements against the backend database.
The DIRAC (Distributed Infrastructure with Remote Agent Control) software framework manages computing jobs and infrastructure components across distributed cloud and grid systems. Within the DIRAC Workload Management System (WMS), the PilotManager component acts as a core service for handling active pilot agents, which are responsible for launching jobs on remote nodes. The execution path is vulnerable to unauthorized remote modification due to structural weaknesses in both its access control limits and query assembly interfaces.
This vulnerability consists of an authorization bypass (CWE-284) coupled with a SQL injection flaw (CWE-89). Under standard deployments, the default communication handler exposes endpoints to modify grid metadata, alter database fields, and inspect execution diagnostics. Because the system's access configurations are excessively broad by default, the attack surface of the internal administrative handlers is exposed directly to any valid user holding authenticated status.
Once an authenticated session is established, an attacker can construct specially crafted payloads within procedural remote parameters. These values feed into the SQL construction interface of the workload tracking database. The resulting chain allows standard users to compromise metadata confidentiality, disrupt active computational pipelines, and execute arbitrary command syntax within the storage backend.
The SQL injection vulnerability originates in src/DIRAC/WorkloadManagementSystem/DB/PilotAgentsDB.py within the setPilotStatus method. When pilot properties require updates, variables are aggregated and structured dynamically. Rather than utilizing parameterized bindings or parameterized SQL statements, the application constructs the raw database update statements directly by formatting raw strings using dynamic Python f-string operators.
Several parameter values, such as statusReason, gridSite, and queue, are converted directly to query components via string interpolation (e.g., setList.append(f"StatusReason='{statusReason}'")). These components are then combined with the dynamic target identifier to compose the complete execution string: req = f"UPDATE PilotAgents SET {set_string} WHERE PilotJobReference='{pilotRef}'". Because the class uses raw dynamic strings and executes them through standard database update procedures without structural containment, any single quote delimiter breaks out of the expected execution context.
Simultaneously, the improper authorization boundary resides inside the global configuration registry template at src/DIRAC/WorkloadManagementSystem/ConfigTemplate.cfg. Under the default configurations of the PilotManager daemon, the configuration block contains the parameter definition Default = authenticated. This definition permits any caller possessing a valid transport-layer security (TLS) user certificate to issue remote execution calls to endpoints exposed by PilotManagerHandler.py, bypassing the expected administrative authorization checks.
An analysis of the vulnerable version of the source code highlights the absence of parameter escaping and input parsing. Below is the vulnerable segment of the setPilotStatus routine within PilotAgentsDB.py:
# Affected File: src/DIRAC/WorkloadManagementSystem/DB/PilotAgentsDB.py
def setPilotStatus(self, pilotRef, status, ...):
setList = []
setList.append(f"Status='{status}'")
# ...
if not statusReason:
statusReason = "Not given"
setList.append(f"StatusReason='{statusReason}'") # Direct dynamic interpolation
# ...
set_string = ",".join(setList)
req = f"UPDATE PilotAgents SET {set_string} WHERE PilotJobReference='{pilotRef}'"
return self._update(req, conn=conn) # Executed without parameterized argumentsThe corresponding patch addresses this by migrating from dynamic format string updates to structured binding. The updated execution logic abstracts inputs by generating a list of positional formatting markers (%s) and feeding the unsanitized parameter values separately into the database adapter:
# Patched File: src/DIRAC/WorkloadManagementSystem/DB/PilotAgentsDB.py
def setPilotStatus(self, pilotRef, status, ...):
setList = []
args = []
setList.append("Status=%s")
args.append(status)
# ...
if not statusReason:
statusReason = "Not given"
setList.append("StatusReason=%s") # Placeholder replaces literal parameter interpolation
args.append(statusReason)
# ...
set_string = ",".join(setList)
req = f"UPDATE PilotAgents SET {set_string} WHERE PilotJobReference=%s"
args.append(pilotRef)
return self._update(req, args=args, conn=conn) # Safe execution via parameterized bindingIn addition to database execution changes, the configuration registry must be updated to raise default authorization barriers. The system moves from a single broad default definition to distinct, granular, role-based definitions:
# Configuration change in src/DIRAC/WorkloadManagementSystem/ConfigTemplate.cfg
PilotManager
{
Port = 9171
Authorization
{
- Default = authenticated
+ Default = Operator
+ setPilotStatus = Operator
+ setPilotStatus += Pilot
+ setPilotStatus += GenericPilot
}
}Exploitation of the vulnerability involves a two-phase attack sequence. First, the attacker connects to the DIRAC network port (typically port 9171 or the integrated Tornado HTTPS gate) using a basic authenticated TLS grid certificate. Because the default configuration designates Default = authenticated for the PilotManager service, the request is permitted by the interface logic, and the user is granted access to the exposed API methods.
Second, the attacker triggers the SQL injection flaw by executing the RPC API routine setPilotStatus. By inputting a crafted string payload into arguments such as statusReason, the attacker alters the structured execution flow of the SQL driver.
For example, setting the statusReason argument to "Injected', BenchMark=SLEEP(10) WHERE PilotJobReference='target-job" results in the generation of a dual-conditional SQL instruction. The database engine executes the command and triggers the SLEEP(10) instruction, confirming the vulnerability through a blind, time-based side channel.
The security implications of this chained vulnerability are substantial. An authenticated attacker can disrupt grid operations by manipulating active pilot jobs. By modifying job entries in the PilotAgents database, attackers can change job tracking workflows, terminate scheduled workload processes, or misroute remote computing operations.
Furthermore, because the SQL injection is executed within the context of the underlying database instance, attackers can run arbitrary SQL commands to read or modify other database tables. This allows for the extraction of cryptographic hashes, administrative details, and grid system credentials.
While this vulnerability does not allow direct shell commands on the server host, the ability to control database tables can lead to privilege escalation within the DIRAC application framework. The lack of proper input validation and authorization checks results in a CVSS v3.1 score of 8.5.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
DIRAC DIRACGrid | >= 6, < 8.0.79 | 8.0.79 |
DIRAC DIRACGrid | >= 8.1.0a1, < 9.0.22 | 9.0.22 |
DIRAC DIRACGrid | >= 9.1.0, < 9.1.10 | 9.1.10 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-89 (SQL Injection), CWE-284 (Improper Access Control) |
| Attack Vector | Network |
| CVSS v3.1 Score | 8.5 (High) |
| Exploit Status | none |
| KEV Status | Not Listed |
The software constructs an SQL command using input from an upstream component, but fails to neutralize or incorrectly neutralizes elements that can modify the SQL command.
CVE-2026-12243 is a path traversal vulnerability in the Natural Language Toolkit (NLTK) version 3.9.4. The flaw exists because the input validation routine fails to account for percent-encoded directory traversal sequences like '..%2f' before passing them to urllib.request.url2pathname(), which decodes them into active traversal sequences.
CVE-2026-73654 is a high-severity prototype pollution vulnerability in Trigger.dev. The flaw occurs during the handling of run-metadata updates through the PUT /api/v1/runs/:runId/metadata endpoint. Because user-supplied keys are parsed directly by the @jsonhero/path library without sanitization, an authenticated attacker with low privileges can pollute the global Object.prototype. This causes database queries via Prisma ORM to fail validation and induces unhandled exceptions in the Prometheus metrics client, resulting in a process-wide denial of service.
CVE-2026-73559 is an uncontrolled resource consumption vulnerability in the vLLM engine, specifically within the /v1/completions API endpoint, allowing authenticated attackers to cause application-level denial of service via unbounded prompt arrays.
A critical security bypass vulnerability in Argo Workflows allows authenticated attackers with workflow submission privileges to bypass 'Strict' or 'Secure' template referencing restrictions. By injecting unvalidated fields into the nested ArtifactGC configuration, attackers can execute arbitrary pod patches, leading to host namespace escape and cluster-wide privilege escalation.
A Server-Side Request Forgery (SSRF) / Confused Deputy vulnerability has been identified in Pydantic AI UI Adapters (such as VercelAIAdapter). Under certain conditions, a malicious client can supply manipulated message history with provider metadata that forces the server to resolve files within privileged cloud environments (AWS S3, Google Cloud Storage) or model providers. This occurs because the adapters deserialize client-provided metadata structures directly into UploadedFile instances without validation, which are subsequently fetched using high-privilege server credentials.
A path traversal vulnerability in the optional dashboard server of atomic-agents-stack before version 1.1.0 allows unauthenticated remote attackers to read arbitrary files from the host filesystem.