PreFlight catches security issues. This is where we explain them — the patterns we look for, the real-world incidents behind the threat-intel, and the architecture shapes that shape (or break) your security posture. Read once, build safer forever.
15 shapes · 15 published · 0 draft
An Express/Fastify/Koa server with no front end. This is the shape where the security probes bite hardest, because every input is remote, untrusted, and arrives without a human in front of it.
Updated 2026-05-15A package with a bin entry and no UI framework. The risk is not a browser, it is the shell, the filesystem, and the fact that other people's scripts will pass it untrusted arguments.
Updated 2026-05-15A CLI that renders its interface with React-for-terminals (Ink). The React part is a distraction from the real surface, which is still the shell and the filesystem of whoever ran it.
Updated 2026-05-15Code meant to be consumed, not deployed. The security posture inverts: you are not protecting an app, you are an input to everyone else's, so your supply-chain hygiene is now their risk.
Updated 2026-05-15A Node-backed desktop shell. The opposite default from Tauri: the renderer can reach Node unless you explicitly close that door, so nodeIntegration and contextIsolation are the load-bearing settings.
Updated 2026-05-15A Rust-backed desktop shell with a webview UI. Safer-by-default than Electron because there is no Node in the webview, but the allowlist is the new boundary and widening it to "make it work" is the failure.
Updated 2026-05-15Multiple package.json files in one repository, services meant to ship independently. At this scale boundary discipline matters more than any single check, and a broken boundary is a security boundary that does not exist.
Updated 2026-05-15A React Native / Expo app that ships to a device. The defining shift: the binary is in the attacker's hands, so anything bundled or stored insecurely is extractable, and there is no server boundary protecting the client.
Updated 2026-05-15The healthy SPA. A React/Vue/Svelte app split across many files, no single file owning the world. This is what good looks like and the contrast that makes the monolith shape legible.
Updated 2026-05-15The "everything in one giant file" shape AI tools default to. Why a 4000-line single-file app is a security problem and not only a tidiness one, the seams to cut on, and the habit that keeps the architecture reviewable.
Updated 2026-05-15A codebase dominated by .ipynb files. Notebooks invite the exact habits that leak: a key pasted into a cell, an output committed with data in it, a model file loaded from anywhere.
Updated 2026-05-15A Python codebase (Django, Flask, FastAPI, or scripts). The classifier switches probe targeting to Python source; the recurring vibe-coded failures are the framework default left on and the unsafe load left in.
Updated 2026-05-15Next.js, Remix, or SvelteKit rendering on the server. The defining failure mode is the server/client boundary: code that was supposed to stay on the server ending up in the bundle the browser downloads, secrets and all.
Updated 2026-05-15A landing-page-with-bundler shape, Vite or esbuild emitting plain HTML/CSS/JS. The minimum-viable hardening that turns "a static site, nothing to attack" into one that actually survives a CSP and a Lighthouse pass.
Updated 2026-05-15A framework that pre-renders to static HTML at build time (Astro static, Next export). No server at request time, but the build is now a trust boundary, and a build-time secret is a shipped secret.
Updated 2026-05-15