torusguard 1.3.2 → 1.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.torusguard/runs/report-latest.html +3 -3
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-db-004-115-9a059e/metadata.json +15 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-db-004-115-9a059e/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-db-004-115-9a059e/patch.diff +9 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-db-004-119-61557c/metadata.json +15 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-db-004-119-61557c/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-db-004-119-61557c/patch.diff +9 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-db-004-265-996ca3/metadata.json +15 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-db-004-265-996ca3/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-db-004-265-996ca3/patch.diff +9 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-db-004-503-d11cf8/metadata.json +15 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-db-004-503-d11cf8/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-db-004-503-d11cf8/patch.diff +9 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-db-004-79-91f41f/metadata.json +15 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-db-004-79-91f41f/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-db-004-79-91f41f/patch.diff +9 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-input-002-107-516a40/metadata.json +15 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-input-002-107-516a40/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-input-002-107-516a40/patch.diff +9 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-input-002-128-7809a1/metadata.json +15 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-input-002-128-7809a1/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-input-002-128-7809a1/patch.diff +9 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-input-002-256-c8a22e/metadata.json +15 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-input-002-256-c8a22e/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-input-002-256-c8a22e/patch.diff +9 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-input-003-53-d167b4/metadata.json +15 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-input-003-53-d167b4/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-input-003-53-d167b4/patch.diff +9 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-platform-001-183-47fd5e/metadata.json +15 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-platform-001-183-47fd5e/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-platform-001-183-47fd5e/patch.diff +9 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-sec-001-209-4f6424/metadata.json +15 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-sec-001-209-4f6424/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-sec-001-209-4f6424/patch.diff +9 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-sec-001-257-89bf34/metadata.json +15 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-sec-001-257-89bf34/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-sec-001-257-89bf34/patch.diff +9 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-sec-001-341-ce228c/metadata.json +15 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-sec-001-341-ce228c/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-sec-001-341-ce228c/patch.diff +9 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-sec-001-355-7b190b/metadata.json +15 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-sec-001-355-7b190b/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-sec-001-355-7b190b/patch.diff +9 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-sec-001-64-5af31a/metadata.json +15 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-sec-001-64-5af31a/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-sec-001-64-5af31a/patch.diff +9 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-sec-001-9-f51467/metadata.json +15 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-sec-001-9-f51467/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260910-120238-audit/bundles/bnd-tg-sec-001-9-f51467/patch.diff +9 -0
- package/.torusguard/runs/run-20260910-120238-audit/findings.json +1520 -0
- package/.torusguard/runs/run-20260910-120238-audit/findings.md +560 -0
- package/.torusguard/runs/run-20260910-120238-audit/manifest.json +13 -0
- package/.torusguard/runs/run-20260910-120238-audit/recheck.md +86 -0
- package/.torusguard/runs/run-20260910-120238-audit/remediation.md +262 -0
- package/.torusguard/runs/run-20260910-120238-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260910-121238-audit/findings.json +794 -0
- package/.torusguard/runs/run-20260910-121238-audit/findings.md +344 -0
- package/.torusguard/runs/run-20260910-121238-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260910-121238-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260910-130454-audit/findings.json +893 -0
- package/.torusguard/runs/run-20260910-130454-audit/findings.md +386 -0
- package/.torusguard/runs/run-20260910-130454-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260910-130454-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260910-130519-audit/findings.json +563 -0
- package/.torusguard/runs/run-20260910-130519-audit/findings.md +246 -0
- package/.torusguard/runs/run-20260910-130519-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260910-130519-audit/summary.md +5 -0
- package/.torusguard/scripts/__pycache__/audit_runner.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/diff_guard.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/html_reporter.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/rules_sync.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/stack_detect.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/term_ui.cpython-311.pyc +0 -0
- package/.torusguard/scripts/apply_runner.py +138 -100
- package/.torusguard/scripts/audit_runner.py +219 -116
- package/.torusguard/scripts/harden_runner.py +144 -64
- package/.torusguard/scripts/html_reporter.py +8 -3
- package/.torusguard/scripts/recheck_runner.py +80 -63
- package/.torusguard/scripts/recipes_runner.py +38 -31
- package/.torusguard/scripts/stack_detect.py +608 -584
- package/.torusguard/scripts/term_ui.py +162 -0
- package/.torusguard/skills/torusguard/SKILL.md +61 -31
- package/.torusguard/skills/torusguard-apply/SKILL.md +80 -46
- package/.torusguard/skills/torusguard-audit/SKILL.md +83 -70
- package/.torusguard/skills/torusguard-authorize/SKILL.md +5 -4
- package/.torusguard/skills/torusguard-exploit-check/SKILL.md +6 -5
- package/.torusguard/skills/torusguard-full/SKILL.md +1 -1
- package/.torusguard/skills/torusguard-harden/SKILL.md +94 -63
- package/.torusguard/skills/torusguard-init/SKILL.md +64 -52
- package/.torusguard/skills/torusguard-recheck/SKILL.md +77 -53
- package/.torusguard/skills/torusguard-report/SKILL.md +72 -54
- package/.torusguard/skills/torusguard-status/SKILL.md +58 -42
- package/.torusguard/skills/torusguard-verify/SKILL.md +8 -7
- package/.torusguard/skills/torusguard-web-validate/SKILL.md +8 -7
- package/README.md +4 -3
- package/bin/torusguard.js +544 -437
- package/package.json +1 -1
- package/skills/torusguard/SKILL.md +61 -31
- package/skills/torusguard/payload/scripts/apply_runner.py +138 -100
- package/skills/torusguard/payload/scripts/audit_runner.py +219 -116
- package/skills/torusguard/payload/scripts/harden_runner.py +144 -64
- package/skills/torusguard/payload/scripts/html_reporter.py +8 -3
- package/skills/torusguard/payload/scripts/recheck_runner.py +80 -63
- package/skills/torusguard/payload/scripts/recipes_runner.py +38 -31
- package/skills/torusguard/payload/scripts/stack_detect.py +608 -584
- package/skills/torusguard/payload/scripts/term_ui.py +162 -0
- package/skills/torusguard/payload/skills/torusguard/SKILL.md +61 -31
- package/skills/torusguard/payload/skills/torusguard-apply/SKILL.md +80 -46
- package/skills/torusguard/payload/skills/torusguard-audit/SKILL.md +83 -70
- package/skills/torusguard/payload/skills/torusguard-authorize/SKILL.md +5 -4
- package/skills/torusguard/payload/skills/torusguard-exploit-check/SKILL.md +6 -5
- package/skills/torusguard/payload/skills/torusguard-full/SKILL.md +1 -1
- package/skills/torusguard/payload/skills/torusguard-harden/SKILL.md +94 -63
- package/skills/torusguard/payload/skills/torusguard-init/SKILL.md +64 -52
- package/skills/torusguard/payload/skills/torusguard-recheck/SKILL.md +77 -53
- package/skills/torusguard/payload/skills/torusguard-report/SKILL.md +72 -54
- package/skills/torusguard/payload/skills/torusguard-status/SKILL.md +58 -42
- package/skills/torusguard/payload/skills/torusguard-verify/SKILL.md +8 -7
- package/skills/torusguard/payload/skills/torusguard-web-validate/SKILL.md +8 -7
- package/skills/torusguard-apply/SKILL.md +80 -46
- package/skills/torusguard-audit/SKILL.md +83 -70
- package/skills/torusguard-authorize/SKILL.md +5 -4
- package/skills/torusguard-exploit-check/SKILL.md +6 -5
- package/skills/torusguard-full/SKILL.md +1 -1
- package/skills/torusguard-harden/SKILL.md +94 -63
- package/skills/torusguard-init/SKILL.md +64 -52
- package/skills/torusguard-recheck/SKILL.md +77 -53
- package/skills/torusguard-report/SKILL.md +72 -54
- package/skills/torusguard-status/SKILL.md +58 -42
- package/skills/torusguard-verify/SKILL.md +8 -7
- package/skills/torusguard-web-validate/SKILL.md +8 -7
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
# TorusGuard Governed Remediation Catalog
|
|
2
|
+
**Run ID:** `run-20260910-120238-audit`
|
|
3
|
+
**Generated:** `2026-09-10 12:02:48 IST`
|
|
4
|
+
**Candidate Bundles Formulated:** `16`
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
## Formulated Candidate Patches
|
|
8
|
+
|
|
9
|
+
### [TG-INPUT-003] Unsafe Dynamic Code or HTML Execution
|
|
10
|
+
- **Target:** `examples/vulnerable-react-express/client/src/App.jsx:53` | **Bundle ID:** `bnd-tg-input-003-53-d167b4`
|
|
11
|
+
- **Strategy:** Replaced raw dangerouslySetInnerHTML injection with safe React text interpolation
|
|
12
|
+
- **Ponytail Churn:** `+1 / -1`
|
|
13
|
+
```diff
|
|
14
|
+
--- a/examples/vulnerable-react-express/client/src/App.jsx
|
|
15
|
+
+++ b/examples/vulnerable-react-express/client/src/App.jsx
|
|
16
|
+
@@ -51,5 +51,5 @@
|
|
17
|
+
|
|
18
|
+
{/* TG-INPUT-003: Unsafe HTML rendering */}
|
|
19
|
+
- <div dangerouslySetInnerHTML={{ __html: bio }} />
|
|
20
|
+
+ <div>{bio}</div>
|
|
21
|
+
|
|
22
|
+
<button onClick={fetchUser}>Fetch user (IDOR demo)</button>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### [TG-SEC-001] Hardcoded Secret or API Key in Tracked Source
|
|
26
|
+
- **Target:** `examples/vulnerable-react-express/server/index.js:9` | **Bundle ID:** `bnd-tg-sec-001-9-f51467`
|
|
27
|
+
- **Strategy:** Migrated hardcoded JWT secret to environment variable process.env.JWT_SECRET
|
|
28
|
+
- **Ponytail Churn:** `+1 / -1`
|
|
29
|
+
```diff
|
|
30
|
+
--- a/examples/vulnerable-react-express/server/index.js
|
|
31
|
+
+++ b/examples/vulnerable-react-express/server/index.js
|
|
32
|
+
@@ -7,5 +7,5 @@
|
|
33
|
+
|
|
34
|
+
// TG-SEC-001: Hardcoded JWT secret
|
|
35
|
+
-const JWT_SECRET = 'FAKE_DEMO_JWT_SECRET_NOT_FOR_PRODUCTION';
|
|
36
|
+
+const secret = process.env.JWT_SECRET || "";
|
|
37
|
+
|
|
38
|
+
// TG-PLATFORM-001: Wildcard CORS with credentials
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### [TG-INPUT-002] Unescaped Raw SQL Query Concatenation
|
|
42
|
+
- **Target:** `harness/engine/fixture_manager.py:128` | **Bundle ID:** `bnd-tg-input-002-128-7809a1`
|
|
43
|
+
- **Strategy:** Replaced unsafe Python SQL f-string interpolation with parameterized SQL query placeholder
|
|
44
|
+
- **Ponytail Churn:** `+1 / -1`
|
|
45
|
+
```diff
|
|
46
|
+
--- a/harness/engine/fixture_manager.py
|
|
47
|
+
+++ b/harness/engine/fixture_manager.py
|
|
48
|
+
@@ -126,5 +126,5 @@
|
|
49
|
+
vulnerable_variant=FixtureVariant(
|
|
50
|
+
relative_path="examples/python/sqlalchemy-vuln",
|
|
51
|
+
- code_pattern="session.execute(f'SELECT * FROM items WHERE name LIKE {q}')",
|
|
52
|
+
+ code_pattern="session.execute('SELECT * FROM items WHERE name LIKE %s')",
|
|
53
|
+
expected_findings_count=4,
|
|
54
|
+
),
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### [TG-SEC-001] Hardcoded Secret or API Key in Tracked Source
|
|
58
|
+
- **Target:** `harness/master_validation.py:257` | **Bundle ID:** `bnd-tg-sec-001-257-89bf34`
|
|
59
|
+
- **Strategy:** Replaced hardcoded credential with os.environ.get('MASKED_PWD')
|
|
60
|
+
- **Ponytail Churn:** `+1 / -1`
|
|
61
|
+
```diff
|
|
62
|
+
--- a/harness/master_validation.py
|
|
63
|
+
+++ b/harness/master_validation.py
|
|
64
|
+
@@ -255,5 +255,5 @@
|
|
65
|
+
self.log("Redaction", "JWT Token Redaction", "Bearer ***REDACTED_JWT***" in masked_jwt and "doNotLeakSignature" not in masked_jwt)
|
|
66
|
+
|
|
67
|
+
- masked_pwd = mask_sensitive_data("DB_PASSWORD = 'super_secret_database_password_123'")
|
|
68
|
+
+ masked_pwd = os.environ.get("MASKED_PWD", "")
|
|
69
|
+
self.log("Redaction", "Password Variable Redaction", "***REDACTED***" in masked_pwd and "super_secret_database_password_123" not in masked_pwd)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### [TG-SEC-001] Hardcoded Secret or API Key in Tracked Source
|
|
73
|
+
- **Target:** `harness/runner.py:209` | **Bundle ID:** `bnd-tg-sec-001-209-4f6424`
|
|
74
|
+
- **Strategy:** Replaced hardcoded credential with os.environ.get('RAW_SNIPPET')
|
|
75
|
+
- **Ponytail Churn:** `+1 / -1`
|
|
76
|
+
```diff
|
|
77
|
+
--- a/harness/runner.py
|
|
78
|
+
+++ b/harness/runner.py
|
|
79
|
+
@@ -207,5 +207,5 @@
|
|
80
|
+
type=EvidenceType.SOURCE,
|
|
81
|
+
location="server/auth.py:42",
|
|
82
|
+
- raw_snippet="SECRET_KEY = 'super_secret_jwt_key'",
|
|
83
|
+
+ raw_snippet = os.environ.get("RAW_SNIPPET", "")
|
|
84
|
+
rationale="Hardcoded secret credential.",
|
|
85
|
+
confidence_level=ConfidenceBand.CONFIRMED,
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### [TG-DB-004] Missing Multi-Tenant Isolation in Scoped Query
|
|
89
|
+
- **Target:** `harness/runner.py:503` | **Bundle ID:** `bnd-tg-db-004-503-d11cf8`
|
|
90
|
+
- **Strategy:** Added explicit organization_id tenant boundary filter to ORM query
|
|
91
|
+
- **Ponytail Churn:** `+1 / -1`
|
|
92
|
+
```diff
|
|
93
|
+
--- a/harness/runner.py
|
|
94
|
+
+++ b/harness/runner.py
|
|
95
|
+
@@ -501,5 +501,5 @@
|
|
96
|
+
|
|
97
|
+
# 2. Stable Finding Identity
|
|
98
|
+
- code_a = "def view():\n return Item.objects.get(id=id)"
|
|
99
|
+
+ code_a = "def view():\n return Item.objects.get(organization_id=request.user.organization_id, id=id)"
|
|
100
|
+
code_b = "# Shifted comment\ndef view():\n return Item.objects.get(id=id)"
|
|
101
|
+
fp1 = IdentityEngine.generate_identity("TG-DB-004", "views.py", code_a, sink_signature="Item.objects.get")
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### [TG-INPUT-002] Unescaped Raw SQL Query Concatenation
|
|
105
|
+
- **Target:** `harness/runner.py:256` | **Bundle ID:** `bnd-tg-input-002-256-c8a22e`
|
|
106
|
+
- **Strategy:** Replaced unsafe Python SQL f-string interpolation with parameterized SQL query placeholder
|
|
107
|
+
- **Ponytail Churn:** `+1 / -1`
|
|
108
|
+
```diff
|
|
109
|
+
--- a/harness/runner.py
|
|
110
|
+
+++ b/harness/runner.py
|
|
111
|
+
@@ -254,5 +254,5 @@
|
|
112
|
+
framework_pattern=FrameworkPattern(
|
|
113
|
+
framework="Django",
|
|
114
|
+
- unsafe_snippet="User.objects.raw(f'SELECT * FROM users WHERE name = {name}')",
|
|
115
|
+
+ unsafe_snippet="User.objects.raw('SELECT * FROM users WHERE name = %s')",
|
|
116
|
+
safe_snippet="User.objects.raw('SELECT * FROM users WHERE name = %s', [name])",
|
|
117
|
+
),
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### [TG-SEC-001] Hardcoded Secret or API Key in Tracked Source
|
|
121
|
+
- **Target:** `harness/validate_e2e.py:355` | **Bundle ID:** `bnd-tg-sec-001-355-7b190b`
|
|
122
|
+
- **Strategy:** Replaced hardcoded credential with os.environ.get('RAW_CODE')
|
|
123
|
+
- **Ponytail Churn:** `+1 / -1`
|
|
124
|
+
```diff
|
|
125
|
+
--- a/harness/validate_e2e.py
|
|
126
|
+
+++ b/harness/validate_e2e.py
|
|
127
|
+
@@ -353,5 +353,5 @@
|
|
128
|
+
|
|
129
|
+
def _create_sample_finding(self, rule_id: str, target_path: str, secret_test: bool = False) -> Finding:
|
|
130
|
+
- raw_code = "API_KEY = 'sk_live_998877665544332211'\nAuthorization = 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.doNotLeakSignature'" if secret_test else f"# Unsafe logic for {rule_id}\nrole = request.headers.get('X-User-Role')"
|
|
131
|
+
+ raw_code = os.environ.get("RAW_CODE", "")
|
|
132
|
+
|
|
133
|
+
ev = Evidence(
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### [TG-SEC-001] Hardcoded Secret or API Key in Tracked Source
|
|
137
|
+
- **Target:** `harness/validate_qa_v0_6_0.py:64` | **Bundle ID:** `bnd-tg-sec-001-64-5af31a`
|
|
138
|
+
- **Strategy:** Replaced hardcoded credential with os.environ.get('DEBUG')
|
|
139
|
+
- **Ponytail Churn:** `+1 / -1`
|
|
140
|
+
```diff
|
|
141
|
+
--- a/harness/validate_qa_v0_6_0.py
|
|
142
|
+
+++ b/harness/validate_qa_v0_6_0.py
|
|
143
|
+
@@ -62,5 +62,5 @@
|
|
144
|
+
"tiny-repo": {
|
|
145
|
+
"vulnerable": {
|
|
146
|
+
- "app.py": 'DEBUG = True\nSECRET_KEY = "sk_live_1234567890"\n\ndef index():\n return "Welcome"\n'
|
|
147
|
+
+ DEBUG = os.environ.get("DEBUG", "")
|
|
148
|
+
},
|
|
149
|
+
"hardened": {
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### [TG-DB-004] Missing Multi-Tenant Isolation in Scoped Query
|
|
153
|
+
- **Target:** `harness/validate_v0_6_1_scale.py:115` | **Bundle ID:** `bnd-tg-db-004-115-9a059e`
|
|
154
|
+
- **Strategy:** Added explicit organization_id tenant boundary filter to ORM query
|
|
155
|
+
- **Ponytail Churn:** `+1 / -1`
|
|
156
|
+
```diff
|
|
157
|
+
--- a/harness/validate_v0_6_1_scale.py
|
|
158
|
+
+++ b/harness/validate_v0_6_1_scale.py
|
|
159
|
+
@@ -113,5 +113,5 @@
|
|
160
|
+
"severity": "High",
|
|
161
|
+
"target": {"file_path": "apps/django_core/billing/views.py", "line_start": 42, "line_end": 42},
|
|
162
|
+
- "evidence": {"code_snippet": "Invoice.objects.get(id=inv_id)"},
|
|
163
|
+
+ "evidence": {"code_snippet": "Invoice.objects.get(organization_id=request.user.organization_id, id=inv_id)"},
|
|
164
|
+
},
|
|
165
|
+
# FastAPI Microservice
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### [TG-SEC-001] Hardcoded Secret or API Key in Tracked Source
|
|
169
|
+
- **Target:** `harness/validate_v0_6_2_modern_stacks.py:341` | **Bundle ID:** `bnd-tg-sec-001-341-ce228c`
|
|
170
|
+
- **Strategy:** Replaced hardcoded credential with os.environ.get('DATABASE_PASSWORD')
|
|
171
|
+
- **Ponytail Churn:** `+1 / -1`
|
|
172
|
+
```diff
|
|
173
|
+
--- a/harness/validate_v0_6_2_modern_stacks.py
|
|
174
|
+
+++ b/harness/validate_v0_6_2_modern_stacks.py
|
|
175
|
+
@@ -339,5 +339,5 @@
|
|
176
|
+
COPY . .
|
|
177
|
+
# Running as root user & hardcoding secrets
|
|
178
|
+
-ENV DATABASE_PASSWORD="secret_in_docker"
|
|
179
|
+
+DATABASE_PASSWORD = os.environ.get("DATABASE_PASSWORD", "")
|
|
180
|
+
CMD ["python", "main.py"]
|
|
181
|
+
""", encoding="utf-8")
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### [TG-DB-004] Missing Multi-Tenant Isolation in Scoped Query
|
|
185
|
+
- **Target:** `harness/validate_v0_6_3_hardening.py:119` | **Bundle ID:** `bnd-tg-db-004-119-61557c`
|
|
186
|
+
- **Strategy:** Added explicit organization_id tenant boundary filter to ORM query
|
|
187
|
+
- **Ponytail Churn:** `+1 / -1`
|
|
188
|
+
```diff
|
|
189
|
+
--- a/harness/validate_v0_6_3_hardening.py
|
|
190
|
+
+++ b/harness/validate_v0_6_3_hardening.py
|
|
191
|
+
@@ -117,5 +117,5 @@
|
|
192
|
+
snippet_v1 = """def process_invoice(req, inv_id):
|
|
193
|
+
# Retrieve invoice
|
|
194
|
+
- inv = Invoice.objects.get(id=inv_id)
|
|
195
|
+
+ inv = Invoice.objects.get(organization_id=request.user.organization_id, id=inv_id)
|
|
196
|
+
return inv
|
|
197
|
+
"""
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### [TG-DB-004] Missing Multi-Tenant Isolation in Scoped Query
|
|
201
|
+
- **Target:** `harness/validate_v1_0_0_memory.py:265` | **Bundle ID:** `bnd-tg-db-004-265-996ca3`
|
|
202
|
+
- **Strategy:** Added explicit organization_id tenant boundary filter to ORM query
|
|
203
|
+
- **Ponytail Churn:** `+1 / -1`
|
|
204
|
+
```diff
|
|
205
|
+
--- a/harness/validate_v1_0_0_memory.py
|
|
206
|
+
+++ b/harness/validate_v1_0_0_memory.py
|
|
207
|
+
@@ -263,5 +263,5 @@
|
|
208
|
+
- return Bill.objects.filter(id=id, tenant=tenant)
|
|
209
|
+
+def get_bill(id):
|
|
210
|
+
-+ return Bill.objects.get(id=id)
|
|
211
|
+
++ return Bill.objects.get(organization_id=request.user.organization_id, id=id)
|
|
212
|
+
"""
|
|
213
|
+
res_reg = diff_guard.audit_diff(regression_diff, check_memory=True, root_dir=test_root)
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### [TG-INPUT-002] Unescaped Raw SQL Query Concatenation
|
|
217
|
+
- **Target:** `harness/validate_v1_1_0_advanced_memory.py:107` | **Bundle ID:** `bnd-tg-input-002-107-516a40`
|
|
218
|
+
- **Strategy:** Replaced unsafe Python SQL f-string interpolation with parameterized SQL query placeholder
|
|
219
|
+
- **Ponytail Churn:** `+1 / -1`
|
|
220
|
+
```diff
|
|
221
|
+
--- a/harness/validate_v1_1_0_advanced_memory.py
|
|
222
|
+
+++ b/harness/validate_v1_1_0_advanced_memory.py
|
|
223
|
+
@@ -105,5 +105,5 @@
|
|
224
|
+
memory_engine.ensure_memory_structure(root_dir=test_root)
|
|
225
|
+
|
|
226
|
+
- valid_before = "cursor.execute(f'SELECT * FROM users WHERE id = {uid}')"
|
|
227
|
+
+ valid_before = "cursor.execute('SELECT * FROM users WHERE id = %s')"
|
|
228
|
+
valid_after = "cursor.execute('SELECT * FROM users WHERE id = %s', (uid,))"
|
|
229
|
+
valid_diff = "- cursor.execute(f'SELECT * FROM users WHERE id = {uid}')\n+ cursor.execute('SELECT * FROM users WHERE id = %s', (uid,))"
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### [TG-PLATFORM-001] Wildcard Permissive CORS Configuration with Credentials
|
|
233
|
+
- **Target:** `skills/torusguard/payload/scripts/harden_runner.py:183` | **Bundle ID:** `bnd-tg-platform-001-183-47fd5e`
|
|
234
|
+
- **Strategy:** Replaced wildcard CORS configuration with strict origin whitelist environment variable
|
|
235
|
+
- **Ponytail Churn:** `+1 / -1`
|
|
236
|
+
```diff
|
|
237
|
+
--- a/skills/torusguard/payload/scripts/harden_runner.py
|
|
238
|
+
+++ b/skills/torusguard/payload/scripts/harden_runner.py
|
|
239
|
+
@@ -181,5 +181,5 @@
|
|
240
|
+
# Strategy 5: Permissive CORS with Credentials (TG-PLATFORM-001)
|
|
241
|
+
elif rule_id == "TG-PLATFORM-001":
|
|
242
|
+
- if "CORS_ALLOW_ALL_ORIGINS = True" in target_line:
|
|
243
|
+
+ CORS_ALLOWED_ORIGINS = [os.environ.get("ALLOWED_ORIGIN", "https://app.example.com")]
|
|
244
|
+
replacement = f'{indent}CORS_ALLOWED_ORIGINS = [os.environ.get("ALLOWED_ORIGIN", "https://app.example.com")]'
|
|
245
|
+
new_lines[line_number - 1] = replacement
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### [TG-DB-004] Missing Multi-Tenant Isolation in Scoped Query
|
|
249
|
+
- **Target:** `tests/test_v0_6_0_governed_remediation.py:79` | **Bundle ID:** `bnd-tg-db-004-79-91f41f`
|
|
250
|
+
- **Strategy:** Added explicit organization_id tenant boundary filter to ORM query
|
|
251
|
+
- **Ponytail Churn:** `+1 / -1`
|
|
252
|
+
```diff
|
|
253
|
+
--- a/tests/test_v0_6_0_governed_remediation.py
|
|
254
|
+
+++ b/tests/test_v0_6_0_governed_remediation.py
|
|
255
|
+
@@ -77,5 +77,5 @@
|
|
256
|
+
def get_invoice(request, invoice_id):
|
|
257
|
+
# Fetch invoice directly without tenant filter
|
|
258
|
+
- invoice = Invoice.objects.get(id=invoice_id)
|
|
259
|
+
+ invoice = Invoice.objects.get(organization_id=request.user.organization_id, id=invoice_id)
|
|
260
|
+
return JsonResponse({"id": invoice.id})
|
|
261
|
+
"""
|
|
262
|
+
```
|