Skip to content

[Bug] PE3 static pattern flags .env file references in documentation as privilege escalation #145

Description

@mimran-khan

Summary

Imagine a security guard who arrests anyone who says the word "explosives" — including the teacher in a chemistry class explaining safety protocols. That's what SkillSpector's PE3 rule does: it flags any mention of .env files, even when the text is clearly instructional documentation explaining how to configure the skill, not attempting to read secrets.

The PE3 "Sensitive File Access" static pattern uses a broad regex that matches any occurrence of .env, .env.local, .env.production, or .env.development in any file, including Markdown documentation and inline code examples. The _is_documentation_example filter exists but does not cover common documentation patterns like create a .env file or cp .env.example .env, leading to false positives on perfectly safe configuration instructions.

Why This Matters — Real-World Scenario

Scenario: A DevOps skill that teaches environment setup

A team creates a skill that helps developers set up their local development environment. The SKILL.md includes standard onboarding instructions:

## Setup
1. Copy the example config: `cp .env.example .env`
2. Fill in your database URL in `.env.local`
3. Never commit `.env.production` — it's in `.gitignore`

The skill itself does nothing with environment files — it just prints setup instructions. But SkillSpector flags all three lines as PE3 - Privilege Escalation (Sensitive File Access) with severity HIGH. The scan report says this benign documentation skill is "attempting to access sensitive configuration files."

A CI pipeline gating on SkillSpector results would reject this skill, forcing the author to either strip their setup documentation or add # skillspector-ignore comments everywhere, both of which reduce quality.

Reproduction

env-skill/
├── SKILL.md

SKILL.md:

---
name: env-skill
description: Helps developers set up .env files
---
# Environment Setup Skill

## Getting Started
1. Create a `.env` file in the project root
2. Copy values from `.env.example`
3. For production, use `.env.production` with vault-injected secrets

## Example
```bash
cp .env.example .env.local
echo "DATABASE_URL=postgres://..." >> .env

```bash
skillspector scan ./env-skill/ --no-llm --format json -o report.json
python -c "
import json
data = json.load(open('report.json'))
pe3 = [i for i in data['issues'] if 'PE3' in i.get('rule_id', '')]
print(f'PE3 findings: {len(pe3)}')
for f in pe3:
    print(f'  - {f[\"finding\"][:80]}')
# PE3 findings: 4+
# All from documentation text, not code execution
"

Root Cause

In src/skillspector/nodes/analyzers/static_patterns_privilege_escalation.py, the PE3 pattern regex at line 89:

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

This matches .env followed by whitespace, end-of-line, or quotes — which catches every documentation reference, code comment, and example.

The _is_documentation_example function (lines 162-192) attempts to filter false positives but has incomplete coverage:

def _is_documentation_example(context: str, match_text: str) -> bool:
    doc_indicators = [
        "example", "sample", "template", "demo",
        "# ", "## ", "### ",
        "```",
    ]
    # Does NOT check for: "create a", "copy the", "cp ", "set up",
    # "configure", "add to", "fill in", etc.

Common documentation phrases like "create a .env file", "copy .env.example", "cp .env.example .env" bypass the filter entirely because they don't contain the whitelisted keywords.

Impact

  • False positives on standard documentation: Any skill that mentions .env files in setup instructions gets flagged
  • Disproportionate to risk: Documentation text cannot access files — flagging it as "privilege escalation" is misleading
  • Forces documentation degradation: Authors must strip helpful configuration guidance to pass scans
  • Affects many skills: .env setup instructions are near-universal in developer-facing skills
  • Undermines trust in PE3 rule: Real privilege escalation findings (e.g., code that reads /etc/shadow) get lost among documentation false positives

Affected Version

SkillSpector v2.2.3

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions