flareguard 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.
Files changed (64) hide show
  1. package/Cargo.lock +2962 -0
  2. package/Cargo.toml +66 -0
  3. package/LICENSE +21 -0
  4. package/README.md +115 -0
  5. package/bin/flareguard.js +78 -0
  6. package/package.json +50 -0
  7. package/scripts/postinstall.mjs +83 -0
  8. package/src/bindings/ast_scanner.rs +950 -0
  9. package/src/bindings/cli.rs +49 -0
  10. package/src/bindings/jsonc.rs +166 -0
  11. package/src/bindings/mod.rs +7 -0
  12. package/src/bindings/reporter.rs +328 -0
  13. package/src/bindings/types.rs +129 -0
  14. package/src/bindings/validator.rs +227 -0
  15. package/src/bindings/wrangler.rs +647 -0
  16. package/src/cli.rs +77 -0
  17. package/src/lib.rs +7 -0
  18. package/src/main.rs +451 -0
  19. package/src/origin/cli.rs +92 -0
  20. package/src/origin/cloudflare.rs +170 -0
  21. package/src/origin/confidence.rs +320 -0
  22. package/src/origin/crtsh.rs +144 -0
  23. package/src/origin/dns.rs +177 -0
  24. package/src/origin/enumerator.rs +271 -0
  25. package/src/origin/error.rs +19 -0
  26. package/src/origin/mock.rs +320 -0
  27. package/src/origin/mod.rs +19 -0
  28. package/src/origin/models.rs +167 -0
  29. package/src/origin/prober.rs +260 -0
  30. package/src/origin/remediation.rs +73 -0
  31. package/src/origin/report.rs +625 -0
  32. package/src/origin/scanner.rs +217 -0
  33. package/src/secrets/cli.rs +94 -0
  34. package/src/secrets/env_parser.rs +464 -0
  35. package/src/secrets/ignore.rs +139 -0
  36. package/src/secrets/mod.rs +14 -0
  37. package/src/secrets/report/json_format.rs +97 -0
  38. package/src/secrets/report/mod.rs +48 -0
  39. package/src/secrets/report/sarif.rs +225 -0
  40. package/src/secrets/report/text.rs +105 -0
  41. package/src/secrets/rules/builtin.rs +280 -0
  42. package/src/secrets/rules/entropy.rs +66 -0
  43. package/src/secrets/rules/mod.rs +7 -0
  44. package/src/secrets/rules/types.rs +183 -0
  45. package/src/secrets/scanner.rs +444 -0
  46. package/src/zone/cli.rs +111 -0
  47. package/src/zone/client/cf_client.rs +405 -0
  48. package/src/zone/client/mod.rs +5 -0
  49. package/src/zone/client/provider.rs +12 -0
  50. package/src/zone/mock_data.rs +481 -0
  51. package/src/zone/mod.rs +125 -0
  52. package/src/zone/models/audit.rs +194 -0
  53. package/src/zone/models/cloudflare.rs +252 -0
  54. package/src/zone/models/mod.rs +7 -0
  55. package/src/zone/models/sarif.rs +89 -0
  56. package/src/zone/reporters/html_rep.rs +345 -0
  57. package/src/zone/reporters/json_rep.rs +7 -0
  58. package/src/zone/reporters/mod.rs +9 -0
  59. package/src/zone/reporters/sarif_rep.rs +100 -0
  60. package/src/zone/reporters/terminal.rs +322 -0
  61. package/src/zone/rules/definitions.rs +201 -0
  62. package/src/zone/rules/evaluator.rs +484 -0
  63. package/src/zone/rules/mod.rs +5 -0
  64. package/src/zone/scoring.rs +104 -0
package/Cargo.toml ADDED
@@ -0,0 +1,66 @@
1
+ [package]
2
+ name = "flareguard"
3
+ version = "0.1.0"
4
+ edition = "2024"
5
+ authors = ["Brandon Hubbard <bhubbard@users.noreply.github.com>"]
6
+ description = "Unified Cloudflare Security Guardian — AST secret scanning, Worker binding verification, Zone posture auditing, and origin IP leak hunting."
7
+ license = "MIT"
8
+ readme = "README.md"
9
+ repository = "https://github.com/bhubbard/flareguard"
10
+ homepage = "https://bhubbard.github.io/flareguard"
11
+ keywords = ["cloudflare", "security", "waf", "workers", "cli"]
12
+ categories = ["command-line-utilities", "development-tools"]
13
+
14
+ [lib]
15
+ name = "flareguard"
16
+ path = "src/lib.rs"
17
+
18
+ [[bin]]
19
+ name = "flareguard"
20
+ path = "src/main.rs"
21
+
22
+ [dependencies]
23
+ # CLI & Args
24
+ clap = { version = "4.5", features = ["derive", "cargo", "env"] }
25
+ clap_complete = "4.5"
26
+
27
+ # Async & Networking
28
+ tokio = { version = "1.43", features = ["full"] }
29
+ reqwest = { version = "0.12", features = ["json"] }
30
+ futures = "0.3"
31
+ hickory-resolver = "0.26"
32
+
33
+ # Parallelism & Performance
34
+ rayon = "1.10"
35
+ memmap2 = "0.9"
36
+
37
+ # Serialization & Formats
38
+ serde = { version = "1.0", features = ["derive"] }
39
+ serde_json = "1.0"
40
+ toml = "1.1"
41
+
42
+ # Terminal Formatting
43
+ colored = "3.0"
44
+ comfy-table = { version = "7.1", features = ["custom_styling"] }
45
+
46
+ # Pattern Matching & Graph
47
+ regex = "1.11"
48
+ glob = "0.3"
49
+ walkdir = "2.5"
50
+ ipnet = "2.12"
51
+ sha2 = "0.10"
52
+ hex = "0.4"
53
+ chrono = { version = "0.4", features = ["serde"] }
54
+
55
+ # OXC AST Parser for JS/TS
56
+ oxc_allocator = "0.146.0"
57
+ oxc_ast = "0.146.0"
58
+ oxc_parser = "0.146.0"
59
+ oxc_span = "0.146.0"
60
+
61
+ # Error Handling
62
+ thiserror = "2.0"
63
+ anyhow = "1.0"
64
+
65
+ [dev-dependencies]
66
+ tempfile = "3.17"
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Brandon Hubbard
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,115 @@
1
+ # 🛡️ Flareguard
2
+
3
+ > **The Unified Cloudflare Security & Architecture Guardian**
4
+ > High-performance Rust CLI & library providing AST secret scanning, Worker binding verification, Zone security posture auditing, and origin IP leak hunting.
5
+
6
+ [![CI](https://github.com/bhubbard/flareguard/actions/workflows/ci.yml/badge.svg)](https://github.com/bhubbard/flareguard/actions)
7
+ [![crates.io](https://img.shields.io/crates/v/flareguard.svg)](https://crates.io/crates/flareguard)
8
+ [![npm version](https://img.shields.io/npm/v/flareguard.svg)](https://www.npmjs.com/package/flareguard)
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
10
+ [![GitHub Pages](https://img.shields.io/badge/docs-bhubbard.github.io-blue)](https://bhubbard.github.io/flareguard)
11
+
12
+ ---
13
+
14
+ ## ⚡ The 4 Pillars of Flareguard
15
+
16
+ | Pillar | Subcommand | Description |
17
+ |---|---|---|
18
+ | **🔑 Secrets** | `flareguard secrets` | High-throughput multithreaded scanner preventing Cloudflare API tokens, Global Keys, and Turnstile secrets from leaking into client bundles or git history. |
19
+ | **⚡ Bindings** | `flareguard bindings` | OXC JavaScript/TypeScript AST scanner that cross-references `wrangler.toml` / `wrangler.jsonc` declarations against actual code usage (D1, KV, R2, Vectorize, Hyperdrive, AI). |
20
+ | **🌐 Zone Audit** | `flareguard zone` | Comprehensive live security posture auditor for Cloudflare zones (SSL/TLS Strict, HSTS, WAF Managed Rules, Bot Fight Mode, DNSSEC, security headers). |
21
+ | **🎯 Origin Hunter** | `flareguard origin` | Probes and discovers unmasked backend origin IPs behind Cloudflare reverse proxies using DNS SPF/MX records, CRT.sh Certificate Transparency logs, and active HTTP signatures. |
22
+
23
+ ---
24
+
25
+
26
+ ## 🔑 Supported Secret Detection Rules (15 Built-in Rules)
27
+
28
+ | Rule ID | Name | Severity | Description |
29
+ |---|---|---|---|
30
+ | **CF-001** | Cloudflare API Token | `CRITICAL` | Scoped API token (40 characters) |
31
+ | **CF-002** | Cloudflare Global API Key | `CRITICAL` | Legacy global account key (37-hex characters) |
32
+ | **CF-003** | Cloudflare Origin CA Key | `CRITICAL` | Origin certificate creation key (`v1.0-` prefix) |
33
+ | **CF-004** | Cloudflare Turnstile Secret Key | `CRITICAL` | Server-side verification secret (`0x4AAAA...`) |
34
+ | **CF-005** | Zero Trust Access Service Token | `CRITICAL` | Service token secret for Zero Trust policies |
35
+ | **CF-006** | Cloudflare Account ID Context | `MEDIUM` | Account ID assigned in sensitive config contexts |
36
+ | **CF-007** | R2 / S3 Secret Access Key | `CRITICAL` | Object storage secret key (40 characters) |
37
+ | **CF-008** | Database URI / D1 Secret | `CRITICAL` | Embedded Postgres/MySQL connection string or D1 token |
38
+ | **CF-009** | Standalone High-Entropy Token | `HIGH` | High Shannon-entropy token matching Cloudflare signatures |
39
+ | **CF-010** | Hyperdrive Origin Secret | `CRITICAL` | Database credentials or pooling passwords |
40
+ | **CF-011** | Cloudflare Tunnel Token | `CRITICAL` | `cloudflared` ingress tunnel credentials (`eyJh...`) |
41
+ | **CF-012** | AI Gateway & LLM API Key | `CRITICAL` | AI Gateway token, OpenAI (`sk-proj`), Anthropic (`sk-ant`), Gemini (`AIzaSy`) |
42
+ | **CF-013** | Vectorize Admin Secret | `CRITICAL` | Vector database index management key |
43
+ | **CF-014** | Email / MailChannels Secret | `HIGH` | DKIM / transactional mail dispatch credentials |
44
+ | **CF-015** | SSL/TLS Private Key | `CRITICAL` | Unencrypted RSA/EC private key (`BEGIN PRIVATE KEY`) |
45
+
46
+ ## 🚀 Installation & Quickstart
47
+
48
+ ```bash
49
+ # Install via Cargo (Rust)
50
+ cargo install flareguard
51
+
52
+ # Or install globally via npm
53
+ npm install -g flareguard
54
+
55
+ # Or run directly via npx without installation
56
+ npx flareguard --help
57
+
58
+ # Or build from source
59
+ git clone https://github.com/bhubbard/flareguard.git
60
+ cd flareguard
61
+ cargo build --release
62
+ ```
63
+
64
+ ### 1. Scan for Leaked Cloudflare Secrets
65
+ ```bash
66
+ # Scan static build directory (e.g. dist, public)
67
+ flareguard secrets dist/
68
+
69
+ # Run in CI mode (fails with exit code 1 on leaks)
70
+ flareguard secrets dist/ --check --format sarif --output results.sarif
71
+ ```
72
+
73
+ ### 2. Validate Worker / Pages Bindings
74
+ ```bash
75
+ # Validate wrangler.jsonc or wrangler.toml against src/ AST usage
76
+ flareguard bindings src/ --config wrangler.jsonc --strict
77
+ ```
78
+
79
+ ### 3. Audit Cloudflare Zone Security
80
+ ```bash
81
+ # Live zone audit via API Token
82
+ flareguard zone --token $CF_API_TOKEN --zone example.com --check
83
+
84
+ # Offline mock audit
85
+ flareguard zone --mock
86
+ ```
87
+
88
+ ### 4. Hunt for Unmasked Origin IPs
89
+ ```bash
90
+ # Scan domain for direct-to-origin leak vectors
91
+ flareguard origin example.com --check
92
+
93
+ # Offline mock scan
94
+ flareguard origin --mock
95
+ ```
96
+
97
+ ### 5. End-to-End Workspace Check
98
+ ```bash
99
+ # Run all local security checks across repository
100
+ flareguard check .
101
+ ```
102
+
103
+ ---
104
+
105
+ ## 📜 Architecture & Core Principles
106
+
107
+ - **Zero-Latency Parallelism:** Rayon-powered parallel directory traversal and memory-mapped file inspection (`memmap2`).
108
+ - **Precision AST Analysis:** Powered by **OXC** (Oxford JavaScript Compiler in Rust) for nanosecond JS/TS parsing without runtime node/v8 dependencies.
109
+ - **Actionable Remediation:** Every finding includes clear, copy-paste shell commands and Cloudflare dashboard remediation instructions.
110
+ - **Enterprise CI/CD Integration:** Direct SARIF output for GitHub Actions Code Scanning and customizable compliance gates.
111
+
112
+ ---
113
+
114
+ ## 📄 License
115
+ MIT © 2026 Brandon Hubbard ([brandonhubbard.com](https://brandonhubbard.com))
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env node
2
+ import { spawnSync } from "node:child_process";
3
+ import fs from "node:fs";
4
+ import { createRequire } from "node:module";
5
+ import path from "node:path";
6
+ import process from "node:process";
7
+ import { fileURLToPath } from "node:url";
8
+
9
+ const require = createRequire(import.meta.url);
10
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
11
+ const root = path.resolve(__dirname, "..");
12
+ const exe = process.platform === "win32" ? "flareguard.exe" : "flareguard";
13
+
14
+ const PLATFORM_PACKAGES = {
15
+ "darwin-arm64": "@flareguard/darwin-arm64",
16
+ "darwin-x64": "@flareguard/darwin-x64",
17
+ "linux-x64": "@flareguard/linux-x64",
18
+ "linux-arm64": "@flareguard/linux-arm64",
19
+ "win32-x64": "@flareguard/win32-x64",
20
+ };
21
+
22
+ export function getBinaryPath() {
23
+ if (process.env.FLAREGUARD_BIN && fs.existsSync(process.env.FLAREGUARD_BIN)) {
24
+ return process.env.FLAREGUARD_BIN;
25
+ }
26
+
27
+ // 1. Check if optional platform-specific package is installed
28
+ const platformKey = `${process.platform}-${process.arch}`;
29
+ const pkgName = PLATFORM_PACKAGES[platformKey];
30
+ if (pkgName) {
31
+ try {
32
+ const resolved = require.resolve(`${pkgName}/bin/${exe}`);
33
+ if (fs.existsSync(resolved)) {
34
+ return resolved;
35
+ }
36
+ } catch {
37
+ // Platform package not present; fall through
38
+ }
39
+ }
40
+
41
+ // 2. Check local builds or vendored binary locations
42
+ const candidates = [
43
+ path.resolve(root, "dist/bin", exe),
44
+ path.resolve(root, "target/release", exe),
45
+ path.resolve(root, "target/debug", exe),
46
+ ];
47
+
48
+ for (const candidate of candidates) {
49
+ if (fs.existsSync(candidate)) {
50
+ if (process.platform !== "win32") {
51
+ try {
52
+ const mode = fs.statSync(candidate).mode;
53
+ if ((mode & 0o111) === 0) {
54
+ fs.chmodSync(candidate, 0o755);
55
+ }
56
+ } catch {
57
+ // Ignore
58
+ }
59
+ }
60
+ return candidate;
61
+ }
62
+ }
63
+
64
+ return exe;
65
+ }
66
+
67
+ const bin = getBinaryPath();
68
+ const res = spawnSync(bin, process.argv.slice(2), { stdio: "inherit" });
69
+ if (res.error) {
70
+ if (res.error.code === "ENOENT") {
71
+ console.error(`[flareguard] Could not find native binary '${bin}'.`);
72
+ console.error("Please run `cargo build --release` or install flareguard via Cargo or prebuilt npm platform package.");
73
+ } else {
74
+ console.error(`[flareguard] Execution error: ${res.error.message}`);
75
+ }
76
+ process.exit(1);
77
+ }
78
+ process.exit(res.status ?? 0);
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "flareguard",
3
+ "version": "0.1.0",
4
+ "description": "Unified Cloudflare Security Guardian — AST secret scanning, Worker binding verification, Zone posture auditing, and origin IP leak hunting.",
5
+ "keywords": [
6
+ "cloudflare",
7
+ "security",
8
+ "waf",
9
+ "workers",
10
+ "cli",
11
+ "secrets",
12
+ "audit"
13
+ ],
14
+ "homepage": "https://bhubbard.github.io/flareguard",
15
+ "bugs": {
16
+ "url": "https://github.com/bhubbard/flareguard/issues"
17
+ },
18
+ "license": "MIT",
19
+ "author": "Brandon Hubbard <bkhubbard@gmail.com>",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/bhubbard/flareguard.git"
23
+ },
24
+ "bin": {
25
+ "flareguard": "bin/flareguard.js"
26
+ },
27
+ "files": [
28
+ "bin",
29
+ "scripts/postinstall.mjs",
30
+ "Cargo.toml",
31
+ "Cargo.lock",
32
+ "src",
33
+ "README.md",
34
+ "LICENSE"
35
+ ],
36
+ "type": "module",
37
+ "scripts": {
38
+ "build:cargo": "cargo build --release",
39
+ "postinstall": "node scripts/postinstall.mjs",
40
+ "prepare:publish": "node scripts/set-optional-deps.mjs",
41
+ "test": "cargo test"
42
+ },
43
+ "engines": {
44
+ "node": ">=18.0.0"
45
+ },
46
+ "//optionalDependencies": [
47
+ "The @flareguard/* prebuilt-binary packages are attached at publish",
48
+ "time by scripts/set-optional-deps.mjs, not committed here."
49
+ ]
50
+ }
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env node
2
+ import { spawnSync } from "node:child_process";
3
+ import fs from "node:fs";
4
+ import { createRequire } from "node:module";
5
+ import path from "node:path";
6
+ import process from "node:process";
7
+ import { fileURLToPath } from "node:url";
8
+
9
+ const require = createRequire(import.meta.url);
10
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
11
+ const exe = process.platform === "win32" ? "flareguard.exe" : "flareguard";
12
+
13
+ const PLATFORM_PACKAGES = {
14
+ "darwin-arm64": "@flareguard/darwin-arm64",
15
+ "darwin-x64": "@flareguard/darwin-x64",
16
+ "linux-x64": "@flareguard/linux-x64",
17
+ "linux-arm64": "@flareguard/linux-arm64",
18
+ "win32-x64": "@flareguard/win32-x64",
19
+ };
20
+
21
+ function log(message) {
22
+ console.log(`[flareguard] ${message}`);
23
+ }
24
+
25
+ function runnable(file) {
26
+ if (!fs.existsSync(file)) return false;
27
+ const res = spawnSync(file, ["--version"], { stdio: "ignore", timeout: 10_000 });
28
+ return !res.error && res.status === 0;
29
+ }
30
+
31
+ function alreadyPresent() {
32
+ const pkg = PLATFORM_PACKAGES[`${process.platform}-${process.arch}`];
33
+ if (pkg) {
34
+ try {
35
+ if (runnable(require.resolve(`${pkg}/bin/${exe}`))) return true;
36
+ } catch {
37
+ // Not installed; keep looking
38
+ }
39
+ }
40
+
41
+ return ["dist/bin", "target/release"].some((dir) => runnable(path.join(root, dir, exe)));
42
+ }
43
+
44
+ function hasCargo() {
45
+ const res = spawnSync("cargo", ["--version"], { stdio: "ignore" });
46
+ return res.status === 0;
47
+ }
48
+
49
+ function main() {
50
+ if (alreadyPresent()) return;
51
+
52
+ if (!hasCargo()) {
53
+ log(
54
+ `No prebuilt binary found for ${process.platform}-${process.arch} and cargo is not installed.\n` +
55
+ ` To build from source, install Rust (https://rustup.rs) and run \`cargo build --release\`,\n` +
56
+ ` or set FLAREGUARD_BIN to an existing flareguard binary.`,
57
+ );
58
+ return;
59
+ }
60
+
61
+ log("No prebuilt binary for this platform — compiling with cargo...");
62
+ const res = spawnSync("cargo", ["build", "--release"], { cwd: root, stdio: "inherit" });
63
+
64
+ if (res.status !== 0) {
65
+ log("cargo build failed. Run `cargo build --release` manually to see the error.");
66
+ return;
67
+ }
68
+
69
+ const built = path.join(root, "target", "release", exe);
70
+ const destDir = path.join(root, "dist", "bin");
71
+ if (fs.existsSync(built)) {
72
+ fs.mkdirSync(destDir, { recursive: true });
73
+ fs.copyFileSync(built, path.join(destDir, exe));
74
+ if (process.platform !== "win32") fs.chmodSync(path.join(destDir, exe), 0o755);
75
+ log("Engine built successfully.");
76
+ }
77
+ }
78
+
79
+ try {
80
+ main();
81
+ } catch (err) {
82
+ log(`Postinstall skipped: ${err.message}`);
83
+ }