NVIDIA / NVIDIA/SkillSpector

E2 shell arm matches one `env | grep` spelling: a second grep flag, quotes, or egrep all evade "Env Variable Harvesting"

Open Beginner friendly
#482 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
17.9k
Forks
1.5k
Avg merge
5d 10h
Merged PRs (30d)
66

Description

Summary

Rule E2 (Data Exfiltration / Env Variable Harvesting) has a shell arm for env | grep, but it accepts exactly one flag (-i) followed by a bare keyword. A second flag, combined flags, a quoted pattern, or egrep all evade it. The README defines E2 as "enumerating, copying, or searching environment data to collect secrets"; the missed spellings are the searching case.

#329 and #441 cover the Python os.environ path. This is the shell path and is independent of both.

Environment

  • SkillSpector v2.11.0 (commit 7805bb9), installed with uv tool install git+https://github.com/NVIDIA/skillspector.git
  • skillspector scan <dir> --no-llm --format json (static-only, deterministic)
  • macOS 15 (Darwin 25.6.0), Python 3.13 runtime

Reproduction

One SKILL.md with one fenced bash block. Only the marked line varies between runs.

spelling E2 fires
env | grep secret yes, 0.8
env | grep -i -E 'token|key|secret' > /tmp/ctx.txt no
env | grep -iE "aws_|secret" no
env | grep --ignore-case token no
env | egrep -e password -e token no
printenv | grep -i secret yes, but only because the line contains the substring env | grep -i secret

The second row is the shape a harvester would write: case-insensitive, alternation over several names, redirected to a file for a later upload. In a skill that goes on to POST that file, the scan reports E1, E3, PE3 and SC2 on the surrounding lines and nothing on the harvest line itself.

Cause

src/skillspector/nodes/analyzers/static_patterns_data_exfiltration.py:73:

(r"env\s*\|\s*grep\s+(?:-i\s+)?(?:key|secret|token|password)", 0.8),

(?:-i\s+)? consumes one -i and nothing else, and the keyword has to follow as a bare word, so a quote or a second flag ends the match. Nothing in tests/unit/test_patterns.py pins a shell spelling; the E2 cases there (lines 150-255) are all Python.

Expected behavior

The shell arm should key on the behavior (the environment piped through a filter for secret-looking names) rather than on one flag layout: env or printenv as the source, grep, egrep or fgrep as the filter, any flags, optional quoting, and the keyword anywhere in the pattern argument. env | grep PATH and env | grep -v SECRET should still pass.

I have a fix with tests and a fixture ready to open against this issue.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at src/skillspector/nodes/analyzers/static_patterns_data_exfiltration.py:73, then review the E2 cases in tests/unit/test_patterns.py around lines 150-255. Add coverage for the shell spellings and exclusions described in the reproduction, using the ready fixture if needed. Done means the supported env/printenv filtering forms trigger E2 while PATH and negative-filter examples do not.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, shell
Domain
security, testing-qa
Issue type
Bug
Difficulty
2/5
Estimated time
Half a day
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.