StackAttestTechnical Trust
Bolt security audit

Audit the application Bolt generated, before strangers use it

A prompt-generated application arrives complete, which is the useful part and also the part worth checking. Every decision inside it was taken in one pass: where the line between browser and server falls, what the permission checks actually test, which packages came along. None of those were wrong on purpose, and none of them were argued about.

Scan a live appValidate a repositorySee an example Passport

What gets tested, and how strongly

Three layers, each producing a different strength of evidence. Start with whichever you can run today; the report names the ones that ran and the ones that did not.

Public URL scan

E4
URL scan

Tests the deployed application from outside, the way any visitor reaches it: transport security, security response headers, and what the running service discloses about itself. It needs nothing but the address, and what it observes it observes against the running system. Its limit is reach rather than strength: a URL can never establish authorisation, data-layer or backup posture, and those controls stay uncovered.

Repository validation

E2
Repository

Reads the source: where secrets live, whether authorisation is enforced on the server or only in the interface, whether data access is injection safe, and which dependencies carry known critical vulnerabilities. Findings cite the file they came from, so a result is checkable rather than asserted.

Runtime validation

E4
Runtime

Builds and runs the application in an isolated environment and probes the running system. This is the layer that answers questions reading code cannot: whether the deployed configuration actually refuses an unauthorised request, and whether error responses leak internals under real conditions.

What is worth checking in a generated full-stack app

These are failure modes common to applications written in one pass, not a claim about your application. The audit establishes which of them are actually present.

The browser and server line was drawn for you

A generator decides what runs in the page and what runs behind an endpoint, and it decides in a single pass. Work that guards data is correct in the demo wherever it sits, and only correct in production if it sits on the server. This is the decision that most often has to be moved afterwards.

Permission checks that landed where they were visible

A check written into the component that renders a record is a check whose author could watch it working. A request that never loads that component never meets it. Whether ownership is tested again on the server is a separate question from whether the interface hides the button, and only one of the two survives a direct call.

Defaults that arrived with the application

It came configured: an origin policy, an error verbosity, a sign-up rule, a session length. Nobody chose them, so nobody has revisited them. The settings that make a first run frictionless are usually the same settings that make a public deployment talkative.

Integrations wired until the flow completed

Payment and webhook handlers, third-party calls, an upload path. They were built until the demo worked end to end, and a demo never sends an unsigned payload, never replays a request and never calls the same endpoint twice. Signature verification and idempotency are not needed until somebody hostile arrives.

A dependency set that arrived in one step

A whole stack of packages appears in a single generation, none of them chosen individually. Advisories against them are public by definition, which makes this the cheapest class of finding to close and the least defensible to leave open.

The backend rules, where there is a backend

Where a Supabase project sits behind the app, the questions are row level security and which of the two keys ended up in the bundle. Those have pages of their own rather than a paragraph here, because a half-remembered version of that distinction is worse than none.

What the result looks like

An illustrative extract, not a real customer result. Every row carries the evidence grade behind it, and a control nobody could establish says so.

ControlStatusEvidenceNote
Authorisation enforced on the serverFailedE2Two routes act on an identifier supplied by the caller
Privileged keys kept out of the browser bundleVerifiedE2Nothing beyond publishable configuration reaches the client
Webhook payloads verified before they are acted onFailedE2One handler trusts an unsigned request body
Dependency advisories triagedPartialE3Two critical advisories, both with a published fix
Database row level securityUncoveredNot gradedThe project's own database rules were not reachable from the layers that ran

Mapped to published standards

Each control is tested against a named clause, so a result means something outside our own vocabulary. Mapping is not certification, and none of these bodies endorse StackAttest.

OWASP ASVS 5OWASP API Security Top 10CWENIST SSDF

What this audit is not

  • It is not a penetration test. A deterministic check and a runtime probe are not an adversarial human engagement, and there are classes of weakness only a person hunting for them will find.
  • It is not SOC 2 and does not replace it. SOC 2 attests to organisational controls over time; this validates technical controls in the software. They answer different questions for different buyers.
  • It does not replace human due diligence. It gives a reviewer repeatable evidence to start from, which is a different thing from being the reviewer.
  • Controls the run could not reach are reported as uncovered rather than passed. A result you did not earn is worse than no result.
  • It is not affiliated with Bolt and does not integrate with it. StackAttest validates the application that was produced, which is a different job from inspecting the tool that produced it.

Questions

What does a Bolt security audit actually test?

Named technical controls in the application rather than anything about the prompt: whether authorisation is enforced on the server, whether a privileged key is reachable from the browser, whether data access is injection safe, whether dependencies carry known critical advisories, and how the running system answers a request it should refuse. Every result records how it was established.

Do you integrate with Bolt?

No. StackAttest is not affiliated with Bolt and does not integrate with it or read anything from it. The tool writes the software, and this independently validates the software that was written, from the deployed address, from the source, or from the running system.

Does this mean apps built with Bolt are insecure?

No, and the page is written to avoid implying it. What is true of any application assembled in one pass is that it contains decisions nobody deliberated over, so the useful question is which of them are present in yours. That question has an answer and the audit produces it.

My Bolt app uses Supabase. Is the database covered?

The source layer reads how your code talks to the database and the runtime layer tests whether the deployed system refuses what it should refuse. The policy questions that are specific to Supabase, row level security and the difference between the two keys, are covered on the Supabase pages linked below rather than summarised here.

Do you need the code?

For source-level evidence, yes, through a read-only connection to wherever the project lives. Without it you can still scan the deployed address and run runtime validation, which produce evidence about the deployed system rather than the code, and the report is explicit about which was which.

I have changed a lot of it by hand since. Does that matter?

Not to the audit. Controls are tested against the application as it stands today, not against its history, and no result depends on who or what wrote a given line.

Related

Vibe code auditReplit security auditSupabase security auditSupabase RLS auditAI app security audit

Find out what is actually true of your application

Start with the layer you can run today. The report says which layers ran and what they could not reach, so the result is honest about its own limits.

Scan a live appValidate a repository