linter speed, scanner depth

foxguard

Local security feedback you actually keep turned on.

120 built-in rules across 10 languages, plus a focused Semgrep-compatible YAML bridge when teams already have rule investments. Single Rust binary. No JVM. No network calls.

local-first built-ins first yaml bridge sarif + json
GitHub
120 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

Not just generic AST patterns. 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

26

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

sessioncookiesjwtxss

Flask / Django

26

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

secret keyscsrfsessiondebug

Gin / net/http

8

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

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

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