pqaudit 0.1.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 +180 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +69 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/reporter/cbom.d.ts +8 -0
- package/dist/reporter/cbom.d.ts.map +1 -0
- package/dist/reporter/cbom.js +153 -0
- package/dist/reporter/cbom.js.map +1 -0
- package/dist/reporter/json.d.ts +3 -0
- package/dist/reporter/json.d.ts.map +1 -0
- package/dist/reporter/json.js +4 -0
- package/dist/reporter/json.js.map +1 -0
- package/dist/reporter/sarif.d.ts +7 -0
- package/dist/reporter/sarif.d.ts.map +1 -0
- package/dist/reporter/sarif.js +91 -0
- package/dist/reporter/sarif.js.map +1 -0
- package/dist/reporter/text.d.ts +3 -0
- package/dist/reporter/text.d.ts.map +1 -0
- package/dist/reporter/text.js +84 -0
- package/dist/reporter/text.js.map +1 -0
- package/dist/scanner/dependency-scanner.d.ts +3 -0
- package/dist/scanner/dependency-scanner.d.ts.map +1 -0
- package/dist/scanner/dependency-scanner.js +133 -0
- package/dist/scanner/dependency-scanner.js.map +1 -0
- package/dist/scanner/engine.d.ts +3 -0
- package/dist/scanner/engine.d.ts.map +1 -0
- package/dist/scanner/engine.js +109 -0
- package/dist/scanner/engine.js.map +1 -0
- package/dist/scanner/file-scanner.d.ts +5 -0
- package/dist/scanner/file-scanner.d.ts.map +1 -0
- package/dist/scanner/file-scanner.js +163 -0
- package/dist/scanner/file-scanner.js.map +1 -0
- package/dist/scanner/rules.d.ts +4 -0
- package/dist/scanner/rules.d.ts.map +1 -0
- package/dist/scanner/rules.js +25 -0
- package/dist/scanner/rules.js.map +1 -0
- package/dist/types.d.ts +102 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/package.json +62 -0
- package/rules/crypto-patterns.yaml +350 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 PQCWorld
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# pqaudit
|
|
2
|
+
|
|
3
|
+
Scan codebases for quantum-vulnerable cryptography. Get a clear picture of what needs to migrate before [Q-Day](https://en.wikipedia.org/wiki/Q-day).
|
|
4
|
+
|
|
5
|
+
pqaudit detects usage of RSA, ECDSA, Ed25519, ECDH, DH, and other algorithms broken by Shor's algorithm. It also identifies already-migrated PQC usage (ML-KEM, ML-DSA, SLH-DSA) so you can track migration progress. Output as human-readable text, JSON, [CycloneDX CBOM](https://cyclonedx.org/capabilities/cbom/), or [SARIF](https://sarifweb.azurewebsites.net/) for GitHub Code Scanning.
|
|
6
|
+
|
|
7
|
+
## Why now
|
|
8
|
+
|
|
9
|
+
On March 31, 2026, Google published research showing that breaking ECDSA-256 requires [20x fewer qubits than previously estimated](https://research.google/blog/safeguarding-cryptocurrency-by-disclosing-quantum-vulnerabilities-responsibly/) — roughly 1,200 logical qubits and under 500,000 physical qubits. NSA's CNSA 2.0 mandates PQC for new national security systems by 2027. The migration window is open but closing.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx pqaudit ./my-project
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Or install globally:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install -g pqaudit
|
|
21
|
+
pqaudit ./my-project
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Scan current directory, human-readable output
|
|
28
|
+
pqaudit .
|
|
29
|
+
|
|
30
|
+
# Only show critical and high findings
|
|
31
|
+
pqaudit ./src --severity high
|
|
32
|
+
|
|
33
|
+
# Generate CycloneDX CBOM
|
|
34
|
+
pqaudit . --format cbom --output cbom.json
|
|
35
|
+
|
|
36
|
+
# Generate SARIF for GitHub Code Scanning
|
|
37
|
+
pqaudit . --format sarif --output results.sarif
|
|
38
|
+
|
|
39
|
+
# CI mode — exit code 1 if critical/high findings exist
|
|
40
|
+
pqaudit . --ci
|
|
41
|
+
|
|
42
|
+
# Skip dependency scanning
|
|
43
|
+
pqaudit . --no-deps
|
|
44
|
+
|
|
45
|
+
# Use custom rules
|
|
46
|
+
pqaudit . --rules ./my-rules.yaml
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Example output
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
pqaudit — Post-Quantum Cryptography Readiness Scanner
|
|
53
|
+
Scanned: ./my-project
|
|
54
|
+
Date: 2026-04-01T00:00:00.000Z
|
|
55
|
+
|
|
56
|
+
NOT PQC READY — Quantum-vulnerable cryptography detected
|
|
57
|
+
|
|
58
|
+
Files scanned: 65 | Findings: 18
|
|
59
|
+
Critical: 12 High: 2 Medium: 1 Low: 0 Safe: 3
|
|
60
|
+
|
|
61
|
+
--- CRITICAL (12) ---
|
|
62
|
+
|
|
63
|
+
[!!] Ed25519 — Ed25519 signatures — elliptic curve, vulnerable to Shor's algorithm
|
|
64
|
+
src/crypto/signing.ts:14
|
|
65
|
+
> import { sign, verify } from "@noble/ed25519";
|
|
66
|
+
Fix: ML-DSA-65 (FIPS 204) or hybrid Ed25519+ML-DSA-65
|
|
67
|
+
Confidence: 90% | Effort: moderate | Via: regex
|
|
68
|
+
...
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## What it detects
|
|
72
|
+
|
|
73
|
+
### Critical (quantum-vulnerable — must migrate)
|
|
74
|
+
|
|
75
|
+
| Algorithm | Threat | Replacement |
|
|
76
|
+
|-----------|--------|-------------|
|
|
77
|
+
| RSA (any key size) | Shor's algorithm | ML-KEM-768 / ML-DSA-65 |
|
|
78
|
+
| ECDSA / Ed25519 | Shor's on elliptic curves | ML-DSA-65 (FIPS 204) |
|
|
79
|
+
| ECDH / X25519 / DH | Shor's on key exchange | ML-KEM-768 (FIPS 203) |
|
|
80
|
+
| DSA | Shor's algorithm | ML-DSA-65 (FIPS 204) |
|
|
81
|
+
|
|
82
|
+
### High (weakened by quantum)
|
|
83
|
+
|
|
84
|
+
| Algorithm | Threat | Replacement |
|
|
85
|
+
|-----------|--------|-------------|
|
|
86
|
+
| AES-128 | Grover reduces to 64-bit | AES-256 |
|
|
87
|
+
|
|
88
|
+
### Safe (already quantum-resistant)
|
|
89
|
+
|
|
90
|
+
ML-KEM (Kyber), ML-DSA (Dilithium), SLH-DSA (SPHINCS+), AES-256, ChaCha20-Poly1305, SHA-256, SHA-3
|
|
91
|
+
|
|
92
|
+
## Output formats
|
|
93
|
+
|
|
94
|
+
### CycloneDX CBOM
|
|
95
|
+
|
|
96
|
+
Generates a [Cryptographic Bill of Materials](https://cyclonedx.org/capabilities/cbom/) conforming to CycloneDX 1.6. Each cryptographic finding becomes a `crypto-asset` component with `cryptoProperties`, NIST quantum security levels, and evidence locations.
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
pqaudit . --format cbom --output cbom.json
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### SARIF (GitHub Code Scanning)
|
|
103
|
+
|
|
104
|
+
Generates SARIF 2.1.0 output compatible with GitHub's code scanning. Upload via `github/codeql-action/upload-sarif`.
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
pqaudit . --format sarif --output results.sarif
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## GitHub Action
|
|
111
|
+
|
|
112
|
+
```yaml
|
|
113
|
+
name: PQC Audit
|
|
114
|
+
on: [push, pull_request]
|
|
115
|
+
jobs:
|
|
116
|
+
pqaudit:
|
|
117
|
+
runs-on: ubuntu-latest
|
|
118
|
+
steps:
|
|
119
|
+
- uses: actions/checkout@v4
|
|
120
|
+
- uses: actions/setup-node@v4
|
|
121
|
+
with:
|
|
122
|
+
node-version: "20"
|
|
123
|
+
- run: npx pqaudit . --format sarif --output pqaudit.sarif --ci
|
|
124
|
+
- uses: github/codeql-action/upload-sarif@v3
|
|
125
|
+
if: always()
|
|
126
|
+
with:
|
|
127
|
+
sarif_file: pqaudit.sarif
|
|
128
|
+
category: pqaudit
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Dependency scanning
|
|
132
|
+
|
|
133
|
+
pqaudit checks `package.json` for known cryptographic libraries and flags quantum-vulnerable dependencies:
|
|
134
|
+
|
|
135
|
+
- `@noble/ed25519`, `@noble/secp256k1` — ECC signatures
|
|
136
|
+
- `tweetnacl`, `elliptic`, `node-rsa` — various asymmetric crypto
|
|
137
|
+
- `jsonwebtoken`, `jose` — JWT libraries (typically RSA/ECDSA)
|
|
138
|
+
- `@solana/web3.js`, `ethers`, `web3` — blockchain (Ed25519/secp256k1)
|
|
139
|
+
- `@noble/post-quantum` — flagged as **safe**
|
|
140
|
+
|
|
141
|
+
## Custom rules
|
|
142
|
+
|
|
143
|
+
Rules are defined in YAML:
|
|
144
|
+
|
|
145
|
+
```yaml
|
|
146
|
+
- id: MY_CUSTOM_RULE
|
|
147
|
+
description: "Custom quantum-vulnerable pattern"
|
|
148
|
+
severity: critical
|
|
149
|
+
category: signature
|
|
150
|
+
algorithm: MyAlgo
|
|
151
|
+
replacement: ML-DSA-65
|
|
152
|
+
effort: complex
|
|
153
|
+
languages: ["javascript", "typescript"]
|
|
154
|
+
patterns:
|
|
155
|
+
- "myVulnerableFunction\\("
|
|
156
|
+
- "import.*myVulnerableLib"
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Detection methods
|
|
160
|
+
|
|
161
|
+
Currently implements L0 (regex) detection. Planned:
|
|
162
|
+
|
|
163
|
+
- **L1**: AST-based analysis via tree-sitter for semantic understanding and fewer false positives
|
|
164
|
+
- **L2**: Data flow / taint analysis for tracing cryptographic data through call chains
|
|
165
|
+
- **Network scanning**: TLS/SSH endpoint analysis
|
|
166
|
+
- **More languages**: Cargo.toml, build.gradle, requirements.txt dependency scanning
|
|
167
|
+
|
|
168
|
+
## References
|
|
169
|
+
|
|
170
|
+
- [NIST FIPS 203 — ML-KEM](https://csrc.nist.gov/pubs/fips/203/final)
|
|
171
|
+
- [NIST FIPS 204 — ML-DSA](https://csrc.nist.gov/pubs/fips/204/final)
|
|
172
|
+
- [NIST FIPS 205 — SLH-DSA](https://csrc.nist.gov/pubs/fips/205/final)
|
|
173
|
+
- [NSA CNSA 2.0 Timeline](https://media.defense.gov/2022/Sep/07/2003071836/-1/-1/0/CSI_CNSA_2.0_FAQ_.PDF)
|
|
174
|
+
- [CycloneDX CBOM Specification](https://cyclonedx.org/capabilities/cbom/)
|
|
175
|
+
- [Google PQC Migration Timeline (March 2026)](https://blog.google/innovation-and-ai/technology/safety-security/cryptography-migration-timeline/)
|
|
176
|
+
- [Google Quantum Vulnerability Research (March 2026)](https://research.google/blog/safeguarding-cryptocurrency-by-disclosing-quantum-vulnerabilities-responsibly/)
|
|
177
|
+
|
|
178
|
+
## License
|
|
179
|
+
|
|
180
|
+
MIT
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { writeFileSync } from "node:fs";
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
import { scan } from "./scanner/engine.js";
|
|
5
|
+
import { formatText } from "./reporter/text.js";
|
|
6
|
+
import { formatJson } from "./reporter/json.js";
|
|
7
|
+
import { formatCbom } from "./reporter/cbom.js";
|
|
8
|
+
import { formatSarif } from "./reporter/sarif.js";
|
|
9
|
+
const program = new Command();
|
|
10
|
+
program
|
|
11
|
+
.name("pqaudit")
|
|
12
|
+
.description("Scan codebases for quantum-vulnerable cryptography and generate a Cryptographic Bill of Materials (CBOM)")
|
|
13
|
+
.version("0.1.0")
|
|
14
|
+
.argument("[target]", "Directory to scan", ".")
|
|
15
|
+
.option("-f, --format <format>", "Output format: text, json, cbom, sarif", "text")
|
|
16
|
+
.option("-o, --output <file>", "Write output to file instead of stdout")
|
|
17
|
+
.option("-s, --severity <level>", "Minimum severity to report: critical, high, medium, low, safe", "safe")
|
|
18
|
+
.option("--no-deps", "Skip dependency scanning")
|
|
19
|
+
.option("--include <patterns...>", "File patterns to include")
|
|
20
|
+
.option("--exclude <patterns...>", "Additional file patterns to exclude")
|
|
21
|
+
.option("--rules <dir>", "Path to custom rules YAML file")
|
|
22
|
+
.option("--ci", "Exit with code 1 if critical/high findings exist")
|
|
23
|
+
.action(async (target, opts) => {
|
|
24
|
+
const config = {
|
|
25
|
+
target,
|
|
26
|
+
format: opts.format,
|
|
27
|
+
output: opts.output,
|
|
28
|
+
minSeverity: opts.severity,
|
|
29
|
+
scanDependencies: opts.deps !== false,
|
|
30
|
+
include: opts.include,
|
|
31
|
+
exclude: opts.exclude,
|
|
32
|
+
rulesDir: opts.rules,
|
|
33
|
+
};
|
|
34
|
+
const result = await scan(config);
|
|
35
|
+
let output;
|
|
36
|
+
switch (config.format) {
|
|
37
|
+
case "json":
|
|
38
|
+
output = formatJson(result);
|
|
39
|
+
break;
|
|
40
|
+
case "cbom":
|
|
41
|
+
output = formatCbom(result);
|
|
42
|
+
break;
|
|
43
|
+
case "sarif":
|
|
44
|
+
output = formatSarif(result);
|
|
45
|
+
break;
|
|
46
|
+
case "text":
|
|
47
|
+
default:
|
|
48
|
+
output = formatText(result);
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
if (config.output) {
|
|
52
|
+
writeFileSync(config.output, output, "utf-8");
|
|
53
|
+
if (config.format === "text") {
|
|
54
|
+
console.log(`Results written to ${config.output}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
console.log(output);
|
|
59
|
+
}
|
|
60
|
+
// CI mode: exit 1 if critical or high findings
|
|
61
|
+
if (opts.ci) {
|
|
62
|
+
const { critical, high } = result.summary.bySeverity;
|
|
63
|
+
if (critical > 0 || high > 0) {
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
program.parse();
|
|
69
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { scan } from "./scanner/engine.js";
|
|
2
|
+
export { formatText } from "./reporter/text.js";
|
|
3
|
+
export { formatJson } from "./reporter/json.js";
|
|
4
|
+
export { formatCbom } from "./reporter/cbom.js";
|
|
5
|
+
export { formatSarif } from "./reporter/sarif.js";
|
|
6
|
+
export type * from "./types.js";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,mBAAmB,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { scan } from "./scanner/engine.js";
|
|
2
|
+
export { formatText } from "./reporter/text.js";
|
|
3
|
+
export { formatJson } from "./reporter/json.js";
|
|
4
|
+
export { formatCbom } from "./reporter/cbom.js";
|
|
5
|
+
export { formatSarif } from "./reporter/sarif.js";
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ScanResult } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Generate a CycloneDX 1.6 CBOM (Cryptographic Bill of Materials)
|
|
4
|
+
*
|
|
5
|
+
* Spec: https://cyclonedx.org/capabilities/cbom/
|
|
6
|
+
*/
|
|
7
|
+
export declare function formatCbom(result: ScanResult): string;
|
|
8
|
+
//# sourceMappingURL=cbom.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cbom.d.ts","sourceRoot":"","sources":["../../src/reporter/cbom.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAW,UAAU,EAAE,MAAM,aAAa,CAAC;AAEvD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CA+BrD"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
/**
|
|
3
|
+
* Generate a CycloneDX 1.6 CBOM (Cryptographic Bill of Materials)
|
|
4
|
+
*
|
|
5
|
+
* Spec: https://cyclonedx.org/capabilities/cbom/
|
|
6
|
+
*/
|
|
7
|
+
export function formatCbom(result) {
|
|
8
|
+
const components = result.findings.map(findingToComponent);
|
|
9
|
+
const cbom = {
|
|
10
|
+
bomFormat: "CycloneDX",
|
|
11
|
+
specVersion: "1.6",
|
|
12
|
+
serialNumber: `urn:uuid:${randomUUID()}`,
|
|
13
|
+
version: 1,
|
|
14
|
+
metadata: {
|
|
15
|
+
timestamp: result.timestamp,
|
|
16
|
+
tools: {
|
|
17
|
+
components: [
|
|
18
|
+
{
|
|
19
|
+
type: "application",
|
|
20
|
+
name: "pqaudit",
|
|
21
|
+
version: "0.1.0",
|
|
22
|
+
description: "Post-quantum cryptography readiness scanner",
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
},
|
|
26
|
+
component: {
|
|
27
|
+
type: "application",
|
|
28
|
+
name: result.target,
|
|
29
|
+
"bom-ref": "target",
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
components,
|
|
33
|
+
};
|
|
34
|
+
return JSON.stringify(cbom, null, 2);
|
|
35
|
+
}
|
|
36
|
+
function findingToComponent(finding) {
|
|
37
|
+
const bomRef = `crypto-${finding.ruleId}-${finding.location.file.replace(/[^a-zA-Z0-9]/g, "-")}-${finding.location.line ?? 0}`;
|
|
38
|
+
return {
|
|
39
|
+
type: "crypto-asset",
|
|
40
|
+
"bom-ref": bomRef,
|
|
41
|
+
name: finding.algorithm,
|
|
42
|
+
description: finding.description,
|
|
43
|
+
cryptoProperties: {
|
|
44
|
+
assetType: categoryToAssetType(finding.category),
|
|
45
|
+
algorithmProperties: {
|
|
46
|
+
primitive: categoryToPrimitive(finding.category),
|
|
47
|
+
variant: finding.algorithm,
|
|
48
|
+
cryptoFunctions: [categoryToFunction(finding.category)],
|
|
49
|
+
},
|
|
50
|
+
classicalSecurityLevel: severityToSecurityLevel(finding.severity),
|
|
51
|
+
nistQuantumSecurityLevel: severityToNistLevel(finding.severity),
|
|
52
|
+
},
|
|
53
|
+
evidence: {
|
|
54
|
+
occurrences: [
|
|
55
|
+
{
|
|
56
|
+
location: finding.location.file,
|
|
57
|
+
line: finding.location.line,
|
|
58
|
+
offset: finding.location.column,
|
|
59
|
+
symbol: finding.location.snippet,
|
|
60
|
+
additionalContext: finding.replacement
|
|
61
|
+
? `Recommended replacement: ${finding.replacement}`
|
|
62
|
+
: undefined,
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
properties: [
|
|
67
|
+
{ name: "pqaudit:severity", value: finding.severity },
|
|
68
|
+
{ name: "pqaudit:confidence", value: String(finding.confidence) },
|
|
69
|
+
{ name: "pqaudit:effort", value: finding.effort },
|
|
70
|
+
{ name: "pqaudit:detectionMethod", value: finding.detectionMethod },
|
|
71
|
+
...(finding.replacement
|
|
72
|
+
? [{ name: "pqaudit:replacement", value: finding.replacement }]
|
|
73
|
+
: []),
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function categoryToAssetType(category) {
|
|
78
|
+
switch (category) {
|
|
79
|
+
case "kem":
|
|
80
|
+
return "algorithm";
|
|
81
|
+
case "signature":
|
|
82
|
+
return "algorithm";
|
|
83
|
+
case "hash":
|
|
84
|
+
return "algorithm";
|
|
85
|
+
case "symmetric":
|
|
86
|
+
return "algorithm";
|
|
87
|
+
case "protocol":
|
|
88
|
+
return "protocol";
|
|
89
|
+
case "kdf":
|
|
90
|
+
return "algorithm";
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function categoryToPrimitive(category) {
|
|
94
|
+
switch (category) {
|
|
95
|
+
case "kem":
|
|
96
|
+
return "pke";
|
|
97
|
+
case "signature":
|
|
98
|
+
return "signature";
|
|
99
|
+
case "hash":
|
|
100
|
+
return "hash";
|
|
101
|
+
case "symmetric":
|
|
102
|
+
return "ae";
|
|
103
|
+
case "protocol":
|
|
104
|
+
return "other";
|
|
105
|
+
case "kdf":
|
|
106
|
+
return "kdf";
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function categoryToFunction(category) {
|
|
110
|
+
switch (category) {
|
|
111
|
+
case "kem":
|
|
112
|
+
return "encapsulate";
|
|
113
|
+
case "signature":
|
|
114
|
+
return "sign";
|
|
115
|
+
case "hash":
|
|
116
|
+
return "digest";
|
|
117
|
+
case "symmetric":
|
|
118
|
+
return "encrypt";
|
|
119
|
+
case "protocol":
|
|
120
|
+
return "other";
|
|
121
|
+
case "kdf":
|
|
122
|
+
return "keygen";
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function severityToSecurityLevel(severity) {
|
|
126
|
+
switch (severity) {
|
|
127
|
+
case "critical":
|
|
128
|
+
return 0; // Broken by quantum
|
|
129
|
+
case "high":
|
|
130
|
+
return 64; // Reduced by Grover
|
|
131
|
+
case "medium":
|
|
132
|
+
return 0; // Already broken classically
|
|
133
|
+
case "low":
|
|
134
|
+
return 128;
|
|
135
|
+
case "safe":
|
|
136
|
+
return 128; // Post-quantum safe
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function severityToNistLevel(severity) {
|
|
140
|
+
switch (severity) {
|
|
141
|
+
case "critical":
|
|
142
|
+
return 0;
|
|
143
|
+
case "high":
|
|
144
|
+
return 1;
|
|
145
|
+
case "medium":
|
|
146
|
+
return 0;
|
|
147
|
+
case "low":
|
|
148
|
+
return 3;
|
|
149
|
+
case "safe":
|
|
150
|
+
return 3;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=cbom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cbom.js","sourceRoot":"","sources":["../../src/reporter/cbom.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/reporter/json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAErD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/reporter/json.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,UAAU,CAAC,MAAkB;IAC3C,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ScanResult } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Generate SARIF output for GitHub Code Scanning integration
|
|
4
|
+
* Spec: https://sarifweb.azurewebsites.net/
|
|
5
|
+
*/
|
|
6
|
+
export declare function formatSarif(result: ScanResult): string;
|
|
7
|
+
//# sourceMappingURL=sarif.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sarif.d.ts","sourceRoot":"","sources":["../../src/reporter/sarif.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,UAAU,EAAY,MAAM,aAAa,CAAC;AAEjE;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CA+DtD"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate SARIF output for GitHub Code Scanning integration
|
|
3
|
+
* Spec: https://sarifweb.azurewebsites.net/
|
|
4
|
+
*/
|
|
5
|
+
export function formatSarif(result) {
|
|
6
|
+
const rules = dedupeRules(result.findings);
|
|
7
|
+
const sarif = {
|
|
8
|
+
$schema: "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/main/sarif-2.1/schema/sarif-schema-2.1.0.json",
|
|
9
|
+
version: "2.1.0",
|
|
10
|
+
runs: [
|
|
11
|
+
{
|
|
12
|
+
tool: {
|
|
13
|
+
driver: {
|
|
14
|
+
name: "pqaudit",
|
|
15
|
+
version: "0.1.0",
|
|
16
|
+
informationUri: "https://github.com/PQCWorld/pqaudit",
|
|
17
|
+
rules: rules.map((r) => ({
|
|
18
|
+
id: r.ruleId,
|
|
19
|
+
shortDescription: { text: r.algorithm },
|
|
20
|
+
fullDescription: { text: r.description },
|
|
21
|
+
defaultConfiguration: {
|
|
22
|
+
level: severityToSarifLevel(r.severity),
|
|
23
|
+
},
|
|
24
|
+
help: {
|
|
25
|
+
text: r.replacement
|
|
26
|
+
? `Replace with: ${r.replacement}`
|
|
27
|
+
: "No migration needed",
|
|
28
|
+
},
|
|
29
|
+
properties: {
|
|
30
|
+
tags: ["security", "cryptography", "post-quantum"],
|
|
31
|
+
},
|
|
32
|
+
})),
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
results: result.findings
|
|
36
|
+
.filter((f) => f.severity !== "safe")
|
|
37
|
+
.map((f) => ({
|
|
38
|
+
ruleId: f.ruleId,
|
|
39
|
+
level: severityToSarifLevel(f.severity),
|
|
40
|
+
message: {
|
|
41
|
+
text: `${f.algorithm}: ${f.description}${f.replacement ? `. Replace with: ${f.replacement}` : ""}`,
|
|
42
|
+
},
|
|
43
|
+
locations: [
|
|
44
|
+
{
|
|
45
|
+
physicalLocation: {
|
|
46
|
+
artifactLocation: {
|
|
47
|
+
uri: f.location.file,
|
|
48
|
+
},
|
|
49
|
+
region: {
|
|
50
|
+
startLine: f.location.line ?? 1,
|
|
51
|
+
startColumn: f.location.column ?? 1,
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
properties: {
|
|
57
|
+
confidence: f.confidence,
|
|
58
|
+
effort: f.effort,
|
|
59
|
+
},
|
|
60
|
+
})),
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
};
|
|
64
|
+
return JSON.stringify(sarif, null, 2);
|
|
65
|
+
}
|
|
66
|
+
function severityToSarifLevel(severity) {
|
|
67
|
+
switch (severity) {
|
|
68
|
+
case "critical":
|
|
69
|
+
return "error";
|
|
70
|
+
case "high":
|
|
71
|
+
return "error";
|
|
72
|
+
case "medium":
|
|
73
|
+
return "warning";
|
|
74
|
+
case "low":
|
|
75
|
+
return "note";
|
|
76
|
+
case "safe":
|
|
77
|
+
return "note";
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function dedupeRules(findings) {
|
|
81
|
+
const seen = new Set();
|
|
82
|
+
const unique = [];
|
|
83
|
+
for (const f of findings) {
|
|
84
|
+
if (!seen.has(f.ruleId)) {
|
|
85
|
+
seen.add(f.ruleId);
|
|
86
|
+
unique.push(f);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return unique;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=sarif.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sarif.js","sourceRoot":"","sources":["../../src/reporter/sarif.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/reporter/text.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAW,UAAU,EAAY,MAAM,aAAa,CAAC;AAkBjE,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAwErD"}
|