torusguard 1.0.0 → 1.3.0
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/.manifest.json +89 -75
- package/.torusguard/references/csharp-security.md +41 -0
- package/.torusguard/references/go-security.md +41 -0
- package/.torusguard/references/java-security.md +40 -0
- package/.torusguard/references/polyglot-security-matrix.md +25 -0
- package/.torusguard/references/rust-security.md +40 -0
- package/.torusguard/rules/custom/.gitkeep +1 -0
- package/.torusguard/rules/custom/README.md +30 -0
- package/.torusguard/runs/report-latest.html +328 -0
- package/.torusguard/schemas/golden-recipe.schema.json +75 -0
- package/.torusguard/scripts/diff_guard.py +131 -4
- package/.torusguard/scripts/finding_scorer.py +33 -5
- package/.torusguard/scripts/html_reporter.py +628 -0
- package/.torusguard/scripts/manifest_builder.py +5 -5
- package/.torusguard/scripts/memory_engine.py +521 -99
- package/.torusguard/scripts/monorepo_detector.py +123 -10
- package/.torusguard/scripts/rules_sync.py +321 -0
- package/.torusguard/scripts/stack_detect.py +458 -26
- package/.torusguard/skills/torusguard/references/csharp-security.md +41 -0
- package/.torusguard/skills/torusguard/references/go-security.md +41 -0
- package/.torusguard/skills/torusguard/references/java-security.md +40 -0
- package/.torusguard/skills/torusguard/references/polyglot-security-matrix.md +25 -0
- package/.torusguard/skills/torusguard/references/rust-security.md +40 -0
- package/README.md +307 -410
- package/bin/torusguard.js +108 -4
- package/package.json +1 -1
- package/skills/torusguard/bootstrap.py +2 -2
- package/skills/torusguard/payload/.manifest.json +89 -75
- package/skills/torusguard/payload/references/csharp-security.md +41 -0
- package/skills/torusguard/payload/references/go-security.md +41 -0
- package/skills/torusguard/payload/references/java-security.md +40 -0
- package/skills/torusguard/payload/references/polyglot-security-matrix.md +25 -0
- package/skills/torusguard/payload/references/rust-security.md +40 -0
- package/skills/torusguard/payload/rules/custom/.gitkeep +1 -0
- package/skills/torusguard/payload/rules/custom/README.md +30 -0
- package/skills/torusguard/payload/schemas/golden-recipe.schema.json +75 -0
- package/skills/torusguard/payload/scripts/diff_guard.py +131 -4
- package/skills/torusguard/payload/scripts/finding_scorer.py +33 -5
- package/skills/torusguard/payload/scripts/html_reporter.py +628 -0
- package/skills/torusguard/payload/scripts/manifest_builder.py +5 -5
- package/skills/torusguard/payload/scripts/memory_engine.py +521 -99
- package/skills/torusguard/payload/scripts/monorepo_detector.py +123 -10
- package/skills/torusguard/payload/scripts/rules_sync.py +321 -0
- package/skills/torusguard/payload/scripts/stack_detect.py +458 -26
- package/skills/torusguard/payload/skills/torusguard/bootstrap.py +2 -2
- package/skills/torusguard/payload/skills/torusguard/references/csharp-security.md +41 -0
- package/skills/torusguard/payload/skills/torusguard/references/go-security.md +41 -0
- package/skills/torusguard/payload/skills/torusguard/references/java-security.md +40 -0
- package/skills/torusguard/payload/skills/torusguard/references/polyglot-security-matrix.md +25 -0
- package/skills/torusguard/payload/skills/torusguard/references/rust-security.md +40 -0
- package/.torusguard/scripts/__pycache__/diff_guard.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/finding_scorer.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/memory_engine.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/monorepo_detector.cpython-311.pyc +0 -0
- package/skills/torusguard/__pycache__/bootstrap.cpython-311.pyc +0 -0
package/bin/torusguard.js
CHANGED
|
@@ -49,7 +49,7 @@ function printHelp() {
|
|
|
49
49
|
console.log(`
|
|
50
50
|
${CYAN}╭─────────────────────────────────────────────────────────────────────────╮${RESET}
|
|
51
51
|
${CYAN}│${RESET} ${CYAN}│${RESET}
|
|
52
|
-
${CYAN}│${RESET} ${BOLD}${WHITE}🛡️ T O R U S G U A R D C L I${RESET} ${GRAY}v1.
|
|
52
|
+
${CYAN}│${RESET} ${BOLD}${WHITE}🛡️ T O R U S G U A R D C L I${RESET} ${GRAY}v1.3.0${RESET} ${CYAN}│${RESET}
|
|
53
53
|
${CYAN}│${RESET} ${DIM}Autonomous Security Engine for AI-Built Applications${RESET} ${CYAN}│${RESET}
|
|
54
54
|
${CYAN}│${RESET} ${CYAN}│${RESET}
|
|
55
55
|
${CYAN}╰─────────────────────────────────────────────────────────────────────────╯${RESET}
|
|
@@ -61,11 +61,22 @@ function printHelp() {
|
|
|
61
61
|
${CYAN}├─────────────────────────────────────────────────────────────────────────┤${RESET}
|
|
62
62
|
${CYAN}│${RESET} ${GREEN}init${RESET} Scaffold ${BOLD}.torusguard/${RESET} workspace + unlock 12 slash commands ${CYAN}│${RESET}
|
|
63
63
|
${CYAN}│${RESET} ${GREEN}status${RESET} Display active security posture, memory, rules, and stack ${CYAN}│${RESET}
|
|
64
|
-
${CYAN}│${RESET} ${GREEN}
|
|
64
|
+
${CYAN}│${RESET} ${GREEN}rules${RESET} Auto-sync memory to AI IDE rules (.cursorrules, CLAUDE.md) ${CYAN}│${RESET}
|
|
65
|
+
${CYAN}│${RESET} ${GREEN}memory${RESET} Manage persistent security memory (export, hook, learn) ${CYAN}│${RESET}
|
|
65
66
|
${CYAN}│${RESET} ${GREEN}audit${RESET} Run static AST security scan on the target project ${CYAN}│${RESET}
|
|
66
|
-
${CYAN}│${RESET} ${GREEN}report${RESET} Export OASIS SARIF v2.1.0
|
|
67
|
+
${CYAN}│${RESET} ${GREEN}report${RESET} Export OASIS SARIF v2.1.0 or single-file visual HTML report ${CYAN}│${RESET}
|
|
68
|
+
${CYAN}│${RESET} ${GREEN}diff-guard${RESET} Scan diffs or wire pre-commit hook (--install-hook) ${CYAN}│${RESET}
|
|
67
69
|
${CYAN}│${RESET} ${GREEN}help${RESET} Show this interactive command guide ${CYAN}│${RESET}
|
|
68
70
|
${CYAN}├─────────────────────────────────────────────────────────────────────────┤${RESET}
|
|
71
|
+
${CYAN}│${RESET} ${BOLD}AI & Memory Subcommands${RESET} ${CYAN}│${RESET}
|
|
72
|
+
${CYAN}├─────────────────────────────────────────────────────────────────────────┤${RESET}
|
|
73
|
+
${CYAN}│${RESET} ${WHITE}rules sync${RESET} ${DIM}[--format all|cursor|claude|agent|windsurf]${RESET} ${CYAN}│${RESET}
|
|
74
|
+
${CYAN}│${RESET} ${WHITE}report --html${RESET} ${DIM}[--out <path>] Self-contained visual HTML dashboard${RESET} ${CYAN}│${RESET}
|
|
75
|
+
${CYAN}│${RESET} ${WHITE}memory context${RESET} ${DIM}[--role auditor|remediator|reviewer] [--file <f>]${RESET} ${CYAN}│${RESET}
|
|
76
|
+
${CYAN}│${RESET} ${WHITE}memory hook${RESET} ${DIM}[install|uninstall] Git pre-commit regression hook${RESET} ${CYAN}│${RESET}
|
|
77
|
+
${CYAN}│${RESET} ${WHITE}memory learn${RESET} ${DIM}[--commits <range>] Ingest security commit fixes${RESET} ${CYAN}│${RESET}
|
|
78
|
+
${CYAN}│${RESET} ${WHITE}memory export${RESET} ${DIM}[--path <file>] [--sanitized] Safe team sharing${RESET} ${CYAN}│${RESET}
|
|
79
|
+
${CYAN}├─────────────────────────────────────────────────────────────────────────┤${RESET}
|
|
69
80
|
${CYAN}│${RESET} ${BOLD}Options${RESET} ${CYAN}│${RESET}
|
|
70
81
|
${CYAN}├─────────────────────────────────────────────────────────────────────────┤${RESET}
|
|
71
82
|
${CYAN}│${RESET} ${GRAY}--target <dir>${RESET} Target directory to analyze or scaffold ${DIM}(default: .)${RESET} ${CYAN}│${RESET}
|
|
@@ -126,7 +137,7 @@ if (command === 'status') {
|
|
|
126
137
|
console.log(`
|
|
127
138
|
${CYAN}╭─────────────────────────────────────────────────────────────────────────╮${RESET}
|
|
128
139
|
${CYAN}│${RESET} ${CYAN}│${RESET}
|
|
129
|
-
${CYAN}│${RESET} ${BOLD}${WHITE}🛡️ TORUSGUARD SECURITY POSTURE${RESET} ${GRAY}v1.
|
|
140
|
+
${CYAN}│${RESET} ${BOLD}${WHITE}🛡️ TORUSGUARD SECURITY POSTURE${RESET} ${GRAY}v1.3.0${RESET} ${CYAN}│${RESET}
|
|
130
141
|
${CYAN}│${RESET} ${CYAN}│${RESET}
|
|
131
142
|
${CYAN}╰─────────────────────────────────────────────────────────────────────────╯${RESET}
|
|
132
143
|
|
|
@@ -190,6 +201,18 @@ if (command === 'memory') {
|
|
|
190
201
|
pyArgs.push('--action', 'status');
|
|
191
202
|
} else if (sub === 'context') {
|
|
192
203
|
pyArgs.push('--action', 'context');
|
|
204
|
+
const roleIdx = args.indexOf('--role');
|
|
205
|
+
if (roleIdx !== -1 && args[roleIdx + 1]) {
|
|
206
|
+
pyArgs.push('--role', args[roleIdx + 1]);
|
|
207
|
+
}
|
|
208
|
+
const fileIdx = args.indexOf('--file') !== -1 ? args.indexOf('--file') : args.indexOf('-f');
|
|
209
|
+
if (fileIdx !== -1 && args[fileIdx + 1]) {
|
|
210
|
+
pyArgs.push('--file', args[fileIdx + 1]);
|
|
211
|
+
}
|
|
212
|
+
const ruleIdx = args.indexOf('--rule') !== -1 ? args.indexOf('--rule') : args.indexOf('-r');
|
|
213
|
+
if (ruleIdx !== -1 && args[ruleIdx + 1]) {
|
|
214
|
+
pyArgs.push('--rule-id', args[ruleIdx + 1]);
|
|
215
|
+
}
|
|
193
216
|
} else if (sub === 'distill') {
|
|
194
217
|
pyArgs.push('--action', 'distill');
|
|
195
218
|
} else if (sub === 'decay') {
|
|
@@ -212,6 +235,9 @@ if (command === 'memory') {
|
|
|
212
235
|
} else {
|
|
213
236
|
pyArgs.push('--target', 'torusguard-memory-export.json');
|
|
214
237
|
}
|
|
238
|
+
if (args.includes('--sanitized')) {
|
|
239
|
+
pyArgs.push('--sanitized');
|
|
240
|
+
}
|
|
215
241
|
} else if (sub === 'import') {
|
|
216
242
|
pyArgs.push('--action', 'import');
|
|
217
243
|
const pathIdx = args.indexOf('--path') !== -1 ? args.indexOf('--path') : args.indexOf('-p');
|
|
@@ -221,6 +247,21 @@ if (command === 'memory') {
|
|
|
221
247
|
console.error(`${RED}Error: --path <file> is required for memory import${RESET}`);
|
|
222
248
|
process.exit(1);
|
|
223
249
|
}
|
|
250
|
+
} else if (sub === 'hook') {
|
|
251
|
+
const hookAction = args[2] === 'uninstall' ? 'hook-uninstall' : 'hook-install';
|
|
252
|
+
pyArgs.push('--action', hookAction);
|
|
253
|
+
} else if (sub === 'learn') {
|
|
254
|
+
pyArgs.push('--action', 'learn');
|
|
255
|
+
const commitsIdx = args.indexOf('--commits');
|
|
256
|
+
if (commitsIdx !== -1 && args[commitsIdx + 1]) {
|
|
257
|
+
pyArgs.push('--commits', args[commitsIdx + 1]);
|
|
258
|
+
}
|
|
259
|
+
const daysIdx = args.indexOf('--days');
|
|
260
|
+
if (daysIdx !== -1 && args[daysIdx + 1]) {
|
|
261
|
+
pyArgs.push('--days', args[daysIdx + 1]);
|
|
262
|
+
}
|
|
263
|
+
} else if (sub === 'recipe') {
|
|
264
|
+
pyArgs.push('--action', 'recipe', ...args.slice(2));
|
|
224
265
|
} else if (sub === 'fp') {
|
|
225
266
|
pyArgs.push('--action', 'fp');
|
|
226
267
|
const ruleIdx = args.indexOf('--rule') !== -1 ? args.indexOf('--rule') : args.indexOf('-r');
|
|
@@ -242,6 +283,69 @@ if (command === 'memory') {
|
|
|
242
283
|
process.exit(proc.status !== null ? proc.status : 0);
|
|
243
284
|
}
|
|
244
285
|
|
|
286
|
+
// Subcommand: diff-guard
|
|
287
|
+
if (command === 'diff-guard') {
|
|
288
|
+
const diffScript = path.join(cwd, '.torusguard', 'scripts', 'diff_guard.py');
|
|
289
|
+
const fallbackDiffScript = path.join(rootDir, '.torusguard', 'scripts', 'diff_guard.py');
|
|
290
|
+
const actualDiffScript = fs.existsSync(diffScript) ? diffScript : fallbackDiffScript;
|
|
291
|
+
|
|
292
|
+
const proc = spawnSync(pythonCmd, [actualDiffScript, ...args.slice(1)], { stdio: 'inherit', cwd });
|
|
293
|
+
process.exit(proc.status !== null ? proc.status : 0);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Subcommand: rules
|
|
297
|
+
if (command === 'rules') {
|
|
298
|
+
const sub = args[1] || 'sync';
|
|
299
|
+
const rulesScript = path.join(cwd, '.torusguard', 'scripts', 'rules_sync.py');
|
|
300
|
+
const fallbackRulesScript = path.join(rootDir, '.torusguard', 'scripts', 'rules_sync.py');
|
|
301
|
+
const actualRulesScript = fs.existsSync(rulesScript) ? rulesScript : fallbackRulesScript;
|
|
302
|
+
|
|
303
|
+
let pyArgs = [actualRulesScript];
|
|
304
|
+
if (sub === 'sync') {
|
|
305
|
+
const fmtIdx = args.indexOf('--format');
|
|
306
|
+
if (fmtIdx !== -1 && args[fmtIdx + 1]) {
|
|
307
|
+
pyArgs.push('--format', args[fmtIdx + 1]);
|
|
308
|
+
}
|
|
309
|
+
const rootIdx = args.indexOf('--root') !== -1 ? args.indexOf('--root') : args.indexOf('--target');
|
|
310
|
+
if (rootIdx !== -1 && args[rootIdx + 1]) {
|
|
311
|
+
pyArgs.push('--root', args[rootIdx + 1]);
|
|
312
|
+
}
|
|
313
|
+
if (args.includes('--json')) {
|
|
314
|
+
pyArgs.push('--json');
|
|
315
|
+
}
|
|
316
|
+
} else {
|
|
317
|
+
pyArgs.push(...args.slice(1));
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
const proc = spawnSync(pythonCmd, pyArgs, { stdio: 'inherit', cwd });
|
|
321
|
+
process.exit(proc.status !== null ? proc.status : 0);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Subcommand: report
|
|
325
|
+
if (command === 'report') {
|
|
326
|
+
if (args.includes('--html') || args[1] === 'html') {
|
|
327
|
+
const htmlScript = path.join(cwd, '.torusguard', 'scripts', 'html_reporter.py');
|
|
328
|
+
const fallbackHtmlScript = path.join(rootDir, '.torusguard', 'scripts', 'html_reporter.py');
|
|
329
|
+
const actualHtmlScript = fs.existsSync(htmlScript) ? htmlScript : fallbackHtmlScript;
|
|
330
|
+
|
|
331
|
+
let pyArgs = [actualHtmlScript];
|
|
332
|
+
const outIdx = args.indexOf('--out');
|
|
333
|
+
if (outIdx !== -1 && args[outIdx + 1]) {
|
|
334
|
+
pyArgs.push('--out', args[outIdx + 1]);
|
|
335
|
+
}
|
|
336
|
+
const rootIdx = args.indexOf('--root') !== -1 ? args.indexOf('--root') : args.indexOf('--target');
|
|
337
|
+
if (rootIdx !== -1 && args[rootIdx + 1]) {
|
|
338
|
+
pyArgs.push('--root', args[rootIdx + 1]);
|
|
339
|
+
}
|
|
340
|
+
if (args.includes('--json')) {
|
|
341
|
+
pyArgs.push('--json');
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const proc = spawnSync(pythonCmd, pyArgs, { stdio: 'inherit', cwd });
|
|
345
|
+
process.exit(proc.status !== null ? proc.status : 0);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
245
349
|
// Locate bootstrap / runner scripts
|
|
246
350
|
const localBootstrap = path.join(rootDir, 'skills', 'torusguard', 'bootstrap.py');
|
|
247
351
|
const localInstall = path.join(rootDir, 'install.py');
|
package/package.json
CHANGED
|
@@ -15,12 +15,12 @@ from pathlib import Path
|
|
|
15
15
|
# Ensure UTF-8 stdout/stderr on Windows consoles
|
|
16
16
|
if sys.stdout and hasattr(sys.stdout, "reconfigure"):
|
|
17
17
|
try:
|
|
18
|
-
sys.stdout
|
|
18
|
+
getattr(sys.stdout, "reconfigure")(encoding="utf-8", errors="replace")
|
|
19
19
|
except Exception:
|
|
20
20
|
pass
|
|
21
21
|
if sys.stderr and hasattr(sys.stderr, "reconfigure"):
|
|
22
22
|
try:
|
|
23
|
-
sys.stderr
|
|
23
|
+
getattr(sys.stderr, "reconfigure")(encoding="utf-8", errors="replace")
|
|
24
24
|
except Exception:
|
|
25
25
|
pass
|
|
26
26
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"ARCHITECTURE.md": "
|
|
2
|
+
"ARCHITECTURE.md": "cdc690a856e82574a6574ab6b1ad8a2d8b3b8264c36931c6212321066eed82e4",
|
|
3
3
|
"TORUSGUARD.md": "c980b0ddd3778d5981f6c16c64015c60dc713b6f151fc531bc5681ecd770fb50",
|
|
4
4
|
"agents/auditor.md": "4ba2c92982823d0886c7ae369126cd5ddd322085a85d3b7e7fa23154f8753314",
|
|
5
5
|
"agents/profiler.md": "0ee9ebbddf4ebd557d454dda8472fffea471e263abeccf40298163084b7ce9a9",
|
|
@@ -7,94 +7,108 @@
|
|
|
7
7
|
"agents/reviewer.md": "69b280bb8a7b2fe425644d01a6f9cb454f9629f348782cd14968657076977c28",
|
|
8
8
|
"agents/validator.md": "79fc4431de5c5507f8730aee6c5c3e61fd238cbf8cf8c7c6aac462eee9761ed6",
|
|
9
9
|
"config/scope.json": "b198a86186b4c6d5e1af516bf4e3a6afa8878e622ca1d57a5bf72d294f8c6f25",
|
|
10
|
-
"config/slash-commands.json": "
|
|
11
|
-
"config/torusguard.json": "
|
|
12
|
-
"references/
|
|
13
|
-
"references/
|
|
14
|
-
"references/
|
|
15
|
-
"references/
|
|
16
|
-
"references/
|
|
17
|
-
"references/
|
|
18
|
-
"references/
|
|
19
|
-
"references/
|
|
20
|
-
"references/
|
|
21
|
-
"references/
|
|
10
|
+
"config/slash-commands.json": "305c1dc5b556e8d64ad9dd585dafac1a9955cf1bd5321429955b19b7a62736b6",
|
|
11
|
+
"config/torusguard.json": "55dbde335997421a01c97709fd1672ad70fa921bfe8346dd57552b799db2419e",
|
|
12
|
+
"references/csharp-security.md": "d6e267855b08ed4fdff26f3b876f089ae1f90a7ec6546cba7e8173380d9daa9d",
|
|
13
|
+
"references/django-security.md": "26ea5535ac435e61489df1e381ac62b19e81702edfe095e78c937be93fa15ea7",
|
|
14
|
+
"references/drf-security.md": "c6796398317b0f264d89fff598404e126d819e69e1ea0a5129924a5eb2a7af9d",
|
|
15
|
+
"references/express-security.md": "3b9896c4c9cfac3199c830db07c661bad1d4529863cab77605db760550def98e",
|
|
16
|
+
"references/fastapi-security.md": "45136325e7cc65aa78af848636f6e18fc0e871978599505cff3ac95c5823d3d4",
|
|
17
|
+
"references/firebase-security.md": "c49eaf58e28b7aa37234ea09f13716fe78357521cdd260d5e536d920e9f406b7",
|
|
18
|
+
"references/flask-security.md": "f359ffdb6ca8c60eaccde2767c8177ed1e2d4fd1391d869405026262fda79f25",
|
|
19
|
+
"references/go-security.md": "a008606e7698c372140c2c5f5e0ec3c11ac34ae760847650a99c0aee102e6138",
|
|
20
|
+
"references/java-security.md": "6f27483e271be9d73af0d00fee280a74aeafb08f584cd3313ca349936f779ee6",
|
|
21
|
+
"references/nextjs-security.md": "4cfa06225a31bc415501ca7d58adc8c12078cc263b78770ae398c7dadcb1e7a2",
|
|
22
|
+
"references/polyglot-security-matrix.md": "d69453814969b5fd33800baa77433b7ae9564264153cddfd45aa0b87756ed919",
|
|
23
|
+
"references/react-vite-security.md": "bcc6c38644ff6c939059f12d0f4fc34d3abd338a6c1a0e8406addcd3e50fae45",
|
|
24
|
+
"references/rust-security.md": "3975f69bb0d983171b521766ca9e0022632acff83439d2f0406599a551702a64",
|
|
25
|
+
"references/sqlalchemy-security.md": "a3671325d4d0dfac95c2f9ef41fa7fccb440400e35dd53bcd0c1984e48626cb2",
|
|
26
|
+
"references/supabase-security.md": "4f057d247c9b35a29105ed5e9f74c61b378b33cbc674cbcfa82dbb8174f98ac5",
|
|
22
27
|
"rules/README.md": "a1b80344b0ca199a4917bdbd00463a8ae1459187f65467dbd627ce93a103042e",
|
|
23
|
-
"rules/TORUSGUARD.md": "
|
|
24
|
-
"rules/active/TG-DIFF-001.md": "
|
|
25
|
-
"rules/active/TG-DIFF-002.md": "
|
|
26
|
-
"rules/active/TG-DIFF-003.md": "
|
|
27
|
-
"
|
|
28
|
-
"schemas/
|
|
29
|
-
"schemas/
|
|
30
|
-
"schemas/
|
|
28
|
+
"rules/TORUSGUARD.md": "c980b0ddd3778d5981f6c16c64015c60dc713b6f151fc531bc5681ecd770fb50",
|
|
29
|
+
"rules/active/TG-DIFF-001.md": "9633466d6aa787ddb0d9df40a18b1bc31c1e12d59d2e11e7ceac4ad8e042770c",
|
|
30
|
+
"rules/active/TG-DIFF-002.md": "330f5200eb93da0b7a25515d3cc0f37839e0d91cc8ee0b870663f70c554211a3",
|
|
31
|
+
"rules/active/TG-DIFF-003.md": "f87730a95446f685f80ac859740883013d832a3c681355fe34ddab0b45e377b8",
|
|
32
|
+
"rules/custom/README.md": "f2128661ad3bc4085a69ddfbabbb2211930215fc42a25e2ab2d3e7a4b749a639",
|
|
33
|
+
"schemas/authorization.schema.json": "84885c9edc930a22c777d8685219f1f25b5320c0c6062722e3ba09f1fe417ad4",
|
|
34
|
+
"schemas/confidence.schema.json": "09c5098f55f3936e9231ba417ace4fa7aa9ebc49233b4bfa88a4103ef6f1202c",
|
|
35
|
+
"schemas/evidence.schema.json": "7dff029c34965e9aeee932028d11bf30d4f3ff76f8137af382bf3d3dc2c0df10",
|
|
36
|
+
"schemas/finding.schema.json": "2cf5f7e29b2544e9dc92069394f5eb2b77bc06e8e3daaccfeea5021d177758a8",
|
|
37
|
+
"schemas/golden-recipe.schema.json": "027d7216e3d000b742ee53d8a5653586aca6a25c69e7b35de4321075ab0206d4",
|
|
31
38
|
"schemas/memory-context.schema.json": "6b9e032c55ba87b2517dd1e7ca0043b8e2439e85fa4a6eac6fc6041f3091e571",
|
|
32
39
|
"schemas/memory-event.schema.json": "4f653610e04fd480325d0ec77a4339bea4690f85e1d2fa0bd4f6b654c813c905",
|
|
33
40
|
"schemas/memory-pattern.schema.json": "df4aae2a3034a7c64ec50b3ae27b6ee9296aac7371c2a1938508834e5f778afe",
|
|
34
|
-
"schemas/provenance.schema.json": "
|
|
35
|
-
"schemas/remediation.schema.json": "
|
|
36
|
-
"schemas/retest.schema.json": "
|
|
37
|
-
"schemas/runtime-evidence.schema.json": "
|
|
38
|
-
"scripts/diff_guard.py": "
|
|
39
|
-
"scripts/finding_scorer.py": "
|
|
40
|
-
"scripts/
|
|
41
|
-
"scripts/
|
|
42
|
-
"scripts/
|
|
41
|
+
"schemas/provenance.schema.json": "8b8e8ddb5c2ca643ae2d5ef6503eceddad3bd4ebe7ae8dd2449090c2ad24e818",
|
|
42
|
+
"schemas/remediation.schema.json": "544904239f871dec9552973e01e09dc1f40dbb8330f20d98c319f3b24031d630",
|
|
43
|
+
"schemas/retest.schema.json": "97c0407ca4365a524020c430912f686f698cc0de90043194621071e9fc681cc7",
|
|
44
|
+
"schemas/runtime-evidence.schema.json": "929d2b094c1cd1f7f9db07be1eba5994e8002477eab3fd24140e1e973fd18cc1",
|
|
45
|
+
"scripts/diff_guard.py": "c2bb88f6e958063c16c06d35eba747ee259bbe79077c7194c3e2eb427195bf70",
|
|
46
|
+
"scripts/finding_scorer.py": "54c574019b31065dd8fe3bd61676657c2db0f0cf7275e308b7bf933536d422b9",
|
|
47
|
+
"scripts/html_reporter.py": "540929c9c79369bc8b6fae58857bb80b6fd492041168f5f1e4ea69ab6d324d84",
|
|
48
|
+
"scripts/manifest_builder.py": "ce351a18ed5092099019d4f469a8cf9c4ae186a426ff9c711ee2c0402755abb9",
|
|
49
|
+
"scripts/memory_engine.py": "05ae1f17e7b4dc9a79aab429427c2cf401846d9e710dd6c3fe317d834b157529",
|
|
50
|
+
"scripts/monorepo_detector.py": "5603674136a5294ebfff89efeca0a546dd4a7deb1d184a2592ff21aff2131f73",
|
|
51
|
+
"scripts/rules_sync.py": "4101b2ca8036ff4f468800b32a8d08898e8640a74d14124af53d454706a62d3a",
|
|
43
52
|
"scripts/run_manager.py": "b576fc3be9929ee6a52e67662e67f801e4e9317c158243582911e10c94a07619",
|
|
44
53
|
"scripts/safety_gate.py": "3379b7534b2590cf563717a448983ad8ed7e8f174f0ad65683d33e8a10f51558",
|
|
45
54
|
"scripts/sarif_exporter.py": "35c66637413afc4b72d5bd426638447c77231d2a8594dce5addceffd4803a20d",
|
|
46
|
-
"scripts/stack_detect.py": "
|
|
55
|
+
"scripts/stack_detect.py": "7848006e3cd6e828f7dbe189a8c9728abd58e021ff02efbc4230ef8ca3444596",
|
|
47
56
|
"skills/torusguard/SKILL.md": "e772e348716aee26e424ec96be5bd6750dbebcefc248bc4dab0df1e6c0e24fcf",
|
|
48
|
-
"skills/torusguard/bootstrap.py": "
|
|
49
|
-
"skills/torusguard/references/auth-and-sessions.md": "
|
|
50
|
-
"skills/torusguard/references/business-logic-and-abuse.md": "
|
|
51
|
-
"skills/torusguard/references/cache-and-sensitive-responses.md": "
|
|
52
|
-
"skills/torusguard/references/client-code-exposure.md": "
|
|
53
|
-
"skills/torusguard/references/
|
|
54
|
-
"skills/torusguard/references/
|
|
55
|
-
"skills/torusguard/references/
|
|
56
|
-
"skills/torusguard/references/
|
|
57
|
-
"skills/torusguard/references/
|
|
58
|
-
"skills/torusguard/references/
|
|
59
|
-
"skills/torusguard/references/
|
|
60
|
-
"skills/torusguard/references/
|
|
61
|
-
"skills/torusguard/references/
|
|
62
|
-
"skills/torusguard/references/
|
|
63
|
-
"skills/torusguard/references/
|
|
64
|
-
"skills/torusguard/references/
|
|
65
|
-
"skills/torusguard/references/
|
|
66
|
-
"skills/torusguard/references/
|
|
67
|
-
"skills/torusguard/references/
|
|
68
|
-
"skills/torusguard/references/
|
|
69
|
-
"skills/torusguard/references/
|
|
70
|
-
"skills/torusguard/references/
|
|
71
|
-
"skills/torusguard/references/
|
|
72
|
-
"skills/torusguard-
|
|
57
|
+
"skills/torusguard/bootstrap.py": "01aaf2d627eeff27b5b7343125cb0a7de09371b157d44e622eae59082b2b8e41",
|
|
58
|
+
"skills/torusguard/references/auth-and-sessions.md": "c3e4b9600cb53fc28c993922dc880accbec5783ac90d5ee98d63b52762d19525",
|
|
59
|
+
"skills/torusguard/references/business-logic-and-abuse.md": "58e87df2864d468af70c1ff39f5d540c687fa846b671457f85046ab2065fe99c",
|
|
60
|
+
"skills/torusguard/references/cache-and-sensitive-responses.md": "81b4a7a08e11dafa4ec58d868c4a35f1f891d0dcdcfbcefaef81e1b9ba94f5a1",
|
|
61
|
+
"skills/torusguard/references/client-code-exposure.md": "b1628410e3dc51990a1653d6d3e3aaefbc2b5f43477b4424b46da6141bfe6984",
|
|
62
|
+
"skills/torusguard/references/csharp-security.md": "d6e267855b08ed4fdff26f3b876f089ae1f90a7ec6546cba7e8173380d9daa9d",
|
|
63
|
+
"skills/torusguard/references/csrf-and-cross-origin.md": "2e5001f9e5668beea29985be59dd7272f85640877b55af49c877f5fb8aa70320",
|
|
64
|
+
"skills/torusguard/references/dependency-and-supply-chain.md": "f54cc745217a8c49b86673794e58fd12e91774e7a2fd66d7e9d27f1a7fde16a8",
|
|
65
|
+
"skills/torusguard/references/django-security.md": "26ea5535ac435e61489df1e381ac62b19e81702edfe095e78c937be93fa15ea7",
|
|
66
|
+
"skills/torusguard/references/drf-security.md": "c6796398317b0f264d89fff598404e126d819e69e1ea0a5129924a5eb2a7af9d",
|
|
67
|
+
"skills/torusguard/references/fastapi-security.md": "45136325e7cc65aa78af848636f6e18fc0e871978599505cff3ac95c5823d3d4",
|
|
68
|
+
"skills/torusguard/references/flask-security.md": "f359ffdb6ca8c60eaccde2767c8177ed1e2d4fd1391d869405026262fda79f25",
|
|
69
|
+
"skills/torusguard/references/frontend-no-db.md": "f0aa4e25c8a144b8a05b0c4c27a4d779e49ba63c4ca6b1cc591ab5a15e7762ba",
|
|
70
|
+
"skills/torusguard/references/go-security.md": "a008606e7698c372140c2c5f5e0ec3c11ac34ae760847650a99c0aee102e6138",
|
|
71
|
+
"skills/torusguard/references/graphql-security.md": "081135fd7709fcbd2ed7bd63452454153e8e42d6b0e1118edac4155b21e180d2",
|
|
72
|
+
"skills/torusguard/references/input-and-injection.md": "dfef3af6162eb5ad9b9f516e25f69827f065b36f238facc51554eeecab4d2038",
|
|
73
|
+
"skills/torusguard/references/java-security.md": "6f27483e271be9d73af0d00fee280a74aeafb08f584cd3313ca349936f779ee6",
|
|
74
|
+
"skills/torusguard/references/mass-assignment-and-property-auth.md": "124c697286476990591d43d5a11a1a65db8b0fa72e2e6cd37c60796d2b2ccf5e",
|
|
75
|
+
"skills/torusguard/references/platform-hardening.md": "b21a2cf735711890982e86ff5c385e7574febcd7011637f35997c6dc203ccc63",
|
|
76
|
+
"skills/torusguard/references/polyglot-security-matrix.md": "d69453814969b5fd33800baa77433b7ae9564264153cddfd45aa0b87756ed919",
|
|
77
|
+
"skills/torusguard/references/python-dependencies.md": "1fc00572c52583ecf38e561add0818298085e7f9bdfb329532a6d78b9ec6ca83",
|
|
78
|
+
"skills/torusguard/references/python-security-overview.md": "a234646fc8ccf77fb84decd2fbb18b057a196807796603d0d453ece8c18397f7",
|
|
79
|
+
"skills/torusguard/references/rate-limit-and-abuse.md": "cbf5776f0ef57a54e76ab3d0d6d5b24d77c1cd4efbc6a24e4c827d8623ea98de",
|
|
80
|
+
"skills/torusguard/references/rust-security.md": "3975f69bb0d983171b521766ca9e0022632acff83439d2f0406599a551702a64",
|
|
81
|
+
"skills/torusguard/references/secrets-and-config.md": "21dac9bb94d1b08f2eef938afa073270f8be54b454dbfaf454347a1503ef8e8e",
|
|
82
|
+
"skills/torusguard/references/sqlalchemy-security.md": "a3671325d4d0dfac95c2f9ef41fa7fccb440400e35dd53bcd0c1984e48626cb2",
|
|
83
|
+
"skills/torusguard/references/ssrf-and-outbound-requests.md": "5ce59ebada2f227b3e0a27f612b59a47801c152d24d2d4d533bee435f32b1b05",
|
|
84
|
+
"skills/torusguard/references/webhook-security.md": "8fd27cce1562a3dfda8d4fae29bef7cfd47a65c1e89c6868cdbcac161ccd2be8",
|
|
85
|
+
"skills/torusguard/references/websocket-security.md": "b5315e49432184c006664436d689d426b7322fc6fbbba2899a9ea5e5bab74c92",
|
|
86
|
+
"skills/torusguard-apply/SKILL.md": "09ddf90b436eae0fd54264dbf3c34f564a4481ec4806e2dcf311bfee5ce44d6b",
|
|
73
87
|
"skills/torusguard-audit/SKILL.md": "f879e280d357ea7f124c647ce39af2b24b79db608c9edd018f26e5312625a8b5",
|
|
74
|
-
"skills/torusguard-authorize/SKILL.md": "
|
|
75
|
-
"skills/torusguard-exploit-check/SKILL.md": "
|
|
76
|
-
"skills/torusguard-full/SKILL.md": "
|
|
88
|
+
"skills/torusguard-authorize/SKILL.md": "689729cfebbf6880869ef4ab1b43657f35c873a782f87a03f26727550f7964d4",
|
|
89
|
+
"skills/torusguard-exploit-check/SKILL.md": "c674040a917d95190e198b5fe386a0f08b00424e2037b814a133fa8bf1449f73",
|
|
90
|
+
"skills/torusguard-full/SKILL.md": "f7da4dbd708b31710bddeb5a1f30e1273b134fee1daae89399a17b596ff0128b",
|
|
77
91
|
"skills/torusguard-harden/SKILL.md": "326fa84bda4832f96b19d73824c3472dfe185247ed3e3db9715dd943d46d9874",
|
|
78
|
-
"skills/torusguard-init/SKILL.md": "
|
|
92
|
+
"skills/torusguard-init/SKILL.md": "534a1a4aff2510dbf7924fe74d7d338ed352f757a23b1c5427b9f758019cd911",
|
|
79
93
|
"skills/torusguard-recheck/SKILL.md": "457b2a1cce064a738fbe43f0dba6b4393f1630a82f60698ea5ebe655ec017e50",
|
|
80
|
-
"skills/torusguard-report/SKILL.md": "
|
|
81
|
-
"skills/torusguard-status/SKILL.md": "
|
|
82
|
-
"skills/torusguard-verify/SKILL.md": "
|
|
83
|
-
"skills/torusguard-web-validate/SKILL.md": "
|
|
94
|
+
"skills/torusguard-report/SKILL.md": "f6f6de3a8b56c4538d02307c5afaf99c508561140cccfe8ea16c2ae87768b64d",
|
|
95
|
+
"skills/torusguard-status/SKILL.md": "23afc632b70b80304952e2559a109d5877f97a048039a818a65b378dc604e19e",
|
|
96
|
+
"skills/torusguard-verify/SKILL.md": "842ca8ca3ad194886605a7fafb98d4309cba695b86a627b24206b5b139eef5c6",
|
|
97
|
+
"skills/torusguard-web-validate/SKILL.md": "b3cd9952601cfe89dbe98765bd61be22b434e5aaf5700751348591919e595ad4",
|
|
84
98
|
"templates/audit-report.template.md": "71149dd05b01a74287a47781fdc71fd2d1b4b70337da303bf78767d0410a6c90",
|
|
85
99
|
"templates/authorization.template.md": "81ef843d42a19412c369f383b787465ac24173c0b14c1f5f211786eab3d10e8b",
|
|
86
100
|
"templates/finding-card.template.md": "8f756edbd3e4139d3da2fb96f35bd2d2b267b33b754f187b590a89584265c1e6",
|
|
87
101
|
"templates/remediation-bundle.template.md": "4d85a540e3a2e74f9b21fc8a2a1072e27ca03e97cd67ca482f529cfe722acc4d",
|
|
88
|
-
"workflows/apply.md": "
|
|
89
|
-
"workflows/audit.md": "
|
|
90
|
-
"workflows/authorize.md": "
|
|
91
|
-
"workflows/exploit-check.md": "
|
|
92
|
-
"workflows/harden.md": "
|
|
93
|
-
"workflows/init.md": "
|
|
102
|
+
"workflows/apply.md": "dc66ef6c59ecf1996d45921ac83ba5dd2503a9f3624c8e6f24568745a072b871",
|
|
103
|
+
"workflows/audit.md": "969df4767b311f6468fb10ad4c98c302feb7112bafa86c14c59c8b9f5d481c89",
|
|
104
|
+
"workflows/authorize.md": "1ac2e3adb367a04bd20b2b6a062f6a65703e4aa6a815fe0affc0697faa433588",
|
|
105
|
+
"workflows/exploit-check.md": "67073930ea86219a4efd54dac4206dfc37775a660ff1b6960ed2bfea0528b4a0",
|
|
106
|
+
"workflows/harden.md": "56d7f8098f19c34bc581a49b5e4bacc42858606ebf1cc35c848bdfaca8744409",
|
|
107
|
+
"workflows/init.md": "d1e6ae9a98c30b2c3b46081c8195f524bcd8d3bc9004562d230b56c704fec02b",
|
|
94
108
|
"workflows/memory.md": "c034f9266380db3c05e9ffed943c2bb4ba73c060507e3508e47b543a035a5873",
|
|
95
|
-
"workflows/recheck.md": "
|
|
96
|
-
"workflows/report.md": "
|
|
97
|
-
"workflows/status.md": "
|
|
98
|
-
"workflows/verify.md": "
|
|
99
|
-
"workflows/web-validate.md": "
|
|
109
|
+
"workflows/recheck.md": "106442712bfb87c6c1c9bc0ed660c6c291d4d6a0a6b860f4f93397440dba08d5",
|
|
110
|
+
"workflows/report.md": "35c7cc44d94ee49d8fea6b75ae7ea524790fd0e6208b5f27b84bc4fdab469b0c",
|
|
111
|
+
"workflows/status.md": "a14a92b8b4c30fdf9e9c073c51de4d0057f43519df03e9661117e62e65ac1d08",
|
|
112
|
+
"workflows/verify.md": "f96e8db92f067395d82f7ef8fd32c7c00e6c41ea1731347aadba2fbaed118cdf",
|
|
113
|
+
"workflows/web-validate.md": "5ef05154671582d95b2d05358f0a4f7ea52fe6ff3d3f238b732b3490925bc7f7"
|
|
100
114
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# TorusGuard Skill Reference: C# & ASP.NET Core Security
|
|
2
|
+
|
|
3
|
+
> **Loaded When:** A project is identified as a C# / .NET application (`*.csproj`, `*.sln`, ASP.NET Core detected).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🛡️ Key Inspection Areas & Rules
|
|
8
|
+
|
|
9
|
+
### 1. Authentication & Authorization
|
|
10
|
+
* `TG-AUTH-001`: Ensure controllers and endpoints have `[Authorize]` attributes.
|
|
11
|
+
* Prohibit unvetted `[AllowAnonymous]` on sensitive business logic or user data endpoints.
|
|
12
|
+
|
|
13
|
+
### 2. Entity Framework Core & SQL Injection
|
|
14
|
+
* `TG-INPUT-002`: Use LINQ expressions or `FromSqlInterpolated` with interpolated string syntax (EF Core converts parameters automatically).
|
|
15
|
+
* Prohibit raw `FromSqlRaw` with un-parameterized string concatenations.
|
|
16
|
+
* `TG-DB-004`: Configure Global Query Filters (`HasQueryFilter(e => e.TenantId == _currentTenant)`) for multi-tenant safety.
|
|
17
|
+
|
|
18
|
+
### 3. Anti-Forgery & TLS
|
|
19
|
+
* `TG-CSRF-001`: Ensure `[ValidateAntiForgeryToken]` or `[AutoValidateAntiforgeryToken]` is applied to POST/PUT/DELETE actions.
|
|
20
|
+
* Prohibit `DangerousAcceptAnyServerCertificateValidator`.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 🛠️ Safe Patterns Summary
|
|
25
|
+
|
|
26
|
+
```csharp
|
|
27
|
+
// Safe Entity Framework Parameterized Query
|
|
28
|
+
var user = await context.Users
|
|
29
|
+
.Where(u => u.Id == userId && u.TenantId == currentTenantId)
|
|
30
|
+
.FirstOrDefaultAsync();
|
|
31
|
+
|
|
32
|
+
// Safe Global Query Filter in DbContext
|
|
33
|
+
modelBuilder.Entity<Invoice>()
|
|
34
|
+
.HasQueryFilter(i => i.TenantId == _tenantProvider.GetTenantId());
|
|
35
|
+
|
|
36
|
+
// Safe Controller Security
|
|
37
|
+
[Authorize]
|
|
38
|
+
[ApiController]
|
|
39
|
+
[Route("api/[controller]")]
|
|
40
|
+
public class InvoicesController : ControllerBase { ... }
|
|
41
|
+
```
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# TorusGuard Skill Reference: Go Security
|
|
2
|
+
|
|
3
|
+
> **Loaded When:** A project is identified as a Go application (`go.mod`, `go.sum`, or Go source files detected).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🛡️ Key Inspection Areas & Rules
|
|
8
|
+
|
|
9
|
+
### 1. Database & SQL Injection
|
|
10
|
+
* `TG-INPUT-002`: Ensure raw queries use parameterized placeholders (`?`, `$1`), never `fmt.Sprintf` or string concatenation.
|
|
11
|
+
* `TG-DB-004`: Enforce tenant isolation in GORM queries (`db.Where("tenant_id = ?", tenantID)`).
|
|
12
|
+
|
|
13
|
+
### 2. TLS & Network Security
|
|
14
|
+
* `TG-DIFF-001`: Prohibit `InsecureSkipVerify: true` in `tls.Config`. Always use valid root CA pools.
|
|
15
|
+
* `TG-SSRF-001`: Validate outbound URLs before issuing `http.Get` or `http.Post`.
|
|
16
|
+
|
|
17
|
+
### 3. Concurrency & Goroutine Safety
|
|
18
|
+
* `TG-BIZ-001`: Ensure context cancellation propagation (`ctx.Done()`) to prevent goroutine leaks.
|
|
19
|
+
* Use mutexes or channels to prevent data races on shared state.
|
|
20
|
+
|
|
21
|
+
### 4. Input Validation & Path Traversal
|
|
22
|
+
* `TG-INPUT-006`: Sanitize file paths with `filepath.Clean` and check `strings.HasPrefix(cleanPath, baseDir)`.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 🛠️ Safe Patterns Summary
|
|
27
|
+
|
|
28
|
+
```go
|
|
29
|
+
// Safe Parameterized Query
|
|
30
|
+
row := db.QueryRowContext(ctx, "SELECT id, email FROM users WHERE id = ? AND tenant_id = ?", userID, tenantID)
|
|
31
|
+
|
|
32
|
+
// Safe GORM Scoping
|
|
33
|
+
var invoice Invoice
|
|
34
|
+
result := db.Where("id = ? AND tenant_id = ?", invoiceID, currentTenantID).First(&invoice)
|
|
35
|
+
|
|
36
|
+
// Safe TLS Client
|
|
37
|
+
tlsConfig := &tls.Config{
|
|
38
|
+
MinVersion: tls.VersionTLS13,
|
|
39
|
+
}
|
|
40
|
+
client := &http.Client{Transport: &http.Transport{TLSClientConfig: tlsConfig}}
|
|
41
|
+
```
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# TorusGuard Skill Reference: Java & Spring Security
|
|
2
|
+
|
|
3
|
+
> **Loaded When:** A project is identified as a Java/Kotlin application (`pom.xml`, `build.gradle`, Spring Boot detected).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🛡️ Key Inspection Areas & Rules
|
|
8
|
+
|
|
9
|
+
### 1. Spring Security & CSRF
|
|
10
|
+
* `TG-CSRF-001`: Prohibit `.csrf().disable()` or `AbstractHttpConfigurer::disable` on state-changing browser routes.
|
|
11
|
+
* `TG-PLATFORM-001`: Avoid `@CrossOrigin(origins = "*")` with `allowCredentials = "true"`.
|
|
12
|
+
|
|
13
|
+
### 2. JPA & Hibernate SQL Injection
|
|
14
|
+
* `TG-INPUT-002`: Use named parameters (`:param`) or `CriteriaBuilder`. Never concatenate strings into JPQL queries.
|
|
15
|
+
* `TG-DB-004`: Enforce tenant isolation via `@Filter` or explicit where clauses.
|
|
16
|
+
|
|
17
|
+
### 3. Insecure Deserialization & XML
|
|
18
|
+
* Prohibit `ObjectInputStream.readObject()` on untrusted input without look-ahead verification.
|
|
19
|
+
* Disable external entity resolution (`setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)`).
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 🛠️ Safe Patterns Summary
|
|
24
|
+
|
|
25
|
+
```java
|
|
26
|
+
// Safe JPA Query
|
|
27
|
+
@Query("SELECT u FROM User u WHERE u.id = :id AND u.tenantId = :tenantId")
|
|
28
|
+
Optional<User> findByIdAndTenantId(@Param("id") Long id, @Param("tenantId") String tenantId);
|
|
29
|
+
|
|
30
|
+
// Safe Spring Security Configuration
|
|
31
|
+
@Bean
|
|
32
|
+
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
|
33
|
+
http
|
|
34
|
+
.authorizeHttpRequests(auth -> auth
|
|
35
|
+
.requestMatchers("/public/**").permitAll()
|
|
36
|
+
.anyRequest().authenticated()
|
|
37
|
+
);
|
|
38
|
+
return http.build();
|
|
39
|
+
}
|
|
40
|
+
```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# TorusGuard Universal Polyglot Security Matrix
|
|
2
|
+
|
|
3
|
+
> **Loaded When:** Any language or framework is detected. Maps universal security invariants across major programming language ecosystems.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🛡️ Cross-Language Invariant Mappings
|
|
8
|
+
|
|
9
|
+
| Rule Family | Python | TypeScript / Node.js | Go | Rust | Java / Kotlin | C# / .NET |
|
|
10
|
+
|---|---|---|---|---|---|---|
|
|
11
|
+
| **TG-SEC (Secrets)** | `os.environ["KEY"]` | `process.env.KEY` | `os.Getenv("KEY")` | `std::env::var("KEY")` | `System.getenv("KEY")` | `Environment.GetEnvironmentVariable()` |
|
|
12
|
+
| **TG-DB (SQL Injection)** | `%s` / ORM bound | `$1` / Prisma / Drizzle | `?` / `$1` / GORM `?` | `sqlx::query!` / Diesel | Named parameters `:param` | `@p0` / `FromSqlInterpolated` |
|
|
13
|
+
| **TG-DB-004 (Tenant Scope)** | `.filter(tenant=...)` | `where: { tenantId }` | `.Where("tenant_id = ?", tid)` | `filter(tenant_id.eq(tid))` | `WHERE e.tenantId = :tid` | `.Where(x => x.TenantId == tid)` |
|
|
14
|
+
| **TG-AUTH (Access Control)** | `@login_required` / Depends | Middleware auth / Guards | Middleware handlers | Tower layer / extractors | `@PreAuthorize` / Spring Sec | `[Authorize]` attributes |
|
|
15
|
+
| **TG-CSRF (Request Forgery)** | CSRF Middleware | SameSite / csurf | Gorilla CSRF | Anti-CSRF token middleware | Spring Security CSRF | `[ValidateAntiForgeryToken]` |
|
|
16
|
+
| **TG-DIFF (Bypass Comments)** | No `# nosec` | No `// nosec` | No `/* nosec */` | No `#![allow(unsafe)]` | No `@SuppressWarnings` | No pragma disable |
|
|
17
|
+
| **TG-DIFF (TLS Verification)** | No `verify=False` | No `rejectUnauthorized:false` | No `InsecureSkipVerify: true` | No `danger_accept_invalid_certs`| No `TrustAllStrategy` | No `DangerousAcceptAny...` |
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 🚀 Polyglot Hardening Rules of Thumb
|
|
22
|
+
|
|
23
|
+
1. **Parameterize Everything:** Never concatenate raw user input into SQL, shell commands, LDAP filters, or template strings, regardless of language.
|
|
24
|
+
2. **Fail Closed on Auth:** Default all endpoints to authenticated; explicitly mark public routes rather than remembering to protect private ones.
|
|
25
|
+
3. **Strict Bounds:** Keep remediation diffs minimal ($\le 35$ additions, $\le 25$ deletions) to ensure auditability across all codebases.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# TorusGuard Skill Reference: Rust Security
|
|
2
|
+
|
|
3
|
+
> **Loaded When:** A project is identified as a Rust application (`Cargo.toml` or `.rs` files detected).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🛡️ Key Inspection Areas & Rules
|
|
8
|
+
|
|
9
|
+
### 1. Memory Safety & Unsafe Blocks
|
|
10
|
+
* `TG-INPUT-003`: Audit and restrict `unsafe { ... }` blocks. Must include a `// SAFETY:` rationale comment.
|
|
11
|
+
* Never disable standard borrow checker lints via `#![allow(unsafe_code)]`.
|
|
12
|
+
|
|
13
|
+
### 2. Database & SQL Queries
|
|
14
|
+
* `TG-INPUT-002`: Use compile-time checked `sqlx::query!` or Diesel query builder methods.
|
|
15
|
+
* `TG-DB-004`: Enforce tenant filtering in queries (`filter(tenant_id.eq(current_tenant_id))`).
|
|
16
|
+
|
|
17
|
+
### 3. Outbound Requests & TLS
|
|
18
|
+
* `TG-DIFF-001`: Prohibit `danger_accept_invalid_certs(true)` in `reqwest::ClientBuilder`.
|
|
19
|
+
* `TG-SSRF-001`: Enforce IP allowlists before dispatching network calls.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 🛠️ Safe Patterns Summary
|
|
24
|
+
|
|
25
|
+
```rust
|
|
26
|
+
// Safe sqlx Parameterized Query
|
|
27
|
+
let user = sqlx::query_as!(
|
|
28
|
+
User,
|
|
29
|
+
"SELECT id, email FROM users WHERE id = $1 AND tenant_id = $2",
|
|
30
|
+
user_id,
|
|
31
|
+
current_tenant_id
|
|
32
|
+
)
|
|
33
|
+
.fetch_one(&pool)
|
|
34
|
+
.await?;
|
|
35
|
+
|
|
36
|
+
// Safe reqwest Client (Strict TLS)
|
|
37
|
+
let client = reqwest::Client::builder()
|
|
38
|
+
.timeout(std::time::Duration::from_secs(10))
|
|
39
|
+
.build()?;
|
|
40
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Retain custom rules directory
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# TorusGuard Custom Rules Directory
|
|
2
|
+
|
|
3
|
+
Place your custom organization-specific, framework-specific, or proprietary library rules here.
|
|
4
|
+
Any markdown files (`*.md`) or JSON files (`*.json`) placed in this directory will be automatically indexed during `/torusguard-audit` and finding scoring.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Example Custom Rule: `TG-CUSTOM-001.md`
|
|
9
|
+
|
|
10
|
+
```markdown
|
|
11
|
+
# TG-CUSTOM-001: Require Organization UUID on All Multi-Tenant Queries
|
|
12
|
+
|
|
13
|
+
**Rule ID:** TG-CUSTOM-001
|
|
14
|
+
**Severity:** High
|
|
15
|
+
**Category:** database-safety
|
|
16
|
+
**Confidence Base:** 85
|
|
17
|
+
|
|
18
|
+
### Description
|
|
19
|
+
Ensure all database operations on multi-tenant tables enforce explicit `org_id` or `tenant_id` boundaries.
|
|
20
|
+
|
|
21
|
+
### Unsafe Pattern
|
|
22
|
+
```python
|
|
23
|
+
db.execute("SELECT * FROM invoices WHERE status = 'paid'")
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Safe Remediation
|
|
27
|
+
```python
|
|
28
|
+
db.execute("SELECT * FROM invoices WHERE status = 'paid' AND org_id = %s", [current_org_id])
|
|
29
|
+
```
|
|
30
|
+
```
|