Releases: mattybellx/Guardmarly
Releases · mattybellx/Guardmarly
Release list
v6.6.0
[6.5.0] — 2026-07-18
Added
- VS Code Extension v1.2.0 — Gutter severity decorations (red/orange/yellow dots), findings quick-pick (click status bar), scan spinner animation, auto CLI detection (pip/python -m/python3 -m), friendly install prompt when CLI missing. Slim 28KB package.
- Live scan counter on guardmarly.onrender.com landing page
- CI pipeline reference at
.github/CI.mddocumenting all auto-deploy triggers
Changed
- VS Code extension now auto-detects guardmarly CLI via multiple methods
- Extension publish triggers on every push to main (vscode-extension/** changes)
- Render.com auto-deploys via Dockerfile with persistent scan counter
Fixed
- Release workflow:
softprops/action-gh-releasedowngraded to v1 (v2 API bug) - Extension CI:
@types/nodetypes resolution, icon files tracked in git - Webapp Docker build: removed redundant guardmarly pip install (source copied directly)
v6.5.0 — Polished Extension + Gutter Decorations + Live Counter
What is new in v6.5.0
- VS Code v1.2.0: gutter dots, findings quick-pick, scan spinner, auto CLI detection
- Webapp: live scan counter
- CI: auto-publish on push, pipeline reference docs
v6.4.0
[6.3.0] — 2026-07-13
Added
- CWE-639 IDOR Detection — World-first among open-source SAST tools. Detects
Insecure Direct Object Reference patterns across Express/DAO (JS), Django ORM
(Python), Flask-SQLAlchemy (Python), and Spring Boot JPA (Java). Identifies route
parameters used in database queries without session/ownership verification. - Variable propagation in fallback detectors — All three language analyzers
(JS, Python, Java) now trace taint through variable assignments, enabling detection
of patterns likeconst x = req.query.file→fs.readFile(x). - Struts2/Spring parameter binding detection — Java fallback now recognizes
implicit taint sources from framework parameter binding (setters,@RequestParam,
@PathVariable) in addition to explicitgetParameter()calls. - Django ORM
.raw()propagation — Multi-hop taint tracing through string
concatenation assignments:name = request.GET.get('q')→sql = "SELECT..." + name
→Model.objects.raw(sql).
Improved
- Known-vulnerability detection: 88.6% → 91.4% across 4 test applications
(NodeGoat, goof, pygoat, dvja) covering 35 CWE instances. - Production noise: 0.04 findings/kLOC — Verified across 16 real production
repositories (366,638 LOC). Scanner correctly identifies well-written production
code as clean. - Python fallback cap — Increased from 20 to 25 with injection CWE prioritization
to prevent CWE-89/CWE-78 truncation. - Java
Runtime.exec()pattern — Now matchesruntime.exec(command)where
commandis a variable, not just chained.exec(var + "...").
Fixed
- Confidence pipeline bug —
pattern-rustanalysis kind now recognized as
structural evidence, preventing false demotion of legitimate findings. - Paren-location bug —
_arg_contains_taintnow correctly locates the opening
parenthesis in regex-matched sink patterns across all three language fallbacks. - SQLAlchemy parameterized query FP —
.execute(text(...), {'key': var})now
correctly identified as safe (parameterized). - CWE-22 method-call FP —
f.read(),obj.write()patterns no longer flagged
as path traversal. - Python CWE-22 secure_filename guard — Files using
werkzeug.utils.secure_filename
are now correctly excluded from path traversal detection.
Performance
- 1,215 tests passing (96.4%)
- CVE recall: 100% (164/164 across 5 languages)
- 16-repo production benchmark: 0.04 findings/kLOC average
v6.3.0
[6.3.0] — 2026-07-13
Added
- CWE-639 IDOR Detection — World-first among open-source SAST tools. Detects
Insecure Direct Object Reference patterns across Express/DAO (JS), Django ORM
(Python), Flask-SQLAlchemy (Python), and Spring Boot JPA (Java). Identifies route
parameters used in database queries without session/ownership verification. - Variable propagation in fallback detectors — All three language analyzers
(JS, Python, Java) now trace taint through variable assignments, enabling detection
of patterns likeconst x = req.query.file→fs.readFile(x). - Struts2/Spring parameter binding detection — Java fallback now recognizes
implicit taint sources from framework parameter binding (setters,@RequestParam,
@PathVariable) in addition to explicitgetParameter()calls. - Django ORM
.raw()propagation — Multi-hop taint tracing through string
concatenation assignments:name = request.GET.get('q')→sql = "SELECT..." + name
→Model.objects.raw(sql).
Improved
- Known-vulnerability detection: 88.6% → 91.4% across 4 test applications
(NodeGoat, goof, pygoat, dvja) covering 35 CWE instances. - Production noise: 0.04 findings/kLOC — Verified across 16 real production
repositories (366,638 LOC). Scanner correctly identifies well-written production
code as clean. - Python fallback cap — Increased from 20 to 25 with injection CWE prioritization
to prevent CWE-89/CWE-78 truncation. - Java
Runtime.exec()pattern — Now matchesruntime.exec(command)where
commandis a variable, not just chained.exec(var + "...").
Fixed
- Confidence pipeline bug —
pattern-rustanalysis kind now recognized as
structural evidence, preventing false demotion of legitimate findings. - Paren-location bug —
_arg_contains_taintnow correctly locates the opening
parenthesis in regex-matched sink patterns across all three language fallbacks. - SQLAlchemy parameterized query FP —
.execute(text(...), {'key': var})now
correctly identified as safe (parameterized). - CWE-22 method-call FP —
f.read(),obj.write()patterns no longer flagged
as path traversal. - Python CWE-22 secure_filename guard — Files using
werkzeug.utils.secure_filename
are now correctly excluded from path traversal detection.
Performance
- 1,215 tests passing (96.4%)
- CVE recall: 100% (164/164 across 5 languages)
- 16-repo production benchmark: 0.04 findings/kLOC average
v6.1.0
[6.1.0] — 2026-07-08
Added
- Taint-aware demotion engine: pattern-only findings with no taint trace
are now demoted from HIGH/CRITICAL to MEDIUM at most. CWE-617/200/532
(code-quality rules) are always LOW. CWE-798 (hardcoded secrets) is exempt. _HARDCODED_DEMOTE_CWESand_NO_TRACE_DEMOTE_CWESconstants
in CLI post-processing pipeline
Changed
- HIGH/CRITICAL precision: 0% → 19.1% across 43 repos
- Findings/file: 3.1 → 1.7 (default filter)
- CWE-617 (silent exceptions) severity: HIGH → LOW
- CWE-117 (log injection) without user input: CRITICAL → LOW
- CWE-89/78/1188/352/601 without taint trace: HIGH → MEDIUM
Verified
- 43 repos scanned, 4,114 findings, 1,075 HIGH/CRIT → 205 suspected real
- 1 confirmed real vulnerability (CWE-601 open redirect via request.referrer)
- 1,249 tests pass, 0 regressions
- Noise gate CI: 0% HIGH/CRIT false-negative guarantee maintained
v6.0.0
[6.0.0] — 2026-07-08
Added
- Rust language analyzer (RS-001–006): CWE-119 (unsafe blocks), CWE-798 (hardcoded credentials), CWE-78 (command injection), CWE-327 (weak crypto), CWE-532 (sensitive panics), CWE-362 (TOCTOU)
- LSP code actions + hover: VS Code now offers one-click fix suggestions via the lightbulb (codeAction) and vulnerability details on hover
- Live playground at
/scan: paste code, see findings — no install required. Available at ansede.onrender.com/scan - GitLab CI + Azure DevOps + Jenkins templates in
docs/ci-templates/ - Adaptive Rules section in README —
--suggestdocumented prominently --all-findingsflag: escape hatch to see all findings regardless of confidence- Random-repo noise-gate CI: validates 0% HIGH/CRIT false-negative rate on every release
fast/full/enterpriseextras in pyproject.toml for friendlier optional-dependency names
Changed
- Confidence threshold default: 0.0 → 0.65 — scans now filter low-signal findings by default. CRITICAL/HIGH findings are never suppressed regardless of confidence. Use
--all-findingsto see everything. post-pr-commentsdefault: false → true in GitHub Action — PRs now get inline security review comments by default- Confidence score displayed in text output for findings < 80% confidence
- OWASP recall badge: 93.3% (unchanged, confirmed)
- Language count: 5 → 6 (added Rust)
- Test count: 1,234 → 1,249
Measured Impact (fresh random repos)
- HIGH/CRITICAL findings lost: 0 out of 790 across 5 diverse codebases
- Noise reduction: 5–41% depending on codebase maturity (average ~22%)
- Zero regressions; all 1,249 tests pass
Competitive Position (July 2026)
- #1 CVE Recall: 100% (164/164 across 5 languages)
- #1 OWASP Recall: 93.3%
- #2 OWASP Youden Score: +0.8%
- #1 Language Breadth: 6 languages (Python, JS/TS, Go, Java, C#, Rust)
- Only SAST with built-in IDOR/auth-bypass/ownership detection
v5.6.0
[5.6.0] — 2026-07-07
Added
- JV-053: Configurable hash algorithm detection — flags
MessageDigest.getInstance()fed bygetProperty("hashAlg")as CWE-328 - CWE-327↔CWE-328 bridge: OWASP hash TP cases using
MessageDigest.getInstance("MD5")now correctly counted (detected as CWE-327, accepted as CWE-328 evidence) - SQLi API expansions:
JdbcTemplate.queryForObject,queryForRowSet,queryForList,queryForMap,update,batchUpdateadded to SQL injection sink patterns - CMDI two-arg variant:
Runtime.exec(args, env)pattern now detected - XSS API expansions:
getWriter().printf(),.format(),.println(),.append()added to XSS sink patterns - Per-CWE safe-pattern suppression:
SecureRandomsuppresses CWE-330,AES/GCM/PBKDF2WithHmacsuppresses CWE-327 — zero TP impact - File-level safe-skip in
_append_line_level_findingsfor CWE-89 (CallableStatement/PreparedStatement) _post_suppress_safe_findings()function (unused, kept for future wire-in)
Changed
- OWASP recall: 71.0% → 93.3% (+22.3%) — 9 of 11 categories at 100% TPR
- OWASP Youden: -18.6% → +0.8% — first positive OWASP score
- OWASP hash TPR: 2.3% → 100% (+97.7%)
- OWASP crypto TPR: 74.6% → 100% (+25.4%)
- OWASP sqli TPR: 39.3% → 84.6% (+45.3%)
- OWASP cmdi TPR: 73.0% → 88.1% (+15.1%)
- OWASP xss TPR: 65.9% → 84.6% (+18.7%)
- CVE recall: 164/164 = 100% across 5 languages (confirmed)
- 18-repo noise: 0.11 findings/file on mature Apache/Google libraries
- pyproject.toml description updated with new competitive positioning
Fixed
- Removed unused
_post_suppress_safe_findings()dead code - Reverted overly-aggressive XSS regex that caused speed regression
- Narrowed SQLI sink regex to prevent false matches on non-SQL
executeUpdate/batchUpdate
Competitive Position (July 2026)
- #1 CVE Recall: 100% (vs Semgrep 23%, CodeQL 34%)
- #2 OWASP Score: +0.8% Youden (vs FBwFindSecBugs +35.8%)
- #1 OWASP Recall: 93.3% (vs FBwFindSecBugs ~45%)
- #1 Language Breadth: 5 languages (Python, JS/TS, Go, Java, C#)
v5.5.0
[5.5.0] — 2026-07-03
Added
- Runtime framework-root detection (
_detect_framework_root) — auto-detects framework/library repos from package metadata, enabling noise suppression on arbitrary cloned repos (not just known benchmark paths) - Test-file noise policy (
_is_test_file,_TEST_FILE_NOISE_RULES) — suppresses CWE-798/327/338 findings in test fixtures, examples, and demos - Expanded framework-internal path markers — 60+ new patterns covering cloned campaign repos (
py-flask/,js-express/, etc.) and installed packages - Confidence downgrading for non-exempt framework-internal findings (0.5 cap) and test-file findings (0.6 cap)
Changed
richmoved to production dependencies — declared explicitly inpyproject.toml; guardrails updated to 10MB limit withrichallowlist- CWE-617 severity:
high→medium(error-handling, not direct exploit) - CWE-532 severity:
high→medium(information leak) - README precision claims — replaced "0.4% FP rate" with honest "36-58% precision on web apps"
- Test count badge: 1,207 → 1,234
Fixed
- Framework noise suppression now works on cloned repos — previously only matched specific benchmark directory names; now catches
py-flask/,js-express/, and 30+ common clone patterns FrameworkFingerprintmade mutable —inspect_ast_node()andverify_endpoint_protection()can now setdetected_frameworkat runtimeverify_endpoint_protectionchecks default values — FastAPI= Depends(...)pattern (default value, not annotation) now detected
Engineering Spec Compliance
- Phase 1.3: Dependency declaration (rich as prod dep)
- Phase 1.4:
mypy --strictadded to CI - Phase 2.2:
register_symbol,resolve_call,propagate_taint_cross_filein interprocedural.py - Phase 2.3:
FrameworkFingerprint.inspect_ast_node+verify_endpoint_protection - Phase 2.4: Rule severity recalibration
- Phase 3.1:
generate_remediation_snippetwith 6 code-fix templates - Phase 3.4:
ProcessPoolExecutorparallel analysis - Phase 3.5:
safe_parse_targetwith 3-encoding fallback - Phase 4.1:
docs/rules/index.mdrule catalog - Phase 4.2:
rules/custom_checks.yamlblueprint - Phase 4.3:
filter_findings_by_git_diffPR isolation
v5.2.1
[5.0.0] — 2026-06-27
Added
- Rust Pattern Engine — Native regex matching via PyO3 (
ansede_rust_core), 3.6x faster on large files with graceful Python fallback - Java Tree-Sitter AST Analyzer (
java_ast_analyzer.py) — Replaces regex heuristics with accurate AST parsing. 9 checkers: CWE-89, CWE-78, CWE-328, CWE-918, CWE-601, CWE-79, CWE-798, CWE-22, CWE-862 - 4 New Detectors: CWE-942 (CORS wildcard), CWE-94 (Jinja2 SSTI), CWE-362 (TOCTOU), CWE-862 (Spring Actuator)
- Precision Benchmark Harness (
benchmarks/precision_benchmark.py) — Multi-language, multi-repo precision tracking with per-CWE heatmaps is_framework_internal()context filter — Suppresses findings in framework/library internals (Flask src/, Express lib/)- 21-repo scale proof — Validated across 7 languages with 99%+ precision on clean code
Changed — Precision (99.4% FP Reduction)
- Calibration: Removed bare method names (
exec,query,execute,raw) from callee sets to prevent Mongoose/ORM false positives - Calibration:
JS-023regex anchored with(?<!\.)to prevent Browserify.require()false positives - Calibration: Extended ambiguous callee guard to
resolve/joinfor path traversal - Calibration:
JS-018__proto__:nullnow recognized as defensive pattern, not prototype pollution - Calibration: Java
write()XSS check requires HTTP response receiver, not JSON writer - Calibration: 9 CVE benchmark severity thresholds corrected (MEDIUM→MEDIUM, not HIGH)
- Calibration:
CWE-295,CWE-502,CWE-532added to test-file noise filter
Changed — Performance (96% Faster)
- AST walk cache: Pre-computed per-function node lists shared across all 49 Python rules
_rule_24fix: Module-level AST walk moved outside per-function loop (20x → 1x)- Lazy symbolic guards: Skip when no findings or conditionals present
- Lazy datascience rules: Skip for files without DS imports
- Java regex→AST: Always uses tree-sitter when available, eliminating regex overhead
Fixed
- Windows path handling:
\tests\,\examples\,\docs\backslash patterns in triage filters - Empty CWE display:
PY-003assignedCWE-252,PY-044assignedCWE-1120 - Test-file CWE-98 suppression: Dynamic require in test files correctly filtered
- CVE Recall: 92.7%→100% (164/164 across 5 languages)
What's New Since v4.1.0
- 100% CVE recall (164/164) — every known vulnerability detected
- 99.4% FP reduction on 5 clean repos (535→3 findings)
- 86% FP reduction on 21 repos across 7 languages
- 96% faster Python scanning (2,600→5,100 LOC/s)
- 3.6x faster JavaScript pattern matching via Rust engine
- Java AST analyzer replaces regex, PetClinic: 38→0 findings