Skip to content

Commit ef6fdf4

Browse files
committed
- [x] ### 3. shell_exec/exec/system/passthru (any usage)
1 parent 16aeacd commit ef6fdf4

11 files changed

Lines changed: 167 additions & 39 deletions

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [1.3.8] - 2026-01-14
11+
12+
### Added
13+
- **Tier 1 Security Rules (PHP)** - Shell command execution detection
14+
- New rule: `php-shell-exec-functions` (**CRITICAL**, security)
15+
- Detects usage of `shell_exec()`, `exec()`, `system()`, and `passthru()` in PHP code
16+
- Pattern JSON: `dist/patterns/php-shell-exec-functions.json`
17+
- Scanner integration: new `run_check` block in `dist/bin/check-performance.sh`
18+
- New fixture: `dist/tests/fixtures/shell-exec-antipatterns.php` with shell command execution anti-patterns
19+
20+
### Changed
21+
- **Severity Configuration** - Updated `dist/config/severity-levels.json`
22+
- Incremented `total_checks` from 35 to 36
23+
- Added severity entry for `php-shell-exec-functions` (CRITICAL, category: security)
24+
1025
## [1.3.7] - 2026-01-14
1126

1227
### Added

PROJECT/1-INBOX/BACKLOG.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
# Backlog - Issues to Investigate
22

3+
### Checklist - 2025-01-14
4+
- [ ] Continue with Tier 1 rules
5+
- [ ] Fix tty output for HTML reports (The commit added great new features (init, update, tab completion) with proper TTY detection. However, the original HTML generation code (lines 5848-5863) still writes to /dev/tty unconditionally)
6+
- [ ] Make a comment in main script to make rules in external files going forward
7+
- [ ] Breakout check-performance.sh into multiple files and external rule files
8+
39
## Mini Project Plan: Enhanced Context Detection (False Positive Reduction)
410

511
Goal: Improve context/scope accuracy (especially “same function”) to reduce false positives and severity inflation, while keeping the scanner fast and zero-dependency.
612

713
Notes:
814
- This is **not a new standalone script**. `dist/bin/check-performance.sh` already has limited “same function” scoping (used in caching mitigation); this mini-project extends/centralizes that approach.
915

10-
### Checklist
11-
- [ ] Fix tty output for HTML reports (The commit added great new features (init, update, tab completion) with proper TTY detection. However, the original HTML generation code (lines 5848-5863) still writes to /dev/tty unconditionally)
12-
- [ ] Make a comment in main script to make rules in external files going forward
13-
- [ ] Breakout check-performance.sh into multiple files and external rule files
14-
- [ ] Continue with Tier 1 rules
15-
1616
- [ ] Audit where we rely on context windows today (±N lines) and where “same function” scoping would reduce false positives.
1717
- [x] Add/centralize a helper to compute function/method scope boundaries (support `function foo()`, `public/protected/private static function foo()`, and common formatting).
1818
- [x] Use the helper in mitigation detection (so caching/ids-only/admin-only/parent-scoped all share the same scoping rules).

PROJECT/1-INBOX/RULES-2026-01-14.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ include_once($user_controlled_path);
5252

5353
---
5454

55-
- [ ] ### 3. `shell_exec`/`exec`/`system`/`passthru` (any usage)
55+
- [x] ### 3. `shell_exec`/`exec`/`system`/`passthru` (any usage)
5656

5757
```php
5858
// CRITICAL - Command execution
@@ -66,7 +66,11 @@ passthru($user_input);
6666

6767
**False positive rate:** Medium (~20%). Legitimate uses exist but are rare in WordPress themes/plugins.
6868

69-
**Current coverage:** Node.js only (`njs-002-command-injection`). PHP not covered.
69+
**Current coverage:**
70+
- Node.js: `njs-002-command-injection` (server-side command injection checks)
71+
- PHP: `php-shell-exec-functions` (new Tier 1 rule, implemented in `check-performance.sh` v1.3.8)
72+
73+
**Status:** Implemented in scanner (PHP + Node.js coverage) as of v1.3.8.
7074

7175
---
7276

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
# Backlog - Future Work
1+
# Backlog - DEPRECATED -
2+
3+
**Status:** DEPRECATED
24

35
This backlog intentionally contains **only pending work**. Completed items belong in `CHANGELOG.md` and `PROJECT/3-COMPLETED/`.
46

@@ -18,6 +20,12 @@ This backlog intentionally contains **only pending work**. Completed items belon
1820
- [ ] Plan and execute a breakout of `dist/bin/check-performance.sh` into smaller, focused modules (e.g., core CLI, scan orchestration, pattern runner, reporting), while keeping the current behavior intact.
1921
- [ ] Gradually migrate existing inline checks to external rule files and continue implementing the remaining **Tier 1 rules** using the JSON + helper pattern (pattern file, fixture, integration, severity wiring, CHANGELOG).
2022

23+
### Alternate - Checklist
24+
- [ ] Continue with Tier 1 rules
25+
- [ ] Fix tty output for HTML reports (The commit added great new features (init, update, tab completion) with proper TTY detection. However, the original HTML generation code (lines 5848-5863) still writes to /dev/tty unconditionally)
26+
- [ ] Make a comment in main script to make rules in external files going forward
27+
- [ ] Breakout check-performance.sh into multiple files and external rule files
28+
2129
### Calibration Feature - Pattern Sensitivity Adjustment (NEW)
2230
**Priority:** MEDIUM
2331
**Effort:** 3–5 days

dist/PATTERN-LIBRARY.json

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
{
22
"version": "1.0.0",
3-
"generated": "2026-01-14T21:03:38Z",
3+
"generated": "2026-01-14T22:17:45Z",
44
"summary": {
5-
"total_patterns": 31,
5+
"total_patterns": 32,
66
"enabled": 31,
7-
"disabled": 0,
7+
"disabled": 1,
88
"by_severity": {
9-
"CRITICAL": 11,
9+
"CRITICAL": 12,
1010
"HIGH": 10,
1111
"MEDIUM": 7,
1212
"LOW": 3
1313
},
1414
"by_category": {
15-
"performance": 9,"duplication": 5,"reliability": 5,"security": 10
15+
"performance": 9,"duplication": 5,"reliability": 5,"security": 11
1616
},
1717
"by_pattern_type": {
18-
"php": 20,
18+
"php": 21,
1919
"headless": 6,
2020
"nodejs": 4,
2121
"javascript": 1
2222
},
2323
"mitigation_detection_enabled": 6,
2424
"heuristic_patterns": 10,
25-
"definitive_patterns": 21
25+
"definitive_patterns": 22
2626
},
2727
"patterns": [
2828
{
@@ -305,6 +305,20 @@
305305
"heuristic": false,
306306
"file": "php-eval-injection.json"
307307
},
308+
{
309+
"id": "php-shell-exec-functions",
310+
"version": "",
311+
"enabled": ,
312+
"category": "security",
313+
"severity": "CRITICAL",
314+
"title": "Shell command execution functions in PHP (shell_exec/exec/system/passthru)",
315+
"description": "Usage of shell_exec(), exec(), system(), or passthru() in PHP code. These functions execute system commands and are almost never safe in WordPress plugins/themes.",
316+
"detection_type": "direct",
317+
"pattern_type": "php",
318+
"mitigation_detection": false,
319+
"heuristic": false,
320+
"file": "php-shell-exec-functions.json"
321+
},
308322
{
309323
"id": "superglobal-with-nonce-context",
310324
"version": "1.0.0",

dist/PATTERN-LIBRARY.md

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,43 @@
11
# Pattern Library Registry
22

33
**Auto-generated by Pattern Library Manager**
4-
**Last Updated:** 2026-01-14 21:03:38 UTC
4+
**Last Updated:** 2026-01-14 22:17:45 UTC
55

66
---
77

88
## 📊 Summary Statistics
99

1010
### Total Patterns
11-
- **Total:** 31 patterns
11+
- **Total:** 32 patterns
1212
- **Enabled:** 31 patterns
13-
- **Disabled:** 0 patterns
13+
- **Disabled:** 1 patterns
1414

1515
### By Severity
1616
| Severity | Count | Percentage |
1717
|----------|-------|------------|
18-
| CRITICAL | 11 | 35.5% |
19-
| HIGH | 10 | 32.3% |
20-
| MEDIUM | 7 | 22.6% |
21-
| LOW | 3 | 9.7% |
18+
| CRITICAL | 12 | 37.5% |
19+
| HIGH | 10 | 31.2% |
20+
| MEDIUM | 7 | 21.9% |
21+
| LOW | 3 | 9.4% |
2222

2323
### By Type
2424
| Type | Count | Percentage |
2525
|------|-------|------------|
26-
| Definitive | 21 | 67.7% |
27-
| Heuristic | 10 | 32.3% |
26+
| Definitive | 22 | 68.8% |
27+
| Heuristic | 10 | 31.2% |
2828

2929
### Advanced Features
30-
- **Mitigation Detection Enabled:** 6 patterns (19.4%)
30+
- **Mitigation Detection Enabled:** 6 patterns (18.8%)
3131
- **False Positive Reduction:** 60-70% on mitigated patterns
3232

3333
### By Category
3434
- **performance:** 9 patterns
3535
- **duplication:** 5 patterns
3636
- **reliability:** 5 patterns
37-
- **security:** 10 patterns
37+
- **security:** 11 patterns
3838

3939
### By Pattern Type
40-
- **PHP/WordPress:** 20 patterns
40+
- **PHP/WordPress:** 21 patterns
4141
- **Headless WordPress:** 6 patterns
4242
- **Node.js/Server-Side JS:** 4 patterns
4343
- **Client-Side JavaScript:** 1 patterns
@@ -54,6 +54,7 @@
5454
- **njs-001-eval-injection** - Dangerous eval() or code execution
5555
- **php-dynamic-include** - Dynamic PHP include/require with variables
5656
- **php-eval-injection** - Dangerous eval() usage in PHP
57+
- **php-shell-exec-functions** - Shell command execution functions in PHP (shell_exec/exec/system/passthru)
5758
- **unbounded-wc-get-orders** 🛡️ - Unbounded wc_get_orders()
5859
- **unbounded-wc-get-products** - Unbounded wc_get_products()
5960
- **wp-query-unbounded** 🛡️ - Unbounded WP_Query/get_posts
@@ -99,26 +100,26 @@
99100

100101
### Key Selling Points
101102

102-
1. **Comprehensive Coverage:** 31 detection patterns across 4 categories
103-
2. **Multi-Platform Support:** PHP/WordPress (20), Headless WordPress (6), Node.js (4), JavaScript (1)
103+
1. **Comprehensive Coverage:** 32 detection patterns across 4 categories
104+
2. **Multi-Platform Support:** PHP/WordPress (21), Headless WordPress (6), Node.js (4), JavaScript (1)
104105
3. **Enterprise-Grade Accuracy:** 6 patterns with AI-powered mitigation detection (60-70% false positive reduction)
105-
4. **Severity-Based Prioritization:** 11 CRITICAL + 10 HIGH severity patterns catch the most dangerous issues
106-
5. **Intelligent Analysis:** 21 definitive patterns + 10 heuristic patterns for comprehensive code review
106+
4. **Severity-Based Prioritization:** 12 CRITICAL + 10 HIGH severity patterns catch the most dangerous issues
107+
5. **Intelligent Analysis:** 22 definitive patterns + 10 heuristic patterns for comprehensive code review
107108

108109
### One-Liner Stats
109110

110-
> **31 detection patterns** | **6 with AI mitigation** | **60-70% fewer false positives** | **Multi-platform: PHP, Headless, Node.js, JS**
111+
> **32 detection patterns** | **6 with AI mitigation** | **60-70% fewer false positives** | **Multi-platform: PHP, Headless, Node.js, JS**
111112
112113
### Feature Highlights
113114

114-
-**11 CRITICAL** OOM and security patterns
115+
-**12 CRITICAL** OOM and security patterns
115116
-**10 HIGH** performance and security patterns
116117
-**6 patterns** with context-aware severity adjustment
117118
-**10 heuristic** patterns for code quality insights
118119
-**Multi-platform:** WordPress, Headless, Node.js, JavaScript
119120

120121
---
121122

122-
**Generated:** 2026-01-14 21:03:38 UTC
123+
**Generated:** 2026-01-14 22:17:45 UTC
123124
**Version:** 1.0.0
124125
**Tool:** Pattern Library Manager

dist/bin/check-performance.sh

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ source "$REPO_ROOT/lib/pattern-loader.sh"
6161
# This is the ONLY place the version number should be defined.
6262
# All other references (logs, JSON, banners) use this variable.
6363
# Update this ONE line when bumping versions - never hardcode elsewhere.
64-
SCRIPT_VERSION="1.3.7"
64+
SCRIPT_VERSION="1.3.8"
6565

6666
# Get the start/end line range for the enclosing function/method.
6767
#
@@ -2775,6 +2775,13 @@ section_start "Critical Checks"
27752775
text_echo "${RED}━━━ CRITICAL CHECKS (will fail build) ━━━${NC}"
27762776
text_echo ""
27772777

2778+
# NOTE (Rule Definition Strategy, v1.3.8):
2779+
# - New rules SHOULD be defined in external JSON pattern files under dist/patterns
2780+
# and registered with the Pattern Library Manager.
2781+
# - Inline run_check(...) blocks below are legacy and glue code; when adding
2782+
# new rules, prefer JSON + helper glue (see dist/patterns/php-eval-injection.json
2783+
# and dist/patterns/php-dynamic-include.json for examples).
2784+
27782785
# Debug code in production (JS + PHP)
27792786
OVERRIDE_GREP_INCLUDE="--include=*.php --include=*.js --include=*.jsx --include=*.ts --include=*.tsx"
27802787
run_check "ERROR" "$(get_severity "spo-001-debug-code" "CRITICAL")" "Debug code in production" "spo-001-debug-code" \
@@ -3117,6 +3124,13 @@ run_check "ERROR" "$(get_severity "php-dynamic-include" "CRITICAL")" "Dynamic PH
31173124
"-E include(_once)?[[:space:]]+[^;]*\\$" \
31183125
"-E require(_once)?[[:space:]]+[^;]*\\$"
31193126

3127+
# Shell command execution functions (shell_exec/exec/system/passthru)
3128+
run_check "ERROR" "$(get_severity "php-shell-exec-functions" "CRITICAL")" "Shell command execution functions in PHP" "php-shell-exec-functions" \
3129+
"-E shell_exec[[:space:]]*\\(" \
3130+
"-E exec[[:space:]]*\\(" \
3131+
"-E system[[:space:]]*\\(" \
3132+
"-E passthru[[:space:]]*\\("
3133+
31203134
# Insecure data deserialization
31213135
run_check "ERROR" "$(get_severity "spo-003-insecure-deserialization" "CRITICAL")" "Insecure data deserialization" "spo-003-insecure-deserialization" \
31223136
"-E unserialize[[:space:]]*\\(\\$_" \

dist/config/severity-levels.json

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"_metadata": {
3-
"version": "1.3.7",
3+
"version": "1.3.8",
44
"description": "WP Code Check - Severity Level Customization",
55
"last_updated": "2026-01-14",
6-
"total_checks": 35,
6+
"total_checks": 36,
77
"instructions": "Copy this file and edit 'level' fields to customize severity. Leave 'factory_default' unchanged for reference. Use --severity-config <path> to apply customizations. Any field starting with underscore (_comment, _note, _reason, _ticket, etc.) is ignored by the parser and can be used for documentation.",
88
"_comment": "Example: This comment field is ignored during parsing. Use it to document your configuration decisions."
99
},
@@ -57,6 +57,14 @@
5757
"category": "security",
5858
"description": "include/require statements where the path expression contains variables; dynamic paths can lead directly to local/remote file inclusion and remote code execution"
5959
},
60+
"php-shell-exec-functions": {
61+
"id": "php-shell-exec-functions",
62+
"name": "Shell command execution functions in PHP",
63+
"level": "CRITICAL",
64+
"factory_default": "CRITICAL",
65+
"category": "security",
66+
"description": "Usage of shell_exec(), exec(), system(), or passthru() in PHP code. These functions execute system commands and are almost never safe in WordPress plugins/themes."
67+
},
6068
"unbounded-posts-per-page": {
6169
"id": "unbounded-posts-per-page",
6270
"name": "Unbounded posts_per_page",
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"id": "php-shell-exec-functions",
3+
"detection_type": "direct",
4+
"category": "security",
5+
"severity": "CRITICAL",
6+
"title": "Shell command execution functions in PHP (shell_exec/exec/system/passthru)",
7+
"description": "Usage of shell_exec(), exec(), system(), or passthru() in PHP code. These functions execute system commands and are almost never safe in WordPress plugins/themes.",
8+
"added_in_scanner_version": "1.3.8",
9+
"languages": ["php"],
10+
"detection": {
11+
"type": "grep",
12+
"file_patterns": ["*.php"],
13+
"patterns": [
14+
{
15+
"id": "shell_exec-call",
16+
"pattern": "shell_exec[[:space:]]*\\("
17+
},
18+
{
19+
"id": "exec-call",
20+
"pattern": "exec[[:space:]]*\\("
21+
},
22+
{
23+
"id": "system-call",
24+
"pattern": "system[[:space:]]*\\("
25+
},
26+
{
27+
"id": "passthru-call",
28+
"pattern": "passthru[[:space:]]*\\("
29+
}
30+
]
31+
},
32+
"rationale": "Shell command execution APIs are high-risk in a web context and are strong indicators of malware, backdoors, or fragile integrations. Legitimate uses in WordPress themes/plugins are rare and should undergo manual review.",
33+
"remediation": "Remove shell_exec/exec/system/passthru usage where possible. Prefer WordPress APIs, PHP built-ins, or background jobs that do not execute arbitrary shell commands. If absolutely required, tightly constrain inputs (whitelists), escape arguments safely, and restrict execution to trusted administrators only.",
34+
"references": [
35+
"https://www.php.net/manual/en/function.exec.php",
36+
"https://owasp.org/www-community/attacks/Command_Injection"
37+
],
38+
"test_fixtures": [
39+
"dist/tests/fixtures/shell-exec-antipatterns.php"
40+
]
41+
}
42+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
// Intentional anti-patterns for shell_exec/exec/system/passthru Tier 1 rule
4+
5+
function bad_shell_exec_from_input() {
6+
$cmd = $_GET['cmd'];
7+
shell_exec($cmd);
8+
}
9+
10+
function bad_exec_for_image_convert($filename) {
11+
// Even seemingly legitimate uses should be reviewed
12+
exec("convert " . $filename);
13+
}
14+
15+
function bad_system_call() {
16+
system($_POST['command']);
17+
}
18+
19+
function bad_passthru_call($arg) {
20+
passthru($arg);
21+
}
22+

0 commit comments

Comments
 (0)