Back to skill

Security audit

Regexpal

Security checks for vulnerabilities and agentic risk

Overview

RegexPal is a straightforward local regex testing utility with disclosed file-reading commands, but users should avoid running it on untrusted files or hostile regex patterns without caution.

Install only if you want a local terminal regex helper. Use it on files you intentionally choose, avoid sensitive files unless you are comfortable displaying matching content in the terminal, and be careful with regexes or input files from untrusted sources because they can hang the process or manipulate terminal output.

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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/script.sh:22
Finding

Terminal Escape-Sequence Injection Through Untrusted Output

Content
View full analysis

Vulnerability Details

File Location: scripts/script.sh:22-25, scripts/script.sh:72-73, scripts/script.sh:126-127, scripts/script.sh:155-166, scripts/script.sh:189-191, scripts/script.sh:225-226, scripts/script.sh:255-258, and scripts/script.sh:274
Vulnerability Type: Unsanitized terminal output and terminal control-sequence injection
Risk Level: Medium

Vulnerable Code

bash
info()    { echo -e "${BLUE}ℹ${NC} $*"; }
success() { echo -e "${GREEN}✔${NC} $*"; }
warn()    { echo -e "${YELLOW}⚠${NC} $*"; }
error()   { echo -e "${RED}✖${NC} $*" >&2; }

User-controlled pattern and text values are passed to the affected output helper:

bash
info "Testing pattern: ${CYAN}${pattern}${NC}"
info "Against text:    ${CYAN}${text}${NC}"

File content and regex matches are also printed without escaping terminal control characters:

python
if matches:
    matching_lines += 1
    total_matches += len(matches)
    # Highlight matches in the line
    highlighted = line
    offset = 0
    parts = []
    last_end = 0
    for m in matches:
        parts.append(line[last_end:m.start()])
        parts.append(f'\033[1;31m{m.group()}\033[0m')
        last_end = m.end()
    parts.append(line[last_end:])
    highlighted = ''.join(parts)
    print(f'  {line_num:5}: {highlighted}')

Technical Analysis

The skill writes user-controlled patterns, text, filenames, matched file content, replacement strings, and extracted groups directly to a terminal. It does not escape control characters before output. The shell helper functions compound the problem by using echo -e, which interprets backslash escape sequences contained in their arguments.

Consequently, an input containing ANSI CSI sequences or OSC sequences may be interpreted by the operator's terminal rather than displayed as inert text. Depending on terminal capabilities and configuration, an attacker m ...[truncated 1405 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace echo -e with printf using a fixed format string:

    bash
    info() {
        printf '%bℹ%b %s\n' "$BLUE" "$NC" "$*"
    }
    

    Keep trusted color constants separate from the untrusted %s value.

  2. Sanitize all user-controlled values and file content before displaying them. Convert control bytes to visible escaped representations such as \x1b, \r, and \x07.

  3. In Python, introduce a shared terminal-sanitization function and apply it to filenames, patterns, matching lines, matches, and extracted groups before printing:

    python
    def terminal_safe(value):
        return ''.join(
            ch if ch == '\t' or ord(ch) >= 0x20 and ord(ch) != 0x7f
            else f'\\x{ord(ch):02x}'
            for ch in str(value)
        )
    
  4. Emit color sequences only when stdout is connected to an interactive terminal, and support a --no-color option or the NO_COLOR environment variable.

  5. Add regression tests containing ESC, BEL, carriage return, OSC hyperlink, and OSC clipboard sequences to verify that untrusted bytes are rendered visibly rather than interpreted.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/script.sh:86
Finding

Denial of Service Through Unbounded Regular-Expression Execution

Content
View full analysis

Vulnerability Details

File Location: scripts/script.sh:86-96, scripts/script.sh:140-151, scripts/script.sh:202-210, scripts/script.sh:239-252, and scripts/script.sh:282
Vulnerability Type: Regular-expression denial of service through catastrophic backtracking
Risk Level: Medium

Vulnerable Code

The test command compiles an arbitrary pattern and performs several unrestricted matching operations:

python
try:
    compiled = re.compile(pattern)
except re.error as e:
    print(f'✖ Invalid regex: {e}', file=sys.stderr)
    sys.exit(1)

# Full match
fm = compiled.fullmatch(text)
# Search (partial)
sm = compiled.search(text)
# Find all
fa = compiled.findall(text)

File-matching commands similarly run arbitrary expressions over potentially large input without execution limits:

python
with open(filepath, 'r', errors='replace') as f:
    for line_num, line in enumerate(f, 1):
        line = line.rstrip('\n')
        matches = list(compiled.finditer(line))

Replacement processing is also unrestricted:

python
total_replacements = 0
with open(filepath, 'r', errors='replace') as f:
    for line in f:
        new_line, count = compiled.subn(replacement, line)
        total_replacements += count
        sys.stdout.write(new_line)

Technical Analysis

Python's standard re engine is a backtracking regular-expression implementation. Certain attacker-controlled patterns, particularly ambiguous nested quantifiers, can require exponential processing time when evaluated against a carefully selected nonmatching string.

The skill accepts arbitrary patterns and arbitrary text or files, but does not enforce a timeout, subprocess resource limits, maximum line length, maximum file size, or pattern-complexity policy. The test command may also evaluate the same hostile pattern through fullmatch, search, and findall, increasing the potential workload. ...[truncated 1365 chars]

Remediation
View remediation

Remediation Suggestions

  1. Execute regex operations in a dedicated subprocess with a strict wall-clock timeout. Terminate the subprocess and return a clear error if the deadline is exceeded.

  2. Apply operating-system resource limits to the worker process, including CPU time and address-space limits where supported.

  3. Enforce maximum pattern length, input text length, file size, and line length before regex processing. Stream files while maintaining bounded memory use.

  4. Avoid materializing every match with list(finditer(...)). Iterate incrementally and enforce a configurable maximum number of matches.

  5. Consider using a linear-time regex engine for untrusted expressions where feature compatibility permits. Clearly reject unsupported backtracking-dependent constructs.

  6. Pattern linting may reject obvious nested or ambiguous quantifiers as defense in depth, but it should not be treated as a replacement for a timeout because reliably determining regex complexity is difficult.

  7. Add denial-of-service regression tests covering catastrophic-backtracking patterns, long lines, zero-length matches, and extremely high match counts.

Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (1)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding

The skill advertises commands that read user-specified files (match, replace, extract) but does not declare any explicit tool scope such as permissions or allowed-tools. That creates an authorization gap: an agent may permit file-reading behavior without clear user-visible constraints, increasing the chance of unintended access to local files if invoked on sensitive paths.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.