Skip to content

PE3 .env pattern matches Python attribute access (self.env, args.env), not just credential files #407

Closed

Description

@benedictkwok

Affected rule: PE3 "Credential Access" Affected file: src/skillspector/nodes/analyzers/static_patterns_privilege_escalation.py, line 89

Summary
python
(r".env(?:.local|.production|.development)?(?:\s|$|['"])", 0.6)

This pattern has no lookbehind on what precedes .env, so it matches any identifier.env attribute access, not just dotenv file references. Confirmed on the official anthropics/skills repo, mcp-builder/scripts/connections.py:80:

python
self.command = command
self.args = args or []
self.env = env # ← matched substring: ".env " (trailing space before "=")

and mcp-builder/scripts/evaluation.py:344:

python
env_vars = parse_env_vars(args.env) if args.env else None # ← matched: ".env " (trailing space before ")")

Neither line touches a credential file. self.env = env is storing a constructor parameter; args.env is reading an argparse --env flag. Confirmed via mcp-builder's own scan report: both fired as PE3/HIGH, survived to the final filtered output (llm-unconfirmed-tagged, preserved under the severity floor for HIGH findings), and were part of what drove that skill's risk score to 91/CRITICAL.

I checked whether _is_env_file_reference_in_docs in static_runner.py covers this — it doesn't; that filter requires file_type in ("markdown", "text") and never runs on .py files at all, so these two findings had no existing exemption path.

Proposed fix

Add a negative lookbehind so the pattern only fires when .env is not immediately preceded by a word character (i.e. not part of an identifier via attribute access):

python
(r"(?<!\w).env(?:.local|.production|.development)?(?:\s|$|['"])", 0.6)
Verifying this doesn't weaken real detection

Genuine dotenv-file references keep matching, since they're not preceded by an identifier character:

open(".env") → " immediately before .env — still matches.
load_dotenv('.env') → ' before .env — still matches.
bare .env in prose ("reads secrets from .env") → whitespace before .env — still matches.

Only the attribute-access false-positive shape (word.env) stops matching.

Reported by

Benedict Kwok, ZTAI Security Advisors LLC ([email protected]) — found while independently evaluating SkillSpector against several official anthropics/skills skills.Summary

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions