Skip to content

What's new

A version-by-version history of Fendix development. v3.4.1 shipped September 2026 — the engine images now ship Go 1.27, raising govulncheck's module ceiling from 1.25; no scanner, fingerprint or exit-code changes, and the Go module floor stays 1.25. v3.4.0 — a scan can no longer look complete when it wasn't: every analyzer records whether it ran and why not, the report carries a coverage block that names the gaps, a URL scan with zero endpoints writes its report instead of vanishing, and two opt-in flags turn a coverage gap into a failing build. v3.3.0 — an upgrade no longer splits a finding you were already tracking into a closed one and a new one, and the list of checks a scan ran is built from what completed rather than what was configured. v3.2.0 — every blocking decision explains itself. A BLOCK now carries the policy it was made under and the evidence class that justified it, all the way through Fendix's own storage into the SARIF you export, so a failed pipeline is answerable from the report alone. Findings held back state why they were held back, confidence scores come with the rules that produced them, and a build blocked only because confidence enforcement was switched off is labelled as such. v3.1.0 stopped findings claiming more than they proved — wildcard CORS with credentials, rate-limit prioritisation, response-aware header grading, path-traversal wording, test-fixture credentials and dependency applicability all became more precise. v3.0 gave findings a stable identity based on rule, file, symbol and operation rather than line number; re-save your baselines once after upgrading from before it.

v0.18.1 Complete

CI-integration hardening — container fix, fewer false positives, stable suppressions

June 2026

  • Whitebox taint engine now loads in containers. The runtime image set FENDIX_PYTHON_ENGINE, but the binary resolves the engine via FENDIX_ENGINE — so in every Docker run the Python taint engine silently fell back to a missing path and disabled itself, leaving only the native Go scanners. The Dockerfile now exports the variable the engine actually reads, so interprocedural auth/injection taint analysis runs in CI and any other container.
  • Fewer secret false positives, at the source. The secrets scanner now recognises a *reference* to a secret (an AWS Secrets Manager ARN, an rds!db- managed-secret name, a GCP projects/*/secrets/* resource) versus an actual credential value, and filters unambiguous placeholders (YOUR_TOKEN_HERE, <...>, ${VAR}, changeme). Deliberately narrow — it never suppresses on the bare substring example, so AWS's documented example keys are still flagged. These two classes previously needed hand-written per-line suppressions.
  • Stable finding fingerprints for durable suppressions. Every finding now carries a content-derived fingerprint (hash of category + location + title) that doesn't change between runs, unlike the positional SEC-NNN id. .fendix-ignore gains a fingerprint: rule (and fendix ignore validate recognises it) so a suppression keeps matching across scans and code moves instead of silently drifting onto the wrong finding. The baseline diff shares the same identity.
  • Coverage is no longer silent + baseline fails closed. Reports now include endpoints_discovered and endpoints_truncated so a scan capped by --max-endpoints is distinguishable from a complete one (no more invisible partial coverage). And a corrupt --baseline file now fails the run (exit 2) instead of silently scanning with no diff — a missing baseline still fail-opens for the legitimate first run.
v0.18.0 Complete

DAST module upgrade — 15 black-box checks, 3 critical fixes

June 2026

  • Black-box DAST expanded 8 → 15 checks. Seven new check types ship in this release: cookie-flags (passive, CWE-1004/614/1275 — missing Secure / HttpOnly / SameSite), open-redirect (active, CWE-601), reflected XSS (active, CWE-79), in-band SSRF (active, CWE-918), host-header injection (active, CWE-644/601), GraphQL introspection (active, CWE-200), and HTTP method tampering (active, CWE-650/693/285). The full registered set is now configleak, headers, cors, exposure, ratelimit, cookie-flags, auth, idor, injection, open-redirect, xss, ssrf, host-header, graphql, and method-tamper.
  • 3 criticals fixed. addAuth double-prefix (auth header value getting the scheme prepended twice on retry), an SSRF-guard bypass that affected 6 active checks (the guard ran before payload mutation on those paths), and a redirect-follow path that re-issued requests without re-validating the resolved IP against the private/loopback denylist.
  • 45 verified accuracy fixes. A batch of false-positive reductions across the active and passive probes, each backed by a regression case, sharpening precision without dropping recall on the labeled corpus.
  • New finding categories. The report schema now emits xss, cookie, redirect, host_header, graphql, and method_tamper alongside the existing categories, so the dashboard and SARIF output classify the new check types correctly.
v0.16.1 Complete

Runs on every commit — diff-aware scans, pre-commit hook, transitive Python SCA

June 13, 2026

  • Diff-aware scan — `fendix scan --code . --diff --staged --fast`. Resolves changed files via git diff and threads a file-allowlist through every whitebox scanner; SCA runs only when a manifest/lockfile changed. Scopes a scan to just the files a commit touches — ~18ms on a 200-file monorepo, fast enough to run on every commit instead of only in CI. (Distinct from the existing --baseline finding-suppression mechanism.)
  • Pre-commit hook — `fendix hook install`. Drops a pre-commit script that runs the diff-aware scan (secrets + textscan, sub-second budget) and blocks the commit the moment a secret or HIGH+ finding is staged. Honours core.hooksPath, refuses to clobber a foreign hook, and git commit --no-verify is the escape hatch.
  • Proven Path v1 (SAST taint chains). For Python/Django/Flask/FastAPI, route-table extraction binds a request route to its handler and exports the full route → handler → source → sink taint chain as SARIF codeFlows/threadFlows, so GitHub renders the step-through inline in the Security tab. A new source_tier provenance tag (native_go / tree_sitter_sidecar / semgrep_shim) travels end-to-end so a regex-tier finding can never ride correlation up to CRITICAL.
  • Transitive Python SCA — `poetry.lock` + `Pipfile.lock`. Both lockfiles are now parsed as the full resolved dependency closure, so a CVE three dependencies deep is caught — closing the requirements.txt-only direct-deps gap. (Separate from the npm package-lock.json transitive tree shipped in v0.8.0.)
  • Released, signed, and shipped to production. v0.16.1 publishes a cosign-signed multi-arch Docker image with CycloneDX SBOM + SLSA provenance, and is live on the hosted platform. The GitHub Action is pinned via uses: Fendix-app/Fendix@v1.
v0.14.1 Complete

Enterprise-readiness complete — audit pass + CI stability

May 18, 2026

  • Enterprise-readiness work complete. The full enterprise-readiness program shipped across the prior releases: trust fixes (v0.11.1), the unified SAST engine (v0.12.0), the REST API served by the backend SaaS layer (v0.12.1), offline mode plus i18n and PDF reports (v0.13.0), integrations (v0.13.1), and the benchmark harness, CI templates, and rule pack (v0.14.0). This patch closes the CI loop and locks in a stable state for the next feature cycle.
  • CI red-state sweep. Resolved three pre-existing CI flakies: context-cancellation tests widened to 8s budget + EPIPE tolerance on plugin stdin writes (macOS-specific pipe close sequence); two hybrid-correlator E2E tests fixed by honouring the FENDIX_ENGINE env var so they opt into --python-engine correctly on CI runners; gofmt drift corrected across 21 files that had accumulated whitespace / import-ordering skew. All 21 Go packages race-clean, 180 Python tests green, 14 E2E tests green.
  • Pre-existing YAML quoting fix in `auth.yaml`. The python-jwt-decode-no-verification rule embedded {"verify_signature": False} unquoted — valid to Python's ruamel-yaml but rejected by gopkg.in/yaml.v3. A new YAML catalog test surfaced it; single-quoted in this patch. Behaviour unchanged at scan time.
  • Backend and frontend synced to v0.14.1. The backend absorbed all new CLI flags and schema fields. The frontend was updated with version literals, changelog entries, CLI reference (new subcommands + flags), checks page (textscan + expanded Semgrep), and integrations page (Jira + Slack/Teams + GitLab/CircleCI).
v0.14.0 Complete

Enterprise benchmark harness + GitLab/CircleCI templates + Semgrep rule pack

May 18, 2026

  • Enterprise SAST comparison harness. scripts/benchmark-enterprise/ provides an apples-to-apples comparison of fendix vs. semgrep vs. bandit on a shared ~100-LOC fixture with 5 labeled true positives and 5 false-positive probes. Measures wall-clock, peak RSS, TP count, and FP count. Tools not on PATH are honestly reported as 'skipped' — no silent zeros. A new benchmark-enterprise.yml GitHub Actions workflow runs on release tags and workflow_dispatch, installs both competitors, and posts results as a job summary.
  • GitLab CI + CircleCI templates via `fendix init --ci`. The init command now auto-detects the CI system from project root files (.github/, .gitlab-ci.yml, .circleci/) and emits a native CI template. --ci github (unchanged), --ci gitlab (.gitlab-ci.fendix.yml + SAST report + NEXT-STEPS.md), --ci circleci (inline snippet + NEXT-STEPS.md). Without --ci, auto-detect falls back to github. Every emitted YAML is parse-validated at test time so typos can't ship in a release.
  • Semgrep rule pack expanded 9 → 24 rules. A new crypto rule file adds 4 cryptography rules. Additions across existing files: 2 new auth rules (Django function-based view missing decorator, Flask route missing auth decorator), 5 new injection rules (Django ORM raw SQL, Flask render_template_string SSTI, subprocess(shell=True) high-precision variant, pickle.loads, yaml.load without SafeLoader), 4 new secrets rules (GCP service-account JSON inline, AWS access-key ID, Slack webhook URL, PEM private key). Every rule carries metadata.category, metadata.fendix_severity, metadata.confidence, metadata.cwe. A new YAML-only catalog test enforces these invariants for every current and future rule.
v0.13.1 Complete

Integrations: GitHub App + Jira + Slack/Teams

May 18, 2026

  • GitHub App handler doc cleanup. The GitHub App webhook documentation now describes what's actually there: HandlePullRequest (clone → scan → comment → SARIF upload), HandleCheckRun (re-run button), HandlePush (no-op baseline placeholder).
  • Jira integration via `fendix jira`. Idempotent Jira sync: each finding above FENDIX_JIRA_MIN_SEVERITY (default HIGH) gets exactly one Jira issue. Idempotency key is fendix-id:<finding.ID> on the issue's label field — re-running the command on the same findings is safe. Severity → priority mapping: CRITICAL→Highest, HIGH→High, MEDIUM→Medium, LOW/INFO→Low. Configured via four environment variables (FENDIX_JIRA_URL, FENDIX_JIRA_PROJECT_KEY, FENDIX_JIRA_EMAIL, FENDIX_JIRA_API_TOKEN). Works against both Jira Cloud and Server tiers (plaintext description format, ADF rendering is server-side).
  • Slack + Teams webhook alerts via `fendix notify`. Post Slack Block Kit and Teams Adaptive Card alerts for findings above a configurable severity floor. Both sinks are optional — set FENDIX_SLACK_WEBHOOK_URL and/or FENDIX_TEAMS_WEBHOOK_URL; whichever are set receive alerts. FENDIX_NOTIFY_MIN_SEVERITY controls the floor (default: CRITICAL). FENDIX_NOTIFY_DEDUP_WINDOW (Go duration, default 1h) prevents re-alerting the same finding ID within the window (in-memory; restart re-arms). Per-sink errors are isolated so a failing Teams endpoint doesn't block Slack delivery.
v0.13.0 Complete

Offline mode + Arabic HTML + PDF executive report

May 18, 2026

  • Air-gapped CVE database + `fendix db`. A JSON snapshot format (schema v1) for OSV advisory exports. Three management subcommands: fendix db update --source <osv-export.json> ingests an OSV export into a local snapshot; fendix db list [--path] prints snapshot metadata; fendix db verify [--path] prints the SHA-256 for integrity checking. New --offline and --offline-db <path> flags on fendix scan enable fully air-gapped operation. Designed for government / enterprise environments with no outbound internet access.
  • Arabic HTML report + i18n foundation. fendix scan and fendix report accept --lang ar to render an HTML report right-to-left with Arabic strings. Adding a new language is a single new constructor plus a switch case. JSON, SARIF, and PDF outputs stay English (machine-consumed; localisation would break downstream tooling). Unknown --lang values fall back to English with a stderr warning.
  • PDF executive report via `--format pdf`. New PDF output format via fendix scan --format pdf and fendix report --format pdf. Structure: cover page → executive summary with severity-counts table and top-3 findings → paginated findings table with severity-coloured cells → remediation plan (CRITICAL + HIGH only) → metadata appendix. New --classification <text> flag (default INTERNAL) renders a red classification banner at the top-right of every page; empty string disables the banner. Uses github.com/go-pdf/fpdf (MIT, pure Go, no CGo). Arabic PDF is deferred — fpdf's built-in fonts do not render Arabic glyphs.
v0.12.0 Complete

Unified Go/JS/IaC textscan SAST engine

May 18, 2026

  • Unified regex SAST engine. A single codebase drives Go, JavaScript/TypeScript, Dockerfile, and Kubernetes YAML rules using shared scanner scaffolding. 16 rules total across 4 language targets: Go rules (SQL injection via string concat, exec.Command shell invocation, weak hash for passwords, hardcoded AWS key ID); JS/TS rules (eval with non-literal arg, innerHTML from non-literal, child_process.exec, document.write, require with non-literal path, hardcoded AWS key); IaC rules (Dockerfile FROM without privilege drop, ADD vs COPY, :latest tag; Kubernetes privileged: true, hostNetwork: true, allowPrivilegeEscalation: true, runAsUser: 0).
  • Extension-based routing. Filename extension determines which rule set applies: .go → Go rules; .js / .ts / .jsx / .tsx → JS rules; Dockerfile / *.dockerfile → Docker rules; .yaml / .yml → Kubernetes rules (heuristic: skips files that look like GitLab/CircleCI CI configs). Skips noisy build directories: node_modules, vendor, .git, build, dist.
  • Pure stdlib — no new deps, no CGo. The textscan engine is wired into the orchestrator between the Semgrep and Python passes; runs whenever --code is set. Go XXE and insecure-rand rules, JS prototype-pollution and insecure-RNG rules, and Terraform HCL support are deferred follow-ups requiring either AST context or MPL-2.0 dep acceptance.

v3.4.1 shipped September 2026 — the engine images now ship Go 1.27, raising govulncheck's module ceiling from 1.25; no scanner, fingerprint or exit-code changes, and the Go module floor stays 1.25. v3.4.0 shipped September 2026 — a scan can no longer look complete when it wasn't: every analyzer records whether it ran and why not, the report carries a coverage block that names the gaps, a URL scan with zero endpoints writes its report instead of vanishing, and two opt-in flags turn a coverage gap into a failing build. v3.3.0 shipped September 2026 — an upgrade no longer splits a finding you were already tracking into a closed one and a new one, and the list of checks a scan ran is built from what completed rather than what was configured. v3.2.0 — every blocking decision explains itself. A BLOCK now carries the policy it was made under and the evidence class that justified it, all the way through Fendix's own storage into the SARIF you export, so a failed pipeline is answerable from the report alone. Findings held back say why, confidence scores come with the rules that produced them, and a build blocked only because confidence enforcement was switched off is labelled as such. v3.1.0 stopped findings claiming more than they proved — wildcard CORS with credentials, rate-limit prioritisation, response-aware header grading, path-traversal wording, test-fixture credentials and dependency applicability all became more precise. v3.0 gave findings a stable identity based on which rule fired, in which file, in which function, about which operation. Re-save your baselines once after upgrading from before v3.0, and rewrite any .fendix-ignore rule that pins a fingerprint: value — rules matching by path, category or rule id are unaffected.