praxis-sec 1.0.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/LICENSE +21 -0
- package/README.md +170 -0
- package/ai-defense/cost-protection.md +292 -0
- package/ai-defense/llm-security-checklist.md +324 -0
- package/ai-defense/prompt-injection-patterns.js +283 -0
- package/ai-defense/system-prompt-armor.md +327 -0
- package/checklists/launch-day.md +168 -0
- package/cli/agents/abom-generator.js +225 -0
- package/cli/agents/agent-attestation-agent.js +318 -0
- package/cli/agents/agent-config-scanner.js +787 -0
- package/cli/agents/agent-telemetry-agent.js +415 -0
- package/cli/agents/agentic-security-agent.js +296 -0
- package/cli/agents/agentic-supply-chain-agent.js +463 -0
- package/cli/agents/ai-infra-inventory-agent.js +449 -0
- package/cli/agents/api-fuzzer.js +345 -0
- package/cli/agents/auth-bypass-agent.js +348 -0
- package/cli/agents/base-agent.js +280 -0
- package/cli/agents/cicd-scanner.js +300 -0
- package/cli/agents/config-auditor.js +757 -0
- package/cli/agents/deep-analyzer.js +776 -0
- package/cli/agents/endpoint-agent-abuse-agent.js +404 -0
- package/cli/agents/exception-handler-agent.js +187 -0
- package/cli/agents/git-history-scanner.js +169 -0
- package/cli/agents/governance-audits.js +138 -0
- package/cli/agents/hermes-security-agent.js +536 -0
- package/cli/agents/html-reporter.js +1125 -0
- package/cli/agents/index.js +147 -0
- package/cli/agents/injection-tester.js +502 -0
- package/cli/agents/legal-risk-agent.js +328 -0
- package/cli/agents/llm-redteam.js +199 -0
- package/cli/agents/managed-agent-scanner.js +333 -0
- package/cli/agents/mcp-security-agent.js +588 -0
- package/cli/agents/memory-poisoning-agent.js +305 -0
- package/cli/agents/mobile-scanner.js +231 -0
- package/cli/agents/model-file-scanner.js +259 -0
- package/cli/agents/orchestrator.js +355 -0
- package/cli/agents/pii-compliance-agent.js +301 -0
- package/cli/agents/policy-engine.js +229 -0
- package/cli/agents/prompt-injection-prober.js +224 -0
- package/cli/agents/rag-security-agent.js +204 -0
- package/cli/agents/recon-agent.js +207 -0
- package/cli/agents/sbom-generator.js +265 -0
- package/cli/agents/scoring-engine.js +273 -0
- package/cli/agents/ssrf-prober.js +130 -0
- package/cli/agents/stateful-watcher.js +238 -0
- package/cli/agents/supabase-rls-agent.js +154 -0
- package/cli/agents/supply-chain-agent.js +857 -0
- package/cli/agents/swarm-orchestrator.js +200 -0
- package/cli/agents/verifier-agent.js +303 -0
- package/cli/agents/vibe-coding-agent.js +250 -0
- package/cli/bin/praxis.js +866 -0
- package/cli/commands/abom.js +73 -0
- package/cli/commands/agent-fix.js +1245 -0
- package/cli/commands/audit.js +1180 -0
- package/cli/commands/autofix.js +383 -0
- package/cli/commands/baseline.js +193 -0
- package/cli/commands/benchmark.js +327 -0
- package/cli/commands/checklist.js +223 -0
- package/cli/commands/ci.js +403 -0
- package/cli/commands/deps.js +516 -0
- package/cli/commands/diff.js +200 -0
- package/cli/commands/doctor.js +195 -0
- package/cli/commands/env-audit.js +349 -0
- package/cli/commands/fix.js +218 -0
- package/cli/commands/guard.js +396 -0
- package/cli/commands/hooks.js +278 -0
- package/cli/commands/init.js +514 -0
- package/cli/commands/legal.js +158 -0
- package/cli/commands/live-advisories.js +241 -0
- package/cli/commands/mcp.js +660 -0
- package/cli/commands/openclaw.js +386 -0
- package/cli/commands/red-team.js +350 -0
- package/cli/commands/redteam.js +78 -0
- package/cli/commands/remediate.js +797 -0
- package/cli/commands/rotate.js +768 -0
- package/cli/commands/rules.js +196 -0
- package/cli/commands/scan-mcp.js +534 -0
- package/cli/commands/scan-skill.js +588 -0
- package/cli/commands/scan-standard.js +251 -0
- package/cli/commands/scan.js +524 -0
- package/cli/commands/score.js +449 -0
- package/cli/commands/shell.js +514 -0
- package/cli/commands/team-report.js +398 -0
- package/cli/commands/undo.js +161 -0
- package/cli/commands/update-intel.js +126 -0
- package/cli/commands/vibe-check.js +276 -0
- package/cli/commands/watch.js +757 -0
- package/cli/commands/web.js +63 -0
- package/cli/core/ast/guardrail-detector.js +141 -0
- package/cli/core/ast/index.js +22 -0
- package/cli/core/ast/parser.js +676 -0
- package/cli/core/ast/scope-tree.js +287 -0
- package/cli/core/ast/taint-tracker.js +158 -0
- package/cli/core/branding.js +37 -0
- package/cli/core/env.js +38 -0
- package/cli/core/errors.js +61 -0
- package/cli/core/fs.js +62 -0
- package/cli/core/output/compliance.js +90 -0
- package/cli/core/output/html-theme.js +158 -0
- package/cli/core/output/index.js +57 -0
- package/cli/core/output/json.js +48 -0
- package/cli/core/output/sarif.js +240 -0
- package/cli/core/version.js +67 -0
- package/cli/core/web/jobs.js +183 -0
- package/cli/core/web/projects.js +146 -0
- package/cli/core/web/server.js +439 -0
- package/cli/data/atlas-knowledge.json +5640 -0
- package/cli/data/eaa-catalog.json +39 -0
- package/cli/data/known-mcps.json +26 -0
- package/cli/data/probes/prompt-injection-corpus.json +271 -0
- package/cli/data/threat-intel.json +85 -0
- package/cli/data/threatpacks/latest.json +41 -0
- package/cli/hooks/patterns.js +313 -0
- package/cli/hooks/post-tool-use.js +140 -0
- package/cli/hooks/pre-tool-use.js +186 -0
- package/cli/index.js +90 -0
- package/cli/providers/llm-provider.js +766 -0
- package/cli/utils/autofix-rules.js +74 -0
- package/cli/utils/cache-manager.js +310 -0
- package/cli/utils/compliance-map.js +191 -0
- package/cli/utils/entropy.js +132 -0
- package/cli/utils/fix-ledger.js +127 -0
- package/cli/utils/hermes-tool-registry.js +252 -0
- package/cli/utils/intel/cache.js +61 -0
- package/cli/utils/intel/http.js +88 -0
- package/cli/utils/intel/index.js +235 -0
- package/cli/utils/intel/merge.js +229 -0
- package/cli/utils/intel/sources/epss.js +54 -0
- package/cli/utils/intel/sources/ghsa.js +81 -0
- package/cli/utils/intel/sources/gitguardian.js +40 -0
- package/cli/utils/intel/sources/gitleaks.js +101 -0
- package/cli/utils/intel/sources/kev.js +38 -0
- package/cli/utils/intel/sources/nvd.js +84 -0
- package/cli/utils/intel/sources/osv.js +132 -0
- package/cli/utils/intel/sources/phylum.js +44 -0
- package/cli/utils/intel/sources/snyk.js +46 -0
- package/cli/utils/intel/sources/socket.js +69 -0
- package/cli/utils/intel/sources/sonatype.js +84 -0
- package/cli/utils/intel/sources/threatpack.js +69 -0
- package/cli/utils/mcp-trust.js +60 -0
- package/cli/utils/output.js +251 -0
- package/cli/utils/patterns.js +1130 -0
- package/cli/utils/pdf-generator.js +94 -0
- package/cli/utils/plugin-loader.js +364 -0
- package/cli/utils/rule-import.js +228 -0
- package/cli/utils/rule-registry.js +426 -0
- package/cli/utils/scan-fingerprint.js +109 -0
- package/cli/utils/scan-playbook.js +312 -0
- package/cli/utils/score-history.js +119 -0
- package/cli/utils/secrets-verifier.js +247 -0
- package/cli/utils/security-memory.js +296 -0
- package/cli/utils/standards/atlas-knowledge.js +87 -0
- package/cli/utils/standards/index.js +127 -0
- package/cli/utils/standards/sources/avid.js +45 -0
- package/cli/utils/standards/sources/eu-ai-act.js +89 -0
- package/cli/utils/standards/sources/google-saif.js +39 -0
- package/cli/utils/standards/sources/iso-42001.js +94 -0
- package/cli/utils/standards/sources/mitre-atlas.js +54 -0
- package/cli/utils/standards/sources/nist-ai-600-1.js +45 -0
- package/cli/utils/standards/sources/owasp-llm.js +45 -0
- package/cli/utils/standards/sources/owasp-ml.js +45 -0
- package/cli/utils/threat-intel.js +265 -0
- package/configs/firebase/firestore-rules.txt +215 -0
- package/configs/firebase/security-checklist.md +236 -0
- package/configs/firebase/storage-rules.txt +206 -0
- package/configs/gitignore-template +258 -0
- package/configs/nextjs-security-headers.js +220 -0
- package/configs/praxisignore-template +50 -0
- package/configs/supabase/secure-client.ts +225 -0
- package/configs/supabase/security-checklist.md +278 -0
- package/docs/THIRD_PARTY_NOTICES.md +26 -0
- package/docs/THREAT_INTEL.md +292 -0
- package/docs/USAGE.md +1205 -0
- package/docs/design/WEB-UI.md +82 -0
- package/package.json +71 -0
- package/scripts/check-determinism.mjs +119 -0
- package/snippets/README.md +122 -0
- package/snippets/api-security/api-security-checklist.md +412 -0
- package/snippets/api-security/cors-config.ts +322 -0
- package/snippets/api-security/input-validation.ts +430 -0
- package/snippets/auth/jwt-checklist.md +322 -0
- package/snippets/rate-limiting/nextjs-middleware.ts +211 -0
- package/snippets/rate-limiting/upstash-ratelimit.ts +229 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live Advisory Feed
|
|
3
|
+
* ===================
|
|
4
|
+
*
|
|
5
|
+
* Queries the GitHub Advisory Database and OSV.dev API for real-time
|
|
6
|
+
* advisories on your exact dependency versions. Unlike static CVE checks,
|
|
7
|
+
* this catches actively-compromised packages (Axios 1.8.2, LiteLLM 1.82.7)
|
|
8
|
+
* within hours of publication.
|
|
9
|
+
*
|
|
10
|
+
* USAGE:
|
|
11
|
+
* praxis advisories . # Check npm + PyPI deps
|
|
12
|
+
* praxis advisories . --ecosystem npm
|
|
13
|
+
* praxis advisories . --json
|
|
14
|
+
*
|
|
15
|
+
* APIs used:
|
|
16
|
+
* - OSV.dev (https://api.osv.dev) — aggregates GitHub Advisories, PyPI, npm
|
|
17
|
+
* - No API key needed — fully open, rate-limited to 1000 req/min
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import fs from 'fs';
|
|
21
|
+
import path from 'path';
|
|
22
|
+
|
|
23
|
+
// =============================================================================
|
|
24
|
+
// DEPENDENCY EXTRACTION
|
|
25
|
+
// =============================================================================
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Extract package names + versions from project manifests.
|
|
29
|
+
* Returns: [{ name, version, ecosystem, file }]
|
|
30
|
+
*/
|
|
31
|
+
export function extractDependencies(rootPath) {
|
|
32
|
+
const deps = [];
|
|
33
|
+
|
|
34
|
+
// npm / Node.js
|
|
35
|
+
const pkgPath = path.join(rootPath, 'package.json');
|
|
36
|
+
if (fs.existsSync(pkgPath)) {
|
|
37
|
+
try {
|
|
38
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
39
|
+
const allDeps = {
|
|
40
|
+
...(pkg.dependencies || {}),
|
|
41
|
+
...(pkg.devDependencies || {}),
|
|
42
|
+
};
|
|
43
|
+
for (const [name, versionRange] of Object.entries(allDeps)) {
|
|
44
|
+
// Strip semver prefix (^, ~, >=)
|
|
45
|
+
const version = String(versionRange).replace(/^[\^~>=<]+/, '').trim();
|
|
46
|
+
if (/^\d/.test(version)) {
|
|
47
|
+
deps.push({ name, version, ecosystem: 'npm', file: pkgPath });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
} catch { /* skip */ }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Also check package-lock.json for pinned versions (more accurate)
|
|
54
|
+
const lockPath = path.join(rootPath, 'package-lock.json');
|
|
55
|
+
if (fs.existsSync(lockPath)) {
|
|
56
|
+
try {
|
|
57
|
+
const lock = JSON.parse(fs.readFileSync(lockPath, 'utf-8'));
|
|
58
|
+
const packages = lock.packages || {};
|
|
59
|
+
for (const [pkgKey, info] of Object.entries(packages)) {
|
|
60
|
+
if (!pkgKey || pkgKey === '') continue; // root entry
|
|
61
|
+
const name = pkgKey.replace(/^node_modules\//, '');
|
|
62
|
+
if (info.version && /^\d/.test(info.version)) {
|
|
63
|
+
// Only add if not already present from package.json
|
|
64
|
+
if (!deps.find(d => d.name === name && d.ecosystem === 'npm')) {
|
|
65
|
+
deps.push({ name, version: info.version, ecosystem: 'npm', file: lockPath });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
} catch { /* skip */ }
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Python
|
|
73
|
+
const reqPath = path.join(rootPath, 'requirements.txt');
|
|
74
|
+
if (fs.existsSync(reqPath)) {
|
|
75
|
+
try {
|
|
76
|
+
const lines = fs.readFileSync(reqPath, 'utf-8').split('\n');
|
|
77
|
+
for (const line of lines) {
|
|
78
|
+
const m = line.trim().match(/^([\w-]+)==([\d.]+)/);
|
|
79
|
+
if (m) {
|
|
80
|
+
deps.push({ name: m[1], version: m[2], ecosystem: 'PyPI', file: reqPath });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
} catch { /* skip */ }
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Poetry (pyproject.toml)
|
|
87
|
+
const pyprojectPath = path.join(rootPath, 'pyproject.toml');
|
|
88
|
+
if (fs.existsSync(pyprojectPath)) {
|
|
89
|
+
try {
|
|
90
|
+
const content = fs.readFileSync(pyprojectPath, 'utf-8');
|
|
91
|
+
const depSection = content.match(/\[tool\.poetry\.dependencies\]([\s\S]*?)(?:\n\[|$)/);
|
|
92
|
+
if (depSection) {
|
|
93
|
+
const lines = depSection[1].split('\n');
|
|
94
|
+
for (const line of lines) {
|
|
95
|
+
const m = line.match(/^([\w-]+)\s*=\s*"([\d.]+)"/);
|
|
96
|
+
if (m) {
|
|
97
|
+
deps.push({ name: m[1], version: m[2], ecosystem: 'PyPI', file: pyprojectPath });
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
} catch { /* skip */ }
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return deps;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// =============================================================================
|
|
108
|
+
// OSV.DEV API
|
|
109
|
+
// =============================================================================
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Query OSV.dev for known vulnerabilities affecting a specific package version.
|
|
113
|
+
* Uses the batch query endpoint for efficiency.
|
|
114
|
+
*
|
|
115
|
+
* @param {{ name: string, version: string, ecosystem: string }[]} deps
|
|
116
|
+
* @returns {Promise<object[]>} — Array of advisory objects
|
|
117
|
+
*/
|
|
118
|
+
export async function queryOSV(deps) {
|
|
119
|
+
if (deps.length === 0) return [];
|
|
120
|
+
|
|
121
|
+
// OSV batch query supports up to 1000 packages per request
|
|
122
|
+
const batchSize = 1000;
|
|
123
|
+
const allResults = [];
|
|
124
|
+
|
|
125
|
+
for (let i = 0; i < deps.length; i += batchSize) {
|
|
126
|
+
const batch = deps.slice(i, i + batchSize);
|
|
127
|
+
const queries = batch.map(d => ({
|
|
128
|
+
package: { name: d.name, ecosystem: d.ecosystem },
|
|
129
|
+
version: d.version,
|
|
130
|
+
}));
|
|
131
|
+
|
|
132
|
+
try {
|
|
133
|
+
const response = await fetch('https://api.osv.dev/v1/querybatch', {
|
|
134
|
+
method: 'POST',
|
|
135
|
+
headers: { 'Content-Type': 'application/json' },
|
|
136
|
+
body: JSON.stringify({ queries }),
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
if (!response.ok) {
|
|
140
|
+
throw new Error(`OSV API error: HTTP ${response.status}`);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const data = await response.json();
|
|
144
|
+
const results = data.results || [];
|
|
145
|
+
|
|
146
|
+
for (let j = 0; j < results.length; j++) {
|
|
147
|
+
const vulns = results[j].vulns || [];
|
|
148
|
+
for (const vuln of vulns) {
|
|
149
|
+
allResults.push({
|
|
150
|
+
id: vuln.id,
|
|
151
|
+
summary: vuln.summary || '',
|
|
152
|
+
severity: extractSeverity(vuln),
|
|
153
|
+
package: batch[j].name,
|
|
154
|
+
version: batch[j].version,
|
|
155
|
+
ecosystem: batch[j].ecosystem,
|
|
156
|
+
file: deps[i + j].file,
|
|
157
|
+
aliases: vuln.aliases || [],
|
|
158
|
+
published: vuln.published || null,
|
|
159
|
+
modified: vuln.modified || null,
|
|
160
|
+
isMalware: (vuln.id || '').startsWith('MAL-') ||
|
|
161
|
+
(vuln.summary || '').toLowerCase().includes('malicious') ||
|
|
162
|
+
(vuln.summary || '').toLowerCase().includes('malware'),
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
} catch (err) {
|
|
167
|
+
// Network error — return what we have so far
|
|
168
|
+
if (allResults.length === 0) {
|
|
169
|
+
throw new Error(`Failed to reach OSV.dev: ${err.message}. Run with --offline to skip live checks.`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return allResults;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Extract the highest severity from an OSV vulnerability object.
|
|
179
|
+
*/
|
|
180
|
+
function extractSeverity(vuln) {
|
|
181
|
+
// Check database_specific severity first
|
|
182
|
+
if (vuln.database_specific?.severity) {
|
|
183
|
+
return vuln.database_specific.severity.toLowerCase();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Check CVSS in severity array
|
|
187
|
+
const sevEntries = vuln.severity || [];
|
|
188
|
+
for (const entry of sevEntries) {
|
|
189
|
+
if (entry.type === 'CVSS_V3') {
|
|
190
|
+
const score = parseFloat(entry.score) || 0;
|
|
191
|
+
if (score >= 9.0) return 'critical';
|
|
192
|
+
if (score >= 7.0) return 'high';
|
|
193
|
+
if (score >= 4.0) return 'medium';
|
|
194
|
+
return 'low';
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Malware is always critical
|
|
199
|
+
if ((vuln.id || '').startsWith('MAL-')) return 'critical';
|
|
200
|
+
|
|
201
|
+
return 'medium';
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// =============================================================================
|
|
205
|
+
// MAIN COMMAND
|
|
206
|
+
// =============================================================================
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Run the live advisory check.
|
|
210
|
+
* Returns findings in praxis standard format.
|
|
211
|
+
*/
|
|
212
|
+
export async function runLiveAdvisories(rootPath, options = {}) {
|
|
213
|
+
const deps = extractDependencies(rootPath);
|
|
214
|
+
|
|
215
|
+
if (deps.length === 0) {
|
|
216
|
+
return { advisories: [], deps: 0, checked: 0 };
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Filter by ecosystem if requested
|
|
220
|
+
const filtered = options.ecosystem
|
|
221
|
+
? deps.filter(d => d.ecosystem.toLowerCase() === options.ecosystem.toLowerCase())
|
|
222
|
+
: deps;
|
|
223
|
+
|
|
224
|
+
const advisories = await queryOSV(filtered);
|
|
225
|
+
|
|
226
|
+
// Sort: malware first, then by severity
|
|
227
|
+
const sevOrder = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
228
|
+
advisories.sort((a, b) => {
|
|
229
|
+
if (a.isMalware && !b.isMalware) return -1;
|
|
230
|
+
if (!a.isMalware && b.isMalware) return 1;
|
|
231
|
+
return (sevOrder[a.severity] || 2) - (sevOrder[b.severity] || 2);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
return {
|
|
235
|
+
advisories,
|
|
236
|
+
deps: filtered.length,
|
|
237
|
+
checked: filtered.length,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export default { extractDependencies, queryOSV, runLiveAdvisories };
|