Changelog

Earlier releases

17 changes

Configuration, quality checks, team access and a round of fixes

  • +New accounts receive the welcome sequence — day 1, day 3 and day 5 — and the two-day "anything blocking your first scan?" note. Accounts created from today onwards enter the sequence; nobody receives a backlog of older messages.
  • +A page that cannot load your data says so instead of showing you an empty one. This covers your security checklist, account activity log, team, team scans, trend chart and saved scan intent — and the checklist no longer saves over itself when it could not load.
  • +Site-verification tokens are no longer reported as possible secrets. Google, Bing, Yandex and Facebook domain-ownership tokens are published on purpose — Next.js renders them into a meta tag on every page — so flagging them cost you grade for doing the right thing. Secret detection also now weighs the name a value is assigned to, so a credential called something like `apiKey` is caught even when the value itself looks unremarkable. Your next scan may report secrets earlier ones did not.
  • +The compliance page now covers NIST SP 800-53, the CIS Critical Security Controls and the HIPAA Security Rule, alongside SOC 2, ISO 27001, OWASP and CWE. Each finding maps to specific controls, with the control's official title shown so a reviewer can check it. As before, this is an informational mapping to help you answer a security questionnaire — not an audit, a certification, or a claim that any control is satisfied. Long control lists collapse, so a tab opens on what matters.
  • +Long lists are paged. A scan report showed every finding at once — up to 500 full cards on one page — and now shows 25 at a time, worst first, so the criticals are always on the first screen. Links that jump straight to a finding still land on it, whichever page it is on. Your saved questionnaire responses are paged the same way.
  • +A pull request whose scan failed gets scanned on the retry. GitHub re-sends a delivery when a scan does not complete, but the record we write to avoid scanning the same pull request twice was also swallowing those retries — so a scan interrupted by a timeout or a transient error left the pull request with no check at all, looking exactly like the App not being installed. An interrupted scan now releases its claim, and a completed one is still never repeated.
40 changes

The scanner now checks your code against what you said it would do

  • +Actions that fail now say so. Saving notification preferences, revoking an API key or a session, deleting a saved questionnaire response, renaming a device and creating a checklist share link all report the outcome instead of assuming success, and a failed rename puts the old name back.
  • +Claiming a free Trust Page after signing up completes cleanly. If the page has already been claimed by another account, you are told that directly rather than sent back to your inbox.
  • +Deleting your account now removes everything tied to it, including your Trust Page — which previously stayed reachable by its public link — along with saved questionnaires and their per-prospect responses, custom domain verifications, project descriptions, your AI-analysis preference, dismissed prompts, review reminders and feedback. A connected GitHub App is unlinked rather than deleted, since the App still exists on GitHub.
  • +Saved scans now keep up to 500 findings, most severe first, so the detail you open matches the counts you were shown. Scans saved earlier kept fewer — re-run one to see everything it found.
  • +New: an intent check. Every other thing a scanner tells you is about code; this one is about the gap between your code and your own description of it. If your README says "customers can only see their own orders" and an endpoint returns orders without checking who is asking, you get that as a sentence: what you wrote, where you wrote it, and the endpoint that disagrees. It reads README.md, CLAUDE.md, AGENTS.md, .cursorrules, and a .xploitscan-intent file if you keep one.
  • +Benchmark figures quoted on the comparison and blog pages now match the benchmark page: XploitScan catches all 16 of the held-out third-party set.
13 changes

Findings now tell you the URL they sit behind — CLI 1.5.0

  • +CLI 1.5.0 — machine-readable scan output now names the AI builder that scaffolded the project. The terminal has shown this for a while ("Detected: Lovable project"); JSON, SARIF and the Splunk, Elastic and Datadog formats did not carry it at all, which is exactly where it is most useful — grouping or filtering findings by builder across many repositories in CI. It is context only and never affects a finding's severity or your grade.
  • +SARIF output was reporting the scanner's version as 0.1.0 regardless of which version produced it. If you upload results to GitHub code scanning, runs from different releases were indistinguishable. It now reports the real version.
  • +A finding used to give you a file and a line. It now also tells you the URL that reaches it, where one exists: "reachable at /api/webhooks/clerk". The scanner reads your project's own route table rather than guessing from folder names, so the path it shows is the path your app actually serves. Next.js, TanStack Router, React Router, Express and Flask are supported. It appears in the terminal, in JSON output, and on the finding card in the web report. Route information is shown for context only and does not change any finding's severity or your grade.
  • +Two new rules for account state that lives in the browser. The first flags an entitlement or role — a plan, a tier, an admin flag — read out of localStorage or sessionStorage and then used to decide what the user can do. Anyone can edit those values in their own browser, so the check has to happen on the server. The second is informational and flags per-account lifecycle state, such as whether onboarding is finished, being decided by browser storage alone: it is not a vulnerability, but it is why a signed-in user gets greeted as a first-time visitor on a new device.
  • +That second rule came from our own bug, and it is fixed here too: the "Welcome to XploitScan" prompt no longer appears for people who have already run a scan. Whether you are new is now answered by your scan history rather than by a flag in the browser, so signing in from a different browser or clearing site data no longer makes the product forget you.
  • +A scanner coverage fix worth naming plainly: files inside a folder called "onboarding" were being skipped during scans. The exclusion was meant to ignore our own demo fixtures and was matching far too broadly. If your project keeps real code in an onboarding folder, it was not being scanned, and your next scan may report findings that were always there. We would rather tell you that than let the number quietly change.
2 changes

The benchmark page now names the version of every scanner it compares against

  • +The methodology section of the benchmark page was showing a blank space where Bearer's version number should have been. The comparison itself was never affected — the numbers on the page are correct — but the page could not tell you which build of Bearer produced them, which is the whole point of publishing a methodology. It now names the version, and the same page states Semgrep's version the same way.
  • +If a version genuinely cannot be determined, the page now leaves it out of the sentence instead of printing an empty value. We would rather say less than show you something we did not actually measure.
2 changes

CLI 1.3.4 — please upgrade if you are on 1.3.3

  • +If you installed xploitscan 1.3.3, upgrade to 1.3.4. A change intended only to print an accurate rule count in the terminal caused the published package to carry rule definitions that belong to the paid tier. 1.3.4 removes them; the count is unchanged and still correct. Run `npm i -g xploitscan@latest`, or nothing at all if you use `npx`, which will pick up the new version on its own.
  • +The scanner's own detection benchmark now reports its coverage correctly. The page said a number of rules had no test fixtures that was wrong twice over — first by four, then by one — because the count was written by hand and then computed against a list that includes the entropy scanner, which is not one of the rules being counted. It is now derived from the rule catalog itself, so it stays right as rules are added.
12 changes

Prove you own the domain, and we'll scan the source behind your public source maps

  • +The top navigation now fits every window it is in, and collapses to the menu button at widths it cannot fill. Signed-in visitors see their own links on first paint rather than the marketing menu, and the bar stays put as you move between pages.
  • +New: if your source maps are public, we can now scan the source behind them. When a URL scan finds source maps being served, prove you control that host and we'll download them, rebuild your original TypeScript, and run the full rule set over it — real findings at file and line, with no repository access and nothing to install. It is the same scan you'd get from pointing the CLI at your code, reached from a URL box.
  • +Proving it takes about a minute: we give you one line to save at /.well-known/xploitscan-verification.txt on that host, and check for it. A DNS TXT record works too if you'd rather, and if you control the zone — many apps live on a builder-provided subdomain where you don't, which is why the file comes first. The proof belongs to your account, so verifying a domain doesn't hand it to anyone else, and we re-check it rather than trusting it forever, because hosts change hands.
  • +The reconstructed scan always tells you what it could not read. Plenty of builds ship maps without the original file contents embedded, and a large map may be more than one scan will download — in either case you get the count of files that went unchecked instead of a clean-looking result over half your app. Nothing is stored: the source is rebuilt in memory for that one request and dropped.
  • +Everything the URL scan already did stays free and needs no account. The verification step exists only for the reconstructed scan, because that output is the one thing on the page that isn't already sitting in your visitors' devtools.
  • +Every verification command on those pages tells you what it can answer on your plan. Some of the checks they cover run only on a paid plan, so each command names the rules a free scan skips and says what the number it returns does and does not mean — a zero from a command whose checks never ran is not a clean result, and a command that mixes free and paid checks returns the free one's count, not nothing. Same for the closing call to action: the first scan still needs no card and no signup, and it runs the 30 free rules rather than the full 212 the Index round used.
10 changes

Scanning the same code twice now gives you the same answer

  • +Scan results are reproducible. Both AI-assisted steps — the false-positive review that removes findings, and the optional contextual analysis that adds them — now run at a fixed sampling setting, so scanning unchanged code returns the same findings and the same grade every time. Both previously ran at the model's default sampling, where a second scan could quietly differ from the first with nothing in your code having changed.
  • +Scanning a subdirectory now respects the .xploitscanignore at your project root. Previously that file was only read when it sat directly in the directory you scanned, so xploitscan scan src/ — and any CI job pointed at a single package in a monorepo — quietly scanned everything you had excluded. Paths are matched relative to the file that declares them, and a nested .xploitscanignore still takes precedence, exactly like .gitignore.
  • +The GitHub Action's outputs (grade, score, findings-count, the per-severity counts, and sarif-file) now carry real values, so you can branch on them in later workflow steps. They previously resolved to an empty string.
  • +Your Trust Page can now show how your app compares to the Vibe Security Index. When your latest scan supports it, the scanning section adds a line like "Fewer findings than 62% of the 25 Lovable apps we scanned for the Vibe Security Index" — matched to the builder that scaffolded your project where we can tell, and to the whole round where we can't. The sample size is always in the sentence, the methodology is one click away, and the line simply doesn't appear when the sample is too small to support it. It is a comparison, not a badge or a certification.
  • +The inline "I've reviewed this" comment now works where you most need it. Marking a single finding as accepted with // VC003-OK: <reason> or // ENTROPY-OK: <reason> had no effect on those two checks — the endpoint-authentication check and the high-entropy-string check — so the only way to quiet one intentionally-public endpoint or one published verification token was to exclude the whole file. Both now honour the marker, and your explanation can run across several lines instead of having to fit on one.
  • +New: scan a URL, no signup. Paste your app's address at /url-scan and see what your deployed build already tells every visitor. Top of the list is whether your source maps are publicly served — if they are, anyone can read your original file names and, where a map embeds its source, your original TypeScript, comments and all. Below that: whether your backend configuration ships to the browser, which AI builder the bundle looks like it came from, and which security headers are missing.
8 changes

Your grade now reflects your code, not your scaffold — and a public index of what AI builders ship

  • +Findings in code you didn't write no longer set your security grade. AI app builders copy shadcn/ui into your project verbatim, codegen writes into __generated__/, and READMEs contain example code that exists to show what not to do. All of it is still scanned and every finding is still reported — it just doesn't decide your grade or fail your CI build.
  • +This was a real problem, not a theoretical one: one vendored UI component uses dangerouslySetInnerHTML to set CSS variables, which trips a critical XSS rule, and a single critical caps a project at grade D. In a 20-repo study of Lovable, v0, Bolt, and Base44 projects, that critical rule fired in 16 of the 20, and most of its hits were in vendored code rather than code the author wrote. Projects graded on their own code now see a very different — and accurate — result.
  • +Nothing is hidden. Held-out findings appear in the CLI, the web report, the SARIF upload, and the GitHub Action's PR comment, each tagged "Not graded," with the count shown right next to the grade. A grade that excluded findings always says so.
  • +Prefer to grade everything? Run xploitscan scan . --grade-vendored, or set { "scan": { "gradeVendored": true } } in .xploitscanrc.
  • +New: the Vibe Security Index. That 20-repo study became a recurring public one. Each round we sample public repositories built with Lovable, v0, Bolt, and Base44, scan them with the full rule set, and publish the aggregate results — how often critical findings show up, how grades are distributed, and which issues repeat. It applies the same application-versus-scaffold split described above, so no builder is charged for a component library it copied in. No repository is ever named: every figure is an aggregate, because publishing the list would mean pointing at live vulnerabilities in other people's projects. The full methodology and every limitation we know about are published beside the numbers.
  • +Dashboard: choosing "All Projects" now shows a genuine portfolio grade — the average across each project's most recent scan, with total open findings by severity beside it. It previously showed whichever single project you happened to scan last, which read as your overall posture when it wasn't. The portfolio grade now matches the one on your reports and exported PDFs.
5 changes

A smoother path from first scan to signed up, and docs that match the CLI exactly

  • +The live demo scanner now gives you 3 scans of your own code per day, plus unlimited scans of the sample code — so you can kick the tires properly before creating an account. Try it from the new Live Demo link in the nav.
  • +Pricing buttons now take you straight to sign-up with your plan and billing interval pre-selected, and signing in returns you to whatever you were doing instead of dropping you on the dashboard.
  • +Anonymous and free-plan web scans now run the 30-rule free set — the same set the free plan gets in the CLI and everywhere else — and every scan result reports exactly how many rules ran. Paid plans scan with all 210+ rules on every surface.
  • +Documentation refresh: the docs and guides now match CLI 1.2.2 exactly — current flags (--diff, --watch, the SIEM output formats), the real .xploitscanrc reference, complete GitHub Action inputs and outputs, and an API reference listing the actual public endpoints.
  • +Slack and Discord webhook settings (Pro) now save to your account instead of a single browser. Configure them once in Settings → Webhooks and scan-complete notifications fire for every scan you upload — web, CLI, or CI. Settings previously saved in this browser are picked up automatically; just hit Save once to finish the move.
3 changes

We added a benchmark case we can't detect (on purpose)

  • +The held-out benchmark now includes a real-world broken-access-control (BOLA) case — a logged-in user editing another user's record — that no scanner we test catches today, including ours. The held-out score is now 15 of 16, with the miss shown openly on the benchmark page. Static analysis genuinely struggles with authenticated-but-not-authorized bugs, and we'd rather show you that gap than hide it.
  • +Scans now recognize what built your project: reports say "Detected: Lovable + Cursor project" when the scaffold is unambiguous, so findings read in the context of what those tools typically get wrong.
  • +Improved IDOR detection for Express and Hono apps: routes that fetch a record by a request-supplied ID (URL, body, or query) without an ownership check are now flagged — tuned to avoid false positives on routes that already enforce ownership. The new held-out case above is a harder shape those improvements don't yet cover.