Safeguard
Application Security

How AI-powered SAST auto-fix engines actually work

GitHub says Copilot Autofix resolves two-thirds of flagged vulnerabilities with little editing; Snyk claims 80% fix accuracy. Here's the pipeline behind both numbers.

Safeguard Research Team
Research
Updated 8 min read

In February 2025, GitHub expanded Copilot Autofix to cover CodeQL alert types representing 29% of all alerts it produces, and reported that the change alone drove an 8% overall increase in alerts with an available autofix and a 270% increase in autofixes generated for that specific alert group. Both numbers describe the fast-maturing category of AI-powered SAST auto-fix. GitHub's own numbers claim the feature resolves "more than two-thirds" of found vulnerabilities with little or no editing required. Snyk, which shipped a comparable feature as DeepCode AI Fix and rebranded it Agent Fix with an agentic architecture update around May 2026, reports 80% fix accuracy and an 84% reduction in mean time to remediate, built on dynamic few-shot prompting against a database of more than 35,000 expert-written fixes. Neither vendor is describing a single model that reads code and writes patches from scratch — both are describing a two-stage pipeline where a deterministic pattern matcher does the finding, and an LLM does the fixing, constrained tightly to what the matcher already proved. If you're wondering what does SAST mean in this context: it's static application security testing, analyzing source code without running it, which is exactly the pattern-matching stage both pipelines build on. This post walks through how that pipeline actually works, and where both vendors still insist a human has to look before the patch ships.

What does the pattern-matching stage actually hand off to the LLM?

The pattern-matching stage is a conventional SAST engine — CodeQL's dataflow queries, Semgrep's rule engine, or an equivalent taint analyzer — and its job is to produce structured, verifiable context, not just a line number. Taint analysis identifies the exact source (say, a request parameter) and sink (a database call or shell command) and traces the path connecting them. The output handed to the LLM stage typically includes the rule or query ID that fired, the vulnerable AST node, the full data-flow path from source to sink, and enough of the surrounding function to give the model working context without exposing the entire codebase. This matters because it means the LLM is never asked "is there a vulnerability here" — that question was already answered deterministically. The LLM's task is narrower and better-suited to what LLMs are actually good at: given a proven vulnerable pattern and its context, propose a syntactically and semantically valid patch that closes it. Constraining scope this way is also what keeps the patch focused on the flagged region instead of producing sprawling, hard-to-review rewrites of unrelated code.

Why does patch generation get constrained to the flagged region instead of free-form rewriting?

Constraining the LLM to the flagged lines or function is a deliberate guardrail, not a limitation of the model — it's what keeps auto-fix reviewable and keeps the blast radius of a wrong suggestion small. If a patch model could rewrite anywhere in a file, a single false or overzealous fix could silently touch logic far from the vulnerability, making the diff harder to review and easier for a reviewer to rubber-stamp without checking. By scoping generation to the source-to-sink path CodeQL or Semgrep already identified, vendors get a patch that a human (or an automated test) can compare directly against the original vulnerable pattern: did this specific sanitization, parameterization, or escaping get added at this specific line? Snyk's approach of grounding generation in a curated library of 35,000+ prior expert fixes serves the same goal from a different angle — it biases the model toward patterns that have already been reviewed as correct fixes for a given CWE class, rather than letting it improvise a novel remediation approach for each finding.

What automated validation happens before a human ever sees the diff?

Before a proposed patch reaches a pull request, both GitHub's and Snyk's pipelines run it through automated checks meant to catch the cases where the model produced something plausible-looking but broken. That typically means confirming the patched code still compiles or parses, and where a test suite exists, running it to catch regressions the patch introduces. This stage exists because LLM patch generation, even when scoped tightly, can still produce a fix that looks like valid code but changes behavior in a way the original taint path didn't require — for example, over-sanitizing an input in a way that breaks a legitimate use case. Automated validation is a filter, not a guarantee: a green test suite proves the patch didn't break what the tests cover, not that it's the correct or complete fix for the vulnerability, especially in codebases with weak test coverage to begin with.

Where do both vendors say human review is still required?

GitHub publishes a document titled "Responsible use of Copilot Autofix" that explicitly recommends manual review of every suggestion before merge, and Snyk — despite describing Agent Fix output as "production-ready" — still gates it behind a pull request rather than direct commits to a default branch. The consistent reasons across both vendors' own guidance: cross-file or architectural vulnerabilities where the fix isn't localized to a single function the model can see in context; business-logic-dependent fixes, particularly around authentication and authorization, where correctness depends on intent a model can't reliably infer from code alone; breaking-change risk on public or widely-called APIs, where a technically-correct security fix can still break callers; and ordinary false-positive triage, since pattern matchers still over-flag and an LLM can generate a confident, well-formatted patch for a finding that wasn't actually exploitable in the first place.

How does this differ from AI-assisted dependency remediation?

SAST auto-fix and dependency (SCA) remediation solve related but distinct problems, and it's worth being precise about which one a given tool actually does. SAST auto-fix generates new source code — a parameterized query in place of string concatenation, an escaped output in place of raw interpolation — for a vulnerability the pattern matcher located inside your own code. Dependency remediation, by contrast, works one layer up: it identifies a vulnerable version of a third-party package and determines the safest upgrade path, handling transitive conflicts and lock-file updates rather than rewriting your logic. Safeguard's AI Remediate, powered by Griffin AI, is built for that second problem — upgrading vulnerable packages, resolving lock-file conflicts, and applying configuration fixes across ecosystems including npm, PyPI, Maven, Go modules, Cargo, Bundler, NuGet, and Composer, with breaking-change detection (Safe/Minor/Major/Critical) gating what gets auto-created as a pull request versus flagged for manual review. It is not a source-level SAST code-pattern rewriter in the Copilot Autofix or Snyk Agent Fix sense, and treating the two categories as interchangeable is a common source of confusion when comparing vendor claims.

Are GitHub and Snyk the only vendors doing this?

No — this post uses GitHub and Snyk because both publish concrete numbers, but the pattern-match-then-patch architecture isn't exclusive to them. Checkmarx SAST and other established static analysis platforms have shipped comparable AI-assisted remediation features, and Gartner's SAST coverage has increasingly treated auto-remediation as a maturity signal analysts ask vendors about directly, rather than a novelty. The core SAST definition hasn't changed for any of these vendors — a SAST test still means static analysis of source code without execution — what's new is the second stage bolted onto the same deterministic finding.

What should a security team actually check before trusting an auto-fix rate?

A headline fix-accuracy number is only meaningful alongside the denominator it was measured against, and both GitHub's and Snyk's published figures apply to specific, bounded alert categories rather than every possible finding a scanner can produce. GitHub's 270% autofix-generation increase followed from deliberately expanding coverage to alert types representing 29% of all CodeQL alerts — meaning the remaining alert types were, at that point, still outside autofix's scope entirely. A team evaluating these tools should ask which CWE categories and languages the vendor's own numbers cover, whether the reported accuracy was measured pre- or post-human-edit, and whether validation ran full integration tests or just a compile check — the same diligence worth applying to raw SAST scans before trusting a vendor's headline finding-count, since a scanner that flags more also has more surface area for autofix to get wrong. None of that makes the underlying architecture less useful — pairing deterministic taint analysis with scoped, validated LLM patch generation is a real improvement over either technique alone — but the gap between "generates a plausible diff" and "safe to merge unreviewed" is exactly where the human-in-the-loop gate both vendors publish still earns its place.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.