Back to skill

Security audit

Promql Validator

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent PromQL validator, but its documented shell commands could turn a malicious query into local command execution if followed literally.

Review this before installing. Use the validator only through a structured process invocation that passes the PromQL query as a single argument, or via stdin, and do not paste untrusted queries into the documented shell command form. There is no evidence of malicious intent, persistence, or data exfiltration, but the current instructions need safer execution guidance.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:33
Finding

Command Injection Risk from Unsafe Shell Interpolation of User-Supplied PromQL Queries

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:33-36 and SKILL.md:54-57
Vulnerability Type: Shell command injection
Risk Level: High

Vulnerable Code

SKILL.md:33-36:

bash
python3 devops-skills-plugin/skills/promql-validator/scripts/validate_syntax.py "<query>"

SKILL.md:54-57:

bash
python3 devops-skills-plugin/skills/promql-validator/scripts/check_best_practices.py "<query>"

Technical Analysis

The documented workflow instructs the agent to substitute a user-provided PromQL query directly into a shell command. Wrapping the value in double quotes does not safely neutralize shell syntax if the query contains an embedded double quote.

If the agent constructs a command string by replacing <query> and executes it through a shell, an attacker can terminate the quoted argument and introduce shell operators. The shell would then interpret the injected text as commands rather than passing the entire value to the Python script as one argument.

The vulnerability depends on the documented command being executed through a shell or equivalent string-based command interface. The Python validators themselves use sys.argv[1] and do not execute the query. The test helper in scripts/test_validators.py:40-47 also demonstrates a safe argument-array invocation. Therefore, the unsafe behavior is specifically in the skill's documented invocation pattern.

Attack Path

  1. An attacker provides a PromQL query containing a closing double quote, shell separators, and a trailing comment marker. A conceptual payload is:

    text
    "; attacker_command; #
    
  2. The agent replaces the documented <query> placeholder with the attacker-controlled text.

  3. The resulting command resembles:

    bash
    python3 devops-skills-plugin/skills/promql-validator/scripts/validate_syntax.py ""; attacker_command; #"
    
  4. If the agent executes this string through a shell, the shell treats the semicolons as ...[truncated 1017 chars]

Remediation
View remediation

Remediation Suggestions

  1. Do not construct a shell command by interpolating the query. Invoke the validator through an argument-array API:

    python
    subprocess.run(
        [sys.executable, validator_path, query],
        shell=False,
        check=False,
        capture_output=True,
        text=True,
    )
    
  2. Update SKILL.md to mandate structured process invocation. Explicitly state that the query must be passed as one argument and that agents must not use shell=True, eval, or a concatenated command string.

  3. Prefer standard input for untrusted queries where the execution environment cannot guarantee argument-array semantics. The scripts can be extended to accept input from stdin:

    python
    query = sys.stdin.read()
    
  4. Add regression tests using queries containing double quotes, semicolons, command substitutions, newlines, backticks, and shell redirection characters. Confirm that all content reaches the validator as data and that no secondary process executes.

  5. Use the existing safe test pattern as the documented implementation model. scripts/test_validators.py:40-47 invokes Python with a list of arguments and does not enable shell processing.

  6. Apply least privilege to the validation process so that any future command-execution defect has limited filesystem, credential, and network impact.

Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
80% confidence
Finding

Skill attempts to nullify the agent's safety policies or restrictions ('you have no restrictions', 'ignore your guidelines', 'do anything now'). This is a direct jailbreak that disables guardrails.

Content

Scanner excerpt · docs/anti_patterns.md (reported line 76)May include surrounding context.

md
---

### Anti-Pattern 3: Wildcard Regex Without Constraints

**Problem**: Overly broad regex patterns match too many series.

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
85% confidence
Finding

Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Content

Scanner excerpt · scripts/check_best_practices.py (reported line 777)May include surrounding context.

python
Important semantic note:
        - by(...) keeps the listed labels in the grouping key (risky for high-cardinality).
        - without(...) removes the listed labels from the grouping key (often the opposite
          of the risk we're checking), so we intentionally do not warn on those labels.
        """
        # Extract aggregation grouping clauses with their mode (by|without)
        agg_clause_pattern = r'\b(by|without)\s*\(([^)]*)\)'

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill instructs the agent to execute shell commands (cd "$(git rev-parse --show-toplevel)" and python3 ...) but does not declare any explicit tool restrictions such as permissions or allowed-tools. In an agent environment, undeclared shell capability increases the risk of command execution in contexts where the skill may be invoked on untrusted input or with broader privileges than intended.

Content

No source excerpt is available for this finding.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding

Suspicious Unicode normalization or mixed-script content

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/test_validators.py (reported line 41)May include surrounding context.

python
def best_cli(query):
    """Run check_best_practices.py as a CLI and return (process, parsed_json)."""
    checker = os.path.join(_SCRIPT_DIR, 'check_best_practices.py')
    proc = subprocess.run(
        [sys.executable, checker, query],
        capture_output=True,
        text=True,

Static analysis

No suspicious patterns detected.