linter speed, scanner depth

foxguard

Local security feedback you actually keep turned on.

131 built-in rules across 10 languages. Semgrep/OpenGrep compatible. Single Rust binary. No JVM. No network calls.

batteries included taint tracking sarif + json
GitHub
131 rules
10 languages
<1s local loop
terminal
$ foxguard .
Scanning 2,814 files...
src/auth/login.js:14:5
critical js/no-sql-injection CWE-89
app/views.py:42:1
high py/no-hardcoded-secret CWE-798
app/controllers/users.rb:23:5
critical rb/no-sql-injection CWE-89
UserService.java:67:12
high java/no-xxe CWE-611
cmd/server.go:31:3
high go/no-ssrf CWE-918
Found 5 issues in 2,814 files (0.92s)

Linter speed, scanner depth

The point is not winning a benchmark chart. The point is keeping security checks inside the edit loop, where developers will actually run them.

express
141 files
foxguard
0.284s
Semgrep
17.373s
61x faster
flask
83 files
foxguard
0.084s
Semgrep
7.325s
87x faster
gin
99 files
foxguard
0.516s
Semgrep
8.007s
16x faster

foxguard built-in rules vs Semgrep auto. Run ./benchmarks/run.sh locally to reproduce.

Leave it on. Fix while context is still warm.

edit
foxguard
fix
commit

What it catches

The default ruleset is biased toward real framework mistakes teams actually ship: Express sessions, Django CSRF, Rails mass assignment, Spring XXE, iOS keychain, .NET LDAP, and more.

Express / Node

28

Session secrets, cookie flags, JWT hardening, reflected response writes.

sessioncookiesjwtxss

Flask / Django

32

Secret keys, debug mode, CSRF protection, session cookie flags, and Django host/redirect hardening.

secret keyscsrfsessiondebug

Gin / net/http

11

Trusted proxies, missing timeouts, SSRF, TLS verification bypass.

proxiestimeoutsssrftls

Rails / Ruby

10

Mass assignment, CSRF bypass, unsafe deserialization, XSS escaping.

paramscsrfmarshalxss

Spring / Java

10

SQL injection, XXE, deserialization, CSRF config, CORS policy.

sqlxxecsrfcors

PHP / Laravel

10

Eval, file inclusion, unserialize, command injection, extract.

evalincludeunserializessrf

Rust

10

Unsafe blocks, transmute, command injection, TLS verification.

unsafetransmutetlsunwrap

C# / .NET

10

SQL injection, deserialization, XXE, LDAP injection, CORS.

sqlxxeldapcors

Swift / iOS

10

Keychain security, transport security, JS injection, TLS.

keychaintlstransportwebview
< 1s

Fast enough to stay enabled

Single Rust binary. No JVM, no Python runtime, no network calls. Built for local runs and pre-commit hooks.

hook

Pre-commit ready

Run foxguard init to install a repo-local hook and get a starter .foxguard.yml without wiring extra services.

.yaml

YAML bridge, not engine sprawl

Load a useful Semgrep/OpenGrep-compatible YAML subset on top of built-ins when you need it.

base

Baselines

Accept existing findings once and keep the rollout focused on new issues with a baseline file.

secret

Secrets scanning

Detect leaked credentials and private keys with redacted output and binary-safe handling in the same tool.

SARIF

CI-friendly output

Terminal output locally, JSON and SARIF for automation, policy gates, and GitHub Code Scanning.

Semgrep compatibility

Bring your existing rules without pretending this is full Semgrep

Load a focused Semgrep/OpenGrep-compatible YAML subset on top of built-ins with --rules. The supported surface is explicit, limited, and parity-tested in CI.

pattern pattern-regex pattern-either pattern-not pattern-not-regex pattern-inside pattern-not-inside patterns (AND) metavariable-regex paths.include/exclude Full Semgrep syntax

Install

npx foxguard .
brew install peaktwilight/tap/foxguard
cargo install foxguard
VS Code / Cursor
Scans on save, shows findings as underlines
Install →
Quick start
1.
foxguard init pre-commit hook + config
2.
foxguard . scan everything
3.
foxguard --changed . scan only modified files
4.
foxguard secrets --changed . check for leaked credentials

Rules

131 built-in rules, each mapped to a CWE identifier.

JavaScript / TypeScript 28
js/express-cookie-no-httponly medium CWE-1004
js/express-cookie-no-samesite medium CWE-352
js/express-cookie-no-secure medium CWE-614
js/express-direct-response-write high CWE-79
js/express-no-hardcoded-session-secret high CWE-798
js/express-session-resave-true medium CWE-384
js/express-session-saveuninitialized-true medium CWE-359
js/jwt-decode-without-verify high CWE-347
js/jwt-hardcoded-secret high CWE-798
js/jwt-ignore-expiration high CWE-613
js/jwt-none-algorithm high CWE-347
js/jwt-verify-missing-algorithms high CWE-347
js/no-command-injection critical CWE-78
js/no-cors-star medium CWE-942
js/no-document-write high CWE-79
js/no-eval critical CWE-95
js/no-hardcoded-secret high CWE-798
js/no-open-redirect medium CWE-601
js/no-path-traversal high CWE-22
js/no-prototype-pollution high CWE-1321
js/no-sql-injection critical CWE-89
js/no-ssrf high CWE-918
js/no-unsafe-format-string medium CWE-134
js/no-unsafe-regex medium CWE-1333
js/no-weak-crypto medium CWE-327
js/no-xss-innerhtml high CWE-79
js/taint-sql-injection critical CWE-89
js/taint-xss-innerhtml high CWE-79
Python 32
py/csrf-cookie-httponly-disabled medium CWE-1004
py/csrf-cookie-samesite-disabled medium CWE-352
py/csrf-cookie-secure-disabled medium CWE-614
py/csrf-exempt high CWE-352
py/django-allowed-hosts-wildcard medium CWE-346
py/django-secret-key-hardcoded high CWE-798
py/flask-debug-mode high CWE-489
py/flask-secret-key-hardcoded high CWE-798
py/no-command-injection critical CWE-78
py/no-cors-star medium CWE-942
py/no-debug-true medium CWE-489
py/no-eval critical CWE-95
py/no-hardcoded-secret high CWE-798
py/no-open-redirect medium CWE-601
py/no-path-traversal high CWE-22
py/no-pickle high CWE-502
py/no-sql-injection critical CWE-89
py/no-ssrf high CWE-918
py/no-weak-crypto medium CWE-327
py/no-yaml-load high CWE-502
py/secure-ssl-redirect-disabled medium CWE-319
py/session-cookie-httponly-disabled medium CWE-1004
py/session-cookie-samesite-disabled medium CWE-352
py/session-cookie-secure-disabled medium CWE-614
py/taint-command-injection critical CWE-78
py/taint-eval critical CWE-95
py/taint-pickle-deserialization critical CWE-502
py/taint-sql-injection critical CWE-89
py/taint-ssrf high CWE-918
py/taint-yaml-load critical CWE-502
py/wtf-csrf-check-default-disabled high CWE-352
py/wtf-csrf-disabled high CWE-352
Go 11
go/gin-no-trusted-proxies medium CWE-346
go/insecure-tls-skip-verify high CWE-295
go/net-http-no-timeout medium CWE-400
go/no-command-injection critical CWE-78
go/no-hardcoded-secret high CWE-798
go/no-sql-injection critical CWE-89
go/no-ssrf high CWE-918
go/no-weak-crypto medium CWE-327
go/taint-command-injection critical CWE-78
go/taint-sql-injection critical CWE-89
go/taint-ssrf high CWE-918
Ruby 10
rb/no-command-injection critical CWE-78
rb/no-csrf-skip high CWE-352
rb/no-eval critical CWE-95
rb/no-hardcoded-secret high CWE-798
rb/no-html-safe high CWE-79
rb/no-mass-assignment high CWE-915
rb/no-open-redirect high CWE-601
rb/no-sql-injection critical CWE-89
rb/no-unsafe-deserialization critical CWE-502
rb/no-weak-crypto medium CWE-327
Java 10
java/no-command-injection critical CWE-78
java/no-hardcoded-secret high CWE-798
java/no-path-traversal high CWE-22
java/no-sql-injection critical CWE-89
java/no-ssrf high CWE-918
java/no-unsafe-deserialization critical CWE-502
java/no-weak-crypto medium CWE-327
java/no-xxe high CWE-611
java/spring-cors-permissive medium CWE-942
java/spring-csrf-disabled high CWE-352
PHP 10
php/no-command-injection critical CWE-78
php/no-eval critical CWE-95
php/no-extract high CWE-621
php/no-file-inclusion critical CWE-98
php/no-hardcoded-secret high CWE-798
php/no-preg-eval critical CWE-95
php/no-sql-injection critical CWE-89
php/no-ssrf high CWE-918
php/no-unserialize critical CWE-502
php/no-weak-crypto medium CWE-327
Rust 10
rs/no-command-injection critical CWE-78
rs/no-hardcoded-secret high CWE-798
rs/no-path-traversal medium CWE-22
rs/no-sql-injection critical CWE-89
rs/no-ssrf high CWE-918
rs/no-unwrap-in-lib medium CWE-248
rs/no-weak-hash medium CWE-328
rs/tls-verify-disabled high CWE-295
rs/transmute-usage high CWE-843
rs/unsafe-block medium CWE-676
C# 10
cs/no-command-injection critical CWE-78
cs/no-cors-star medium CWE-942
cs/no-hardcoded-secret high CWE-798
cs/no-ldap-injection high CWE-90
cs/no-path-traversal high CWE-22
cs/no-sql-injection critical CWE-89
cs/no-ssrf high CWE-918
cs/no-unsafe-deserialization critical CWE-502
cs/no-weak-crypto medium CWE-327
cs/no-xxe high CWE-611
Swift 10
swift/no-command-injection critical CWE-78
swift/no-eval-js critical CWE-95
swift/no-hardcoded-secret high CWE-798
swift/no-insecure-keychain high CWE-311
swift/no-insecure-transport high CWE-319
swift/no-path-traversal high CWE-22
swift/no-sql-injection critical CWE-89
swift/no-ssrf high CWE-918
swift/no-tls-disabled high CWE-295
swift/no-weak-crypto medium CWE-327