diff --git a/.claude/commands/security-review.md b/.claude/commands/security-review.md index 93651ea..4c82def 100644 --- a/.claude/commands/security-review.md +++ b/.claude/commands/security-review.md @@ -81,6 +81,15 @@ SECURITY CATEGORIES TO EXAMINE: - API endpoint data leakage - Debug information exposure +**Dependency & Supply Chain Security:** +- Known vulnerable dependencies (CVEs in pinned versions in manifest files) +- Unpinned or loosely pinned dependency versions (e.g. `*`, `latest`, `>=` without upper bound) +- Dependencies from untrusted or non-standard registries +- Typosquatting risks in package names (e.g. misspelled popular packages) +- Dependency confusion (private vs public namespace conflicts) +- Malicious post-install scripts in dependency manifests +- Lock file integrity issues (missing, inconsistent, or uncommitted lock files) + Additional notes: - Even if something is only exploitable from the local network, it can still be a HIGH severity issue diff --git a/claudecode/prompts.py b/claudecode/prompts.py index ee44e0a..aeee1f6 100644 --- a/claudecode/prompts.py +++ b/claudecode/prompts.py @@ -99,6 +99,15 @@ def get_security_audit_prompt(pr_data, pr_diff=None, include_diff=True, custom_s - PII handling violations - API endpoint data leakage - Debug information exposure + +**Dependency & Supply Chain Security:** +- Known vulnerable dependencies (CVEs in pinned versions in manifest files) +- Unpinned or loosely pinned dependency versions (e.g. `*`, `latest`, `>=` without upper bound) +- Dependencies from untrusted or non-standard registries +- Typosquatting risks in package names (e.g. misspelled popular packages) +- Dependency confusion (private vs public namespace conflicts) +- Malicious post-install scripts in dependency manifests +- Lock file integrity issues (missing, inconsistent, or uncommitted lock files) {custom_categories_section} Additional notes: - Even if something is only exploitable from the local network, it can still be a HIGH severity issue diff --git a/claudecode/test_prompts.py b/claudecode/test_prompts.py index 4cd3a6a..8d8a591 100644 --- a/claudecode/test_prompts.py +++ b/claudecode/test_prompts.py @@ -322,4 +322,53 @@ def test_get_security_audit_prompt_unicode(self): assert "🎉" in prompt # Title emoji assert "émoji-user" in prompt assert "émojis.py" in prompt - assert "🚨" in prompt # From diff \ No newline at end of file + assert "🚨" in prompt # From diff + def test_get_security_audit_prompt_contains_supply_chain_category(self): + """Test that the prompt includes the Dependency & Supply Chain Security category.""" + pr_data = { + "number": 1, + "title": "Update dependencies", + "body": "Bumping versions", + "user": "bot", + "changed_files": 1, + "additions": 1, + "deletions": 1, + "head": {"repo": {"full_name": "owner/repo"}}, + "files": [{"filename": "package.json", "status": "modified", + "additions": 1, "deletions": 1}] + } + + prompt = get_security_audit_prompt(pr_data) + + assert "Dependency & Supply Chain Security" in prompt + assert "typosquatting" in prompt.lower() + assert "dependency confusion" in prompt.lower() + assert "lock file" in prompt.lower() + assert "post-install scripts" in prompt.lower() + + def test_get_security_audit_prompt_supply_chain_with_custom_instructions(self): + """Test that custom_scan_instructions still injects after the supply chain category.""" + pr_data = { + "number": 2, + "title": "Test", + "body": "", + "user": "tester", + "changed_files": 1, + "additions": 1, + "deletions": 1, + "head": {"repo": {"full_name": "owner/repo"}}, + "files": [{"filename": "setup.py", "status": "modified", + "additions": 1, "deletions": 1}] + } + + custom = "Also check for GPL license violations." + prompt = get_security_audit_prompt(pr_data, custom_scan_instructions=custom) + + supply_chain_pos = prompt.find("Dependency & Supply Chain Security") + custom_pos = prompt.find(custom) + + assert supply_chain_pos != -1, "Supply chain section missing" + assert custom_pos != -1, "Custom instructions missing" + assert supply_chain_pos < custom_pos, ( + "Custom instructions appeared before the supply chain section" + )