Skip to content

cron script body scanned as one shell command line: stage-budget refusal permanently blocks every ~512+ line script cron #8563

Description

@NicholasRBowers

Summary

mcp_cron._vet_script_contents scans a cron script body — Python source — by calling security.is_sensitive_bash_command on the whole file. That function's alt-traversal pass walks its input as pipeline stages of one shell command line under a fail-closed budget (_ALT_MAX_STAGES, 512). A source file's stage count is its line count, so every script past ~512 statements exhausts the walk by construction and is refused, at every fire, forever:

Error: cron script blocked by security policy: Blocked: command has more pipeline stages than this gate inspects (512), so a traversal in it cannot be ruled out

Reproduction

A ~700-line script cron of plain benign Python (a real memory-export job) is refused with the message above on every tick. Nothing in it runs a shell.

With the stage-budget refusal bypassed experimentally, two sibling fabrications surface on the same real scripts, same root cause (shell-grammar analyses reading multi-line Python as one command):

  • the find delivery analysis resolves cross-line fragments of ordinary Python into a fenced path the file never names;
  • the env-credential pipeline shapes assemble an env | grep AWS_SECRET-style verdict from os.environ code plus a detection-regex literal hundreds of lines away (| in source is regex alternation, not a pipe).

Why it matters

The denial is permanent in practice — the fire-time gate deliberately keeps the job and does not auto-pause — and it scales with script length, so it fires on exactly the well-documented, structured scripts the script cron feature encourages. This is the same class as #7912 (separator-run collapse on source bodies), one pass further in: the vet's own docstring already excludes is_denied for this reason.

Expected

Scan a source body with the detectors that are meaningful on source (full-text fences, credential paths, secret env names, exfil URLs), scan the body's string literals — the only place a shell payload can live — with the full shell gate, and do not model the raw file as a single shell command line.

Scope

  • src/kiro_crew/mcp_cron.py_vet_script_contents
  • src/kiro_crew/security.pyis_sensitive_bash_command pass structure

Related: #7912 (sibling false-positive class in pass 1b, fix in flight in #7913 — neither closes this).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: cronScheduled jobs, autonudge, schedule templatesarea: securitybugSomething is not working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions