<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: FlawPilot</title>
    <description>The latest articles on DEV Community by FlawPilot (@flawpilot).</description>
    <link>https://dev.to/flawpilot</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4062116%2F65b712d3-54d2-4489-a0c5-e024c9d1baaf.png</url>
      <title>DEV Community: FlawPilot</title>
      <link>https://dev.to/flawpilot</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/flawpilot"/>
    <language>en</language>
    <item>
      <title>Node.js October 2026 Security Update: A Practical Patch Guide</title>
      <dc:creator>FlawPilot</dc:creator>
      <pubDate>Fri, 30 Oct 2026 08:17:10 +0000</pubDate>
      <link>https://dev.to/flawpilot/nodejs-october-2026-security-update-a-practical-patch-guide-31d3</link>
      <guid>https://dev.to/flawpilot/nodejs-october-2026-security-update-a-practical-patch-guide-31d3</guid>
      <description>&lt;p&gt;The Node.js project released security updates for the 22.x, 24.x, and 26.x release lines on October 21, 2026.&lt;/p&gt;

&lt;p&gt;The release fixes ten vulnerabilities. Four are rated high severity, three medium, and three low. The issue getting the most attention is CVE-2026-111497, an out-of-bounds write in Node.js's Brotli decoder that can lead to process crashes, memory disclosure, or remote code execution.&lt;/p&gt;

&lt;p&gt;The fix is available, but updating one version file is not enough.&lt;/p&gt;

&lt;p&gt;Node.js may be installed in production servers, container images, background workers, build systems, CI runners, serverless environments, and local toolchains. A complete response requires teams to locate every affected runtime, replace it, redeploy the service, and verify what is actually running.&lt;/p&gt;

&lt;p&gt;This guide focuses on that process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which Node.js versions contain the fixes?
&lt;/h2&gt;

&lt;p&gt;The fixed versions published with the advisory are:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Release line&lt;/th&gt;
&lt;th&gt;Fixed version&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Node.js 22&lt;/td&gt;
&lt;td&gt;22.23.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node.js 24&lt;/td&gt;
&lt;td&gt;24.22.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node.js 26&lt;/td&gt;
&lt;td&gt;26.12.1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you use one of these release lines, upgrade to the listed version or a newer secure release in the same supported line.&lt;/p&gt;

&lt;p&gt;If you read this article after October 2026, confirm the latest version on the official Node.js website. Newer security and maintenance releases may already be available.&lt;/p&gt;

&lt;h2&gt;
  
  
  What makes the Brotli vulnerability serious?
&lt;/h2&gt;

&lt;p&gt;Brotli is a compression format used across the web. Node.js applications can process Brotli data through the &lt;code&gt;node:zlib&lt;/code&gt; module.&lt;/p&gt;

&lt;p&gt;CVE-2026-111497 affects the bundled Brotli decoder. Specially formed compressed input can cause the decoder to write beyond the boundary of an internal buffer.&lt;/p&gt;

&lt;p&gt;That type of memory corruption can have several outcomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Node.js process crashes.&lt;/li&gt;
&lt;li&gt;Data from process memory may be exposed.&lt;/li&gt;
&lt;li&gt;An attacker may be able to execute code within the affected process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important condition is whether an attacker can provide Brotli data that the application decompresses. A public web service, proxy, upload processor, or integration may create that path directly or indirectly.&lt;/p&gt;

&lt;p&gt;Do not assume an application is unaffected simply because its own responses use gzip instead of Brotli. Review where the service accepts compressed content and how upstream systems transform traffic.&lt;/p&gt;

&lt;p&gt;No published configuration change replaces the runtime update. The reliable remediation is to run a patched Node.js version.&lt;/p&gt;

&lt;h2&gt;
  
  
  The other high-severity issues
&lt;/h2&gt;

&lt;p&gt;The same release fixes three additional high-severity vulnerabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  CVE-2026-105482: NUL characters in DNS names
&lt;/h3&gt;

&lt;p&gt;The affected DNS functions could truncate a hostname at a NUL character when passing it to c-ares.&lt;/p&gt;

&lt;p&gt;An application might validate one hostname but resolve another. For example, a string could appear to belong to an approved domain during validation while the resolver processes only the attacker-controlled part before the NUL character.&lt;/p&gt;

&lt;p&gt;This can matter in systems that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validate webhook destinations&lt;/li&gt;
&lt;li&gt;Use hostname allowlists&lt;/li&gt;
&lt;li&gt;Fetch remote resources&lt;/li&gt;
&lt;li&gt;Restrict server-side outbound requests&lt;/li&gt;
&lt;li&gt;Resolve user-provided domains&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If a security decision depends on validating a hostname before resolving it, update the runtime and test that workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  CVE-2026-105483: Fullwidth digits in an IP address
&lt;/h3&gt;

&lt;p&gt;Node.js TLS hostname verification could treat an IPv4 address written with certain non-ASCII digits as a DNS name instead of an IP address.&lt;/p&gt;

&lt;p&gt;That difference could allow a certificate to pass a hostname check when it should be rejected.&lt;/p&gt;

&lt;p&gt;This vulnerability affects Node.js 24.x and 26.x.&lt;/p&gt;

&lt;h3&gt;
  
  
  CVE-2026-106069: Non-canonical IPv4 notation
&lt;/h3&gt;

&lt;p&gt;Another TLS issue involved hostnames that could be interpreted as IP addresses in different ways.&lt;/p&gt;

&lt;p&gt;Node.js and the operating system resolver could normalize the same input differently. Under the right conditions, the application could connect to one address while validating the certificate against another.&lt;/p&gt;

&lt;p&gt;This affects software that relies on Node.js hostname verification for outbound TLS connections.&lt;/p&gt;

&lt;h2&gt;
  
  
  A medium-severity issue worth checking separately
&lt;/h2&gt;

&lt;p&gt;CVE-2026-106074 involves the entropy caches behind functions such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randomUUID&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randomUUIDv7&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randomInt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When these functions are called while building a user-land startup snapshot or a single executable application that uses a snapshot, cached random values may be stored in the resulting artifact.&lt;/p&gt;

&lt;p&gt;Processes created from that artifact can then produce the same early sequence of values.&lt;/p&gt;

&lt;p&gt;This can lead to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UUID collisions between processes&lt;/li&gt;
&lt;li&gt;Repeated identifiers&lt;/li&gt;
&lt;li&gt;Values that are more predictable than expected&lt;/li&gt;
&lt;li&gt;Incorrect assumptions about uniqueness&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The issue is most relevant when an application uses startup snapshots or Node.js single executable applications. Teams using those features should check whether random-value APIs run during the build phase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Build a runtime inventory
&lt;/h2&gt;

&lt;p&gt;Before changing anything, list every environment that may contain Node.js.&lt;/p&gt;

&lt;p&gt;Start with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Public APIs and web applications&lt;/li&gt;
&lt;li&gt;Internal services&lt;/li&gt;
&lt;li&gt;Queue consumers and background workers&lt;/li&gt;
&lt;li&gt;Scheduled jobs&lt;/li&gt;
&lt;li&gt;Serverless functions&lt;/li&gt;
&lt;li&gt;Container images&lt;/li&gt;
&lt;li&gt;CI/CD runners&lt;/li&gt;
&lt;li&gt;Build servers&lt;/li&gt;
&lt;li&gt;Preview and staging deployments&lt;/li&gt;
&lt;li&gt;Developer images used for reproducible builds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run the following command inside each real environment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not rely only on &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"engines"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;=22"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That configuration describes an expected range. It does not prove which binary is running in production.&lt;/p&gt;

&lt;p&gt;Record the service name, environment, current version, deployment method, owner, and required update. A small inventory table is enough if it covers every runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Locate every version pin
&lt;/h2&gt;

&lt;p&gt;Node.js versions are often declared in more than one place.&lt;/p&gt;

&lt;p&gt;Search for files and settings such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.nvmrc&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.node-version&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Dockerfile&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Docker Compose files&lt;/li&gt;
&lt;li&gt;CI workflow files&lt;/li&gt;
&lt;li&gt;Infrastructure-as-code templates&lt;/li&gt;
&lt;li&gt;Serverless runtime settings&lt;/li&gt;
&lt;li&gt;Kubernetes manifests&lt;/li&gt;
&lt;li&gt;Buildpack configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, a Dockerfile may contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:22.23.3-alpine&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Updating &lt;code&gt;.nvmrc&lt;/code&gt; will not change that image. The Dockerfile needs its own update, followed by a fresh build and deployment.&lt;/p&gt;

&lt;p&gt;Avoid broad version tags if your release process requires reproducible builds. Pin a patched version or an approved immutable image digest, then manage future updates through your normal dependency process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Rebuild instead of restarting
&lt;/h2&gt;

&lt;p&gt;Restarting a container does not install a newer Node.js binary. It starts the same image again.&lt;/p&gt;

&lt;p&gt;For containerized services:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Update the base-image reference.&lt;/li&gt;
&lt;li&gt;Pull the current base image.&lt;/li&gt;
&lt;li&gt;Rebuild the application image.&lt;/li&gt;
&lt;li&gt;Run tests against the new image.&lt;/li&gt;
&lt;li&gt;Push the new artifact.&lt;/li&gt;
&lt;li&gt;Deploy it.&lt;/li&gt;
&lt;li&gt;Verify the Node.js version inside the running container.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Be careful with cached build layers. A successful image build does not always prove that the intended base image was downloaded.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Test the areas affected by the release
&lt;/h2&gt;

&lt;p&gt;Run the application's normal test suite, then focus on behavior connected to the patched components.&lt;/p&gt;

&lt;p&gt;Useful test areas include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compressed request and response handling&lt;/li&gt;
&lt;li&gt;File uploads containing compressed content&lt;/li&gt;
&lt;li&gt;DNS resolution of user-provided hostnames&lt;/li&gt;
&lt;li&gt;Outbound HTTPS requests&lt;/li&gt;
&lt;li&gt;Certificate and hostname validation&lt;/li&gt;
&lt;li&gt;Keep-alive connection reuse&lt;/li&gt;
&lt;li&gt;Random UUID and integer generation&lt;/li&gt;
&lt;li&gt;Startup snapshots&lt;/li&gt;
&lt;li&gt;Single executable builds&lt;/li&gt;
&lt;li&gt;Permission Model filesystem rules&lt;/li&gt;
&lt;li&gt;ZIP processing in Node.js 26&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You do not need to create exploit code to validate the update. Confirm the new runtime, run functional and regression tests, and ensure the application still behaves correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Deploy and verify the live process
&lt;/h2&gt;

&lt;p&gt;After deployment, check the running environment again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For containers, run the command inside the deployed container rather than on the host.&lt;/p&gt;

&lt;p&gt;Also verify every replica and worker group. A rolling deployment can leave an old instance running if the rollout stalls or a health check fails.&lt;/p&gt;

&lt;p&gt;Useful post-deployment checks include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All replicas report the patched version.&lt;/li&gt;
&lt;li&gt;Old container images are no longer serving traffic.&lt;/li&gt;
&lt;li&gt;Background workers were restarted with the new artifact.&lt;/li&gt;
&lt;li&gt;Scheduled jobs use the updated runtime.&lt;/li&gt;
&lt;li&gt;Error and crash rates remain normal.&lt;/li&gt;
&lt;li&gt;Core HTTP and TLS workflows still pass.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The task is complete only when the production runtime has been verified.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about Node.js 20 and older versions?
&lt;/h2&gt;

&lt;p&gt;Node.js 20 and earlier release lines are not part of this security update.&lt;/p&gt;

&lt;p&gt;That does not mean they are protected. It means they are outside the supported lines receiving these fixes.&lt;/p&gt;

&lt;p&gt;If an application still depends on an end-of-life Node.js release, create a migration plan to a supported major version. Include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dependency compatibility checks&lt;/li&gt;
&lt;li&gt;Framework compatibility checks&lt;/li&gt;
&lt;li&gt;Automated tests&lt;/li&gt;
&lt;li&gt;Staging validation&lt;/li&gt;
&lt;li&gt;Performance checks&lt;/li&gt;
&lt;li&gt;A rollback plan&lt;/li&gt;
&lt;li&gt;A production migration date&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Installing the last available patch for an unsupported release does not address vulnerabilities discovered after support ended.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common incomplete fixes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Updating local development only
&lt;/h3&gt;

&lt;p&gt;The developer sees a patched version, but the deployment image still contains the vulnerable binary.&lt;/p&gt;

&lt;h3&gt;
  
  
  Updating the main API but not its workers
&lt;/h3&gt;

&lt;p&gt;The web service is patched while queue consumers and scheduled jobs continue using an older image.&lt;/p&gt;

&lt;h3&gt;
  
  
  Merging the update without deploying it
&lt;/h3&gt;

&lt;p&gt;The repository is correct, but production still runs the previous build.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rebuilding from a cached base image
&lt;/h3&gt;

&lt;p&gt;The build completes successfully while preserving an outdated runtime layer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ignoring CI runners
&lt;/h3&gt;

&lt;p&gt;Production is patched, but build systems continue processing repositories and network data with an affected runtime.&lt;/p&gt;

&lt;h3&gt;
  
  
  Waiting for evidence of exploitation
&lt;/h3&gt;

&lt;p&gt;Security patching should be based on confirmed exposure to a vulnerable version, not on whether the team has already noticed an incident.&lt;/p&gt;

&lt;h2&gt;
  
  
  A concise remediation checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Read the official Node.js advisory.&lt;/li&gt;
&lt;li&gt;[ ] Identify every Node.js runtime in production and supporting systems.&lt;/li&gt;
&lt;li&gt;[ ] Upgrade Node.js 22, 24, and 26 to fixed versions.&lt;/li&gt;
&lt;li&gt;[ ] Plan migration for end-of-life release lines.&lt;/li&gt;
&lt;li&gt;[ ] Update container base images and CI configurations.&lt;/li&gt;
&lt;li&gt;[ ] Rebuild all affected artifacts.&lt;/li&gt;
&lt;li&gt;[ ] Run functional and regression tests.&lt;/li&gt;
&lt;li&gt;[ ] Deploy through the normal release process.&lt;/li&gt;
&lt;li&gt;[ ] Verify the runtime inside every live environment.&lt;/li&gt;
&lt;li&gt;[ ] Record the completed update and remaining exceptions.&lt;/li&gt;
&lt;li&gt;[ ] Monitor application health after deployment.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;CVE-2026-111497 makes the October 2026 Node.js release an important update, but the broader lesson is about runtime management.&lt;/p&gt;

&lt;p&gt;Teams often know which Node.js version they intend to use. Security incidents expose the gap between intended versions and deployed versions.&lt;/p&gt;

&lt;p&gt;A dependable patching process closes that gap:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Inventory every runtime.&lt;/li&gt;
&lt;li&gt;Update every version pin.&lt;/li&gt;
&lt;li&gt;Rebuild affected artifacts.&lt;/li&gt;
&lt;li&gt;Test the application.&lt;/li&gt;
&lt;li&gt;Deploy the update.&lt;/li&gt;
&lt;li&gt;Verify the live process.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The version change may take a few minutes. Proving that no affected runtime remains is the part that requires discipline.&lt;/p&gt;

</description>
      <category>node</category>
      <category>security</category>
      <category>webdev</category>
      <category>devops</category>
    </item>
    <item>
      <title>Anthropic’s OSS Scanner: What Open-Source Maintainers Need to Know</title>
      <dc:creator>FlawPilot</dc:creator>
      <pubDate>Fri, 23 Oct 2026 08:58:05 +0000</pubDate>
      <link>https://dev.to/flawpilot/anthropics-oss-scanner-what-open-source-maintainers-need-to-know-26g5</link>
      <guid>https://dev.to/flawpilot/anthropics-oss-scanner-what-open-source-maintainers-need-to-know-26g5</guid>
      <description>&lt;p&gt;Anthropic has launched OSS Scanner, a free service that uses AI agents to search eligible open-source repositories for security vulnerabilities.&lt;/p&gt;

&lt;p&gt;The headline is easy to understand. The operating model deserves more attention.&lt;/p&gt;

&lt;p&gt;OSS Scanner does not work like Anthropic’s usual coordinated vulnerability disclosure process. Instead of waiting for people to validate every finding, the service can send model-generated reports directly to participating maintainers.&lt;/p&gt;

&lt;p&gt;That choice makes reporting faster. It also means maintainers must be prepared to verify the results themselves.&lt;/p&gt;

&lt;p&gt;This article explains how the service works, which projects can apply, what maintainers may receive and what teams should prepare before enrolling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Anthropic built OSS Scanner
&lt;/h2&gt;

&lt;p&gt;AI models can examine far more code than a small group of security researchers can manually review.&lt;/p&gt;

&lt;p&gt;That creates a bottleneck. A model may identify thousands of possible vulnerabilities, but each result still needs someone to reproduce it, evaluate its impact and decide whether the proposed fix is safe.&lt;/p&gt;

&lt;p&gt;Anthropic already uses a coordinated vulnerability disclosure process for its security research. In that workflow, people review findings before maintainers receive them. Human review helps filter incorrect reports and adds useful context, but it takes time.&lt;/p&gt;

&lt;p&gt;Some established projects would rather receive possible vulnerabilities immediately. Their maintainers already have the experience and processes needed to perform their own triage.&lt;/p&gt;

&lt;p&gt;OSS Scanner provides that faster route. Participating projects receive reports directly from Anthropic’s models without routine human validation before delivery.&lt;/p&gt;

&lt;p&gt;The service does not remove human work. It moves part of that work from Anthropic to the project maintainer.&lt;/p&gt;

&lt;h2&gt;
  
  
  The central trade-off: speed versus prior validation
&lt;/h2&gt;

&lt;p&gt;The most important feature of OSS Scanner is also its main limitation.&lt;/p&gt;

&lt;p&gt;Reports are produced by AI models and may be incorrect, duplicated or based on a misunderstanding of the project’s threat model. Anthropic’s pipeline includes agents that examine findings, but this is not the same as an independent human confirming each issue.&lt;/p&gt;

&lt;p&gt;For a mature project, this trade-off may be reasonable. Receiving a high-quality but unverified report today could be more useful than receiving a fully reviewed report weeks later.&lt;/p&gt;

&lt;p&gt;For an under-resourced project, the same report stream could create more work than value. Maintainers may spend scarce time reproducing issues, correcting severity ratings and closing false positives.&lt;/p&gt;

&lt;p&gt;The service therefore depends on the receiving team’s capacity, not just the scanner’s capability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which projects are eligible?
&lt;/h2&gt;

&lt;p&gt;OSS Scanner is not a free scanning tool for every public repository.&lt;/p&gt;

&lt;p&gt;Anthropic evaluates applications individually using criteria influenced by Google’s OSS-Fuzz program. The service is intended for established projects that have a meaningful effect on infrastructure or user security.&lt;/p&gt;

&lt;p&gt;Factors can include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Exposure to untrusted or remotely supplied input&lt;/li&gt;
&lt;li&gt;The number of people and projects that depend on the software&lt;/li&gt;
&lt;li&gt;Project age and maintenance frequency&lt;/li&gt;
&lt;li&gt;Usage and adoption&lt;/li&gt;
&lt;li&gt;Stars and forks&lt;/li&gt;
&lt;li&gt;OpenSSF criticality score&lt;/li&gt;
&lt;li&gt;Use of an accepted open-source license&lt;/li&gt;
&lt;li&gt;Importance to security-sensitive systems or sectors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;New projects generally do not qualify. Forks are also usually excluded unless they are substantially different from the original project and independently meet the criteria.&lt;/p&gt;

&lt;p&gt;This limited access reflects the service’s risk model. Anthropic expects participating projects to keep up with serious security reports and investigate unverified findings responsibly.&lt;/p&gt;

&lt;h2&gt;
  
  
  How project enrollment works
&lt;/h2&gt;

&lt;p&gt;Core maintainers enroll through a public configuration process.&lt;/p&gt;

&lt;p&gt;A maintainer submits a pull request that adds a project configuration file. The basic configuration identifies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The repository that should be scanned&lt;/li&gt;
&lt;li&gt;The primary contact who should receive reports&lt;/li&gt;
&lt;li&gt;A Dockerfile that prepares and builds the project&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anthropic provides validation tooling so maintainers can check the configuration before submitting it. Maintainers should also build the Dockerfile locally and verify that the project’s tests work inside the resulting container.&lt;/p&gt;

&lt;p&gt;Anthropic reviews enrollment requests. It checks that the requester is connected to the project and that reports will go to an appropriate security contact.&lt;/p&gt;

&lt;p&gt;Once accepted, the project enters the scanning pipeline. The frequency of later scans is not guaranteed. It can depend on the number of enrolled projects, their usage and the capacity of the scanning system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the Dockerfile matters
&lt;/h2&gt;

&lt;p&gt;The Dockerfile gives the scanner a reproducible environment in which it can build and analyze the project.&lt;/p&gt;

&lt;p&gt;It should install the required dependencies, prepare the code and make the relevant tests or entry points available. The Dockerfile build may use network access, but the scanning agent runs offline after the environment has been created.&lt;/p&gt;

&lt;p&gt;Maintainers should treat this setup as part of the security boundary.&lt;/p&gt;

&lt;p&gt;A broken or incomplete build can limit what the scanner sees. An overly broad configuration may also include code that the project does not intend to place in scope.&lt;/p&gt;

&lt;p&gt;Before applying, maintainers should confirm that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The image builds successfully from a clean environment.&lt;/li&gt;
&lt;li&gt;Tests pass inside the container.&lt;/li&gt;
&lt;li&gt;Only the intended project is included.&lt;/li&gt;
&lt;li&gt;Required test assets are available offline.&lt;/li&gt;
&lt;li&gt;Secrets and private credentials are not baked into the image.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The quality of the scan depends partly on the quality of the environment supplied to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The threat model may be the most valuable configuration
&lt;/h2&gt;

&lt;p&gt;Projects can optionally provide a threat-model document.&lt;/p&gt;

&lt;p&gt;Although it is not required, this file can help prevent the scanner from making incorrect assumptions. It gives maintainers a place to explain how the software is used and what should count as a meaningful security issue.&lt;/p&gt;

&lt;p&gt;A useful threat model can describe:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which components are in scope&lt;/li&gt;
&lt;li&gt;Which inputs should be treated as hostile&lt;/li&gt;
&lt;li&gt;Which capabilities an attacker may already possess&lt;/li&gt;
&lt;li&gt;Which behavior is intentional&lt;/li&gt;
&lt;li&gt;Which deployment assumptions matter&lt;/li&gt;
&lt;li&gt;How severity should be assigned&lt;/li&gt;
&lt;li&gt;What a useful proof of concept should contain&lt;/li&gt;
&lt;li&gt;Whether proposed patches should be minimal or production-ready&lt;/li&gt;
&lt;li&gt;How closely related reports should be deduplicated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without this information, the scanner must infer the project’s security boundaries from its code and documentation.&lt;/p&gt;

&lt;p&gt;Consider a function that accepts a local file path. That behavior could represent a serious traversal risk in a network service. The same behavior could be expected in a command-line tool that only processes files selected by the local user. Code alone may not reveal the intended trust boundary.&lt;/p&gt;

&lt;p&gt;A good threat model does not guarantee perfect findings, but it gives the scanner better context.&lt;/p&gt;

&lt;h2&gt;
  
  
  What maintainers receive
&lt;/h2&gt;

&lt;p&gt;After a scan, maintainers receive a collection of reports. A report may contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A description of the suspected vulnerability&lt;/li&gt;
&lt;li&gt;A self-contained reproducer&lt;/li&gt;
&lt;li&gt;An explanation of the root cause&lt;/li&gt;
&lt;li&gt;Information about when the issue was introduced, where available&lt;/li&gt;
&lt;li&gt;A candidate patch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The scanner’s pipeline can use additional agents to double-check possible bugs, investigate causes and propose changes before a report is sent.&lt;/p&gt;

&lt;p&gt;These steps can make the report more actionable, but maintainers should still treat every result as a hypothesis until they reproduce it.&lt;/p&gt;

&lt;p&gt;A candidate patch is also not automatically safe to merge. It may solve the demonstrated problem while changing supported behavior, breaking compatibility or leaving a related attack path open.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical triage workflow
&lt;/h2&gt;

&lt;p&gt;Projects considering OSS Scanner should define their response process before the first report arrives.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Confirm the affected version
&lt;/h3&gt;

&lt;p&gt;Check whether the report applies to the current branch, a released version or code that has already changed.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Reproduce the behavior
&lt;/h3&gt;

&lt;p&gt;Run the supplied reproducer in an isolated environment. Do not test destructive proofs of concept against production systems or real user data.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Check reachability
&lt;/h3&gt;

&lt;p&gt;Determine whether an attacker can reach the vulnerable code under realistic deployment conditions. A dangerous function may be inaccessible in production or protected by another control.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Reassess severity
&lt;/h3&gt;

&lt;p&gt;Review the permissions, interaction and environmental conditions needed for exploitation. Model-generated severity can be too high or too low when project context is missing.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Search for duplicates
&lt;/h3&gt;

&lt;p&gt;Compare the report with known issues, private advisories, existing patches and other reports from the same scan.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Review the proposed patch
&lt;/h3&gt;

&lt;p&gt;Treat generated code like any external contribution. Review it, test it and check for regressions.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Decide on disclosure
&lt;/h3&gt;

&lt;p&gt;If the issue is real, identify affected releases, downstream users and packages. Coordinate remediation before publishing details that could help attackers.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Record the outcome
&lt;/h3&gt;

&lt;p&gt;Document whether the report was confirmed, duplicated, rejected or accepted as a known risk. That history can improve future triage and threat-model guidance.&lt;/p&gt;

&lt;h2&gt;
  
  
  How disclosure differs from the standard process
&lt;/h2&gt;

&lt;p&gt;Anthropic’s coordinated vulnerability disclosure process normally applies a defined disclosure period to verified findings.&lt;/p&gt;

&lt;p&gt;Unvalidated OSS Scanner reports do not automatically start that clock. Anthropic does not want to force maintainers into a disclosure deadline for a finding that its own researchers have not yet confirmed.&lt;/p&gt;

&lt;p&gt;If Anthropic later validates the report through its regular process, the coordinated disclosure period may begin at that point.&lt;/p&gt;

&lt;p&gt;This separation protects maintainers from being pressured by uncertain reports while preserving a route for confirmed issues to enter a formal disclosure workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the scanning environment is protected
&lt;/h2&gt;

&lt;p&gt;Allowing automated security analysis raises a reasonable question: how is sensitive vulnerability information handled?&lt;/p&gt;

&lt;p&gt;Anthropic says scanning agents run without internet access inside hardened sandboxes. Reports are stored in an isolated cloud environment available only to relevant security personnel.&lt;/p&gt;

&lt;p&gt;Enrollment requests receive human review, and the security contact is checked. The target configuration is reviewed to ensure that it points to the intended project. Before reports are sent, automated checks help verify that the finding concerns the enrolled project rather than one of its dependencies.&lt;/p&gt;

&lt;p&gt;These safeguards reduce obvious risks, but maintainers should still review the program’s current terms and documentation before enrolling. The service is new, and its policies, report format and eligibility rules may evolve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Can a project pause or leave?
&lt;/h2&gt;

&lt;p&gt;Participation is not permanent.&lt;/p&gt;

&lt;p&gt;A maintainer can temporarily disable automated reports through the project configuration. The project can later resume participation.&lt;/p&gt;

&lt;p&gt;A project can also leave by removing its configuration. After opting out, it may still receive human-reviewed reports through Anthropic’s standard disclosure process if Anthropic independently discovers a relevant vulnerability.&lt;/p&gt;

&lt;p&gt;This control is useful for projects that need to pause during a major release, clear a reporting backlog or reconsider their ability to handle unvalidated findings.&lt;/p&gt;

&lt;h2&gt;
  
  
  OSS Scanner is not the same as Claude Security
&lt;/h2&gt;

&lt;p&gt;The two offerings solve different problems.&lt;/p&gt;

&lt;p&gt;OSS Scanner is a no-cost program for selected open-source projects. Its purpose is to strengthen widely used public software by sending participating maintainers periodic model-generated findings.&lt;/p&gt;

&lt;p&gt;Claude Security is intended for organizations that want to review their own source code as part of their development and security workflow.&lt;/p&gt;

&lt;p&gt;Most application teams cannot submit a private repository to OSS Scanner simply because they want a free audit. The project must be open source, eligible and accepted into the program.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means for software teams
&lt;/h2&gt;

&lt;p&gt;Even teams that never use OSS Scanner can learn from its design.&lt;/p&gt;

&lt;p&gt;Security scanning is moving beyond finding simple patterns. AI agents can investigate code paths, construct reproducers, explain root causes and suggest patches. That can shorten the distance between detection and remediation.&lt;/p&gt;

&lt;p&gt;But a more capable scanner does not eliminate the need for engineering judgment.&lt;/p&gt;

&lt;p&gt;Teams still need to answer questions that depend on context:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the vulnerable path reachable?&lt;/li&gt;
&lt;li&gt;Does the report match the deployed version?&lt;/li&gt;
&lt;li&gt;How likely is exploitation?&lt;/li&gt;
&lt;li&gt;What systems and users are affected?&lt;/li&gt;
&lt;li&gt;Is the suggested fix complete?&lt;/li&gt;
&lt;li&gt;Can the change be released safely?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The limiting factor may increasingly become the team’s ability to review and act on findings rather than the scanner’s ability to produce them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Anthropic’s OSS Scanner is not a universal free security scanner. It is a selective program for established open-source projects that can handle fast, model-generated vulnerability reporting.&lt;/p&gt;

&lt;p&gt;Its value comes from reducing the delay between discovery and notification. Its main risk comes from the same decision: reports arrive without routine human validation.&lt;/p&gt;

&lt;p&gt;Projects with experienced maintainers, clear threat models and reliable triage processes may benefit from that exchange. Projects without those foundations could receive more security work than they can responsibly manage.&lt;/p&gt;

&lt;p&gt;The broader lesson applies to every automated security tool. Producing alerts is only the beginning. Real improvement happens when a team can validate the issue, understand its impact, review the fix and confirm that the risk is actually resolved.&lt;/p&gt;

</description>
      <category>security</category>
      <category>opensource</category>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>Software Supply Chain Security for Web Apps: A Developer's Threat-to-Control Guide</title>
      <dc:creator>FlawPilot</dc:creator>
      <pubDate>Fri, 16 Oct 2026 07:25:57 +0000</pubDate>
      <link>https://dev.to/flawpilot/software-supply-chain-security-for-web-apps-a-developers-threat-to-control-guide-i7j</link>
      <guid>https://dev.to/flawpilot/software-supply-chain-security-for-web-apps-a-developers-threat-to-control-guide-i7j</guid>
      <description>&lt;p&gt;A web application is rarely built from source code written entirely by one team. It also depends on packages, container images, development tools, CI/CD workflows, cloud services, build systems, and credentials.&lt;/p&gt;

&lt;p&gt;That extended chain makes development faster, but it also creates more places where an attacker, unsafe change, or configuration mistake can affect the final application.&lt;/p&gt;

&lt;p&gt;Software supply chain security is the practice of protecting that entire path. It covers what enters the codebase, who can change it, how it is built, what gets deployed, and how the team verifies the result.&lt;/p&gt;

&lt;p&gt;The goal is not to make every component perfectly safe. The goal is to know what you trust, reduce unnecessary access, detect meaningful changes, and retain enough evidence to investigate a problem.&lt;/p&gt;

&lt;p&gt;This guide organizes the work around five questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Can we trust our dependencies?&lt;/li&gt;
&lt;li&gt;Can we trust changes to the repository?&lt;/li&gt;
&lt;li&gt;Can we trust the build process?&lt;/li&gt;
&lt;li&gt;Can we verify the artifact we deploy?&lt;/li&gt;
&lt;li&gt;Can we confirm that production matches our security expectations?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For each question, we will look at the threat, the useful controls, and the evidence a team should be able to produce.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Can you trust your dependencies?
&lt;/h2&gt;

&lt;p&gt;Third-party packages save enormous amounts of development time. They also introduce code that your team did not write and may not review line by line.&lt;/p&gt;

&lt;h3&gt;
  
  
  The threat
&lt;/h3&gt;

&lt;p&gt;Dependency risk is broader than an old package with a known vulnerability. A project may also be exposed through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A compromised maintainer account&lt;/li&gt;
&lt;li&gt;A malicious new release&lt;/li&gt;
&lt;li&gt;A package name that closely resembles a legitimate dependency&lt;/li&gt;
&lt;li&gt;An abandoned library that no longer receives fixes&lt;/li&gt;
&lt;li&gt;A transitive dependency that developers did not select directly&lt;/li&gt;
&lt;li&gt;An install script that performs unexpected actions&lt;/li&gt;
&lt;li&gt;A public package replacing an internal package because of resolution order&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A dependency can therefore be risky even when its direct API looks harmless.&lt;/p&gt;

&lt;h3&gt;
  
  
  Useful controls
&lt;/h3&gt;

&lt;p&gt;Start by making dependency changes visible and repeatable.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Commit lockfiles and review their changes.&lt;/li&gt;
&lt;li&gt;Pin versions where reproducibility matters.&lt;/li&gt;
&lt;li&gt;Use an approved package registry or proxy for sensitive projects.&lt;/li&gt;
&lt;li&gt;Run dependency analysis on pull requests and on a recurring schedule.&lt;/li&gt;
&lt;li&gt;Review new direct dependencies before adoption.&lt;/li&gt;
&lt;li&gt;Remove unused packages instead of carrying them indefinitely.&lt;/li&gt;
&lt;li&gt;Restrict or inspect package lifecycle scripts.&lt;/li&gt;
&lt;li&gt;Define a response time for critical vulnerabilities.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Automated update tools are helpful, but automation should not automatically mean approval. A version bump can change maintainers, scripts, transitive packages, or runtime behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  Evidence to retain
&lt;/h3&gt;

&lt;p&gt;A team should be able to answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which package version is in production?&lt;/li&gt;
&lt;li&gt;Why was the package introduced?&lt;/li&gt;
&lt;li&gt;Who approved the latest major upgrade?&lt;/li&gt;
&lt;li&gt;Which transitive dependencies arrived with it?&lt;/li&gt;
&lt;li&gt;When was it last checked for known vulnerabilities?&lt;/li&gt;
&lt;li&gt;Is the vulnerable component actually reachable in the application?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A software bill of materials, or SBOM, can help inventory components. It does not prove that every component is safe. It provides a record that makes investigation and response faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Can you trust changes to the repository?
&lt;/h2&gt;

&lt;p&gt;Strong dependency controls will not help if an attacker can modify source code or pipeline configuration through a compromised account.&lt;/p&gt;

&lt;h3&gt;
  
  
  The threat
&lt;/h3&gt;

&lt;p&gt;Repository attacks often target identity and workflow rather than application logic. Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A stolen developer token&lt;/li&gt;
&lt;li&gt;An overprivileged service account&lt;/li&gt;
&lt;li&gt;A branch protection rule that can be bypassed&lt;/li&gt;
&lt;li&gt;A malicious pull request that changes both code and security checks&lt;/li&gt;
&lt;li&gt;A workflow file that exposes a secret to untrusted code&lt;/li&gt;
&lt;li&gt;A former employee whose access was not removed&lt;/li&gt;
&lt;li&gt;A bot credential with permission to write to the repository&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The dangerous change may be small. A single modified workflow step can download a malicious script, leak a token, or publish a substituted artifact.&lt;/p&gt;

&lt;h3&gt;
  
  
  Useful controls
&lt;/h3&gt;

&lt;p&gt;Protect the path by which code becomes trusted.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Require multi-factor authentication for repository access.&lt;/li&gt;
&lt;li&gt;Protect production and release branches.&lt;/li&gt;
&lt;li&gt;Require pull requests and independent review for sensitive changes.&lt;/li&gt;
&lt;li&gt;Apply ownership rules to workflow, infrastructure, and authentication files.&lt;/li&gt;
&lt;li&gt;Block direct pushes to protected branches.&lt;/li&gt;
&lt;li&gt;Use short-lived credentials where the platform supports them.&lt;/li&gt;
&lt;li&gt;Review user, bot, and integration permissions regularly.&lt;/li&gt;
&lt;li&gt;Remove access promptly during employee offboarding.&lt;/li&gt;
&lt;li&gt;Keep audit logs long enough to support an investigation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not every file needs the same review policy. A documentation edit does not carry the same risk as a change to a deployment workflow, access policy, or authentication module.&lt;/p&gt;

&lt;h3&gt;
  
  
  Evidence to retain
&lt;/h3&gt;

&lt;p&gt;For a production change, you should be able to identify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The commit that introduced it&lt;/li&gt;
&lt;li&gt;The pull request and reviewers&lt;/li&gt;
&lt;li&gt;The checks that ran&lt;/li&gt;
&lt;li&gt;Any exceptions or bypasses&lt;/li&gt;
&lt;li&gt;The identity that merged the change&lt;/li&gt;
&lt;li&gt;The branch and tag used for release&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This creates traceability. When something unexpected appears in production, the team can work backward without guessing.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Can you trust the build process?
&lt;/h2&gt;

&lt;p&gt;CI/CD systems often have access to source code, registries, cloud environments, signing keys, and deployment targets. That makes the build pipeline part of the security boundary.&lt;/p&gt;

&lt;h3&gt;
  
  
  The threat
&lt;/h3&gt;

&lt;p&gt;A build can be compromised without changing the application's normal source files. An attacker might:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alter a workflow definition&lt;/li&gt;
&lt;li&gt;Replace a referenced action or plugin&lt;/li&gt;
&lt;li&gt;Inject commands through untrusted input&lt;/li&gt;
&lt;li&gt;Extract secrets from logs or environment variables&lt;/li&gt;
&lt;li&gt;Run a pull request with excessive permissions&lt;/li&gt;
&lt;li&gt;Reuse an unprotected runner&lt;/li&gt;
&lt;li&gt;publish an artifact from an unreviewed branch&lt;/li&gt;
&lt;li&gt;Disable a security check while keeping the pipeline green&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result may look like a normal build even though the process that created it was not trustworthy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Useful controls
&lt;/h3&gt;

&lt;p&gt;Treat pipeline code like production code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pin third-party CI actions to trusted versions or immutable references.&lt;/li&gt;
&lt;li&gt;Review workflow changes through designated code owners.&lt;/li&gt;
&lt;li&gt;Give each job only the permissions it needs.&lt;/li&gt;
&lt;li&gt;Separate build and deployment permissions.&lt;/li&gt;
&lt;li&gt;Avoid exposing production secrets to untrusted pull requests.&lt;/li&gt;
&lt;li&gt;Prefer temporary identity tokens over long-lived cloud keys.&lt;/li&gt;
&lt;li&gt;Isolate runners and clean their state after jobs.&lt;/li&gt;
&lt;li&gt;Prevent secrets from being printed in logs.&lt;/li&gt;
&lt;li&gt;Require approval before production deployment when risk warrants it.&lt;/li&gt;
&lt;li&gt;Record the exact source revision and inputs used by each build.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Security checks should fail clearly. A scanner that crashes, times out, or never receives the intended files should not be reported as a successful security result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Evidence to retain
&lt;/h3&gt;

&lt;p&gt;For each release, preserve enough information to show:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which workflow version ran&lt;/li&gt;
&lt;li&gt;Which source revision it used&lt;/li&gt;
&lt;li&gt;Which runner or environment performed the build&lt;/li&gt;
&lt;li&gt;Which checks completed successfully&lt;/li&gt;
&lt;li&gt;Which dependencies and build tools were present&lt;/li&gt;
&lt;li&gt;Who approved the deployment&lt;/li&gt;
&lt;li&gt;Whether an exception was granted&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This evidence matters during an incident, but it also helps diagnose ordinary release failures.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Can you verify the artifact you deploy?
&lt;/h2&gt;

&lt;p&gt;Passing tests on source code does not guarantee that the resulting container, package, or static bundle is the artifact that reaches production.&lt;/p&gt;

&lt;h3&gt;
  
  
  The threat
&lt;/h3&gt;

&lt;p&gt;Artifact risk appears when there is a gap between build and deployment. Common problems include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mutable tags such as &lt;code&gt;latest&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Images pulled from an untrusted registry&lt;/li&gt;
&lt;li&gt;A package overwritten after approval&lt;/li&gt;
&lt;li&gt;A release rebuilt differently in another environment&lt;/li&gt;
&lt;li&gt;A manual file copied outside the normal pipeline&lt;/li&gt;
&lt;li&gt;Missing provenance for the production artifact&lt;/li&gt;
&lt;li&gt;Build output that contains secrets or development files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the team cannot connect a deployed artifact to its reviewed source, it cannot confidently explain what is running.&lt;/p&gt;

&lt;h3&gt;
  
  
  Useful controls
&lt;/h3&gt;

&lt;p&gt;Make artifacts identifiable and difficult to replace silently.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use immutable artifact identifiers or digests.&lt;/li&gt;
&lt;li&gt;Store artifacts in controlled registries.&lt;/li&gt;
&lt;li&gt;Restrict who and what can publish releases.&lt;/li&gt;
&lt;li&gt;Scan the final artifact, not only the repository.&lt;/li&gt;
&lt;li&gt;Generate checksums, signatures, or attestations where appropriate.&lt;/li&gt;
&lt;li&gt;Record build provenance.&lt;/li&gt;
&lt;li&gt;Promote the same approved artifact between environments instead of rebuilding it.&lt;/li&gt;
&lt;li&gt;Apply retention policies that support rollback and investigation.&lt;/li&gt;
&lt;li&gt;Reject artifacts that do not meet the expected origin or integrity checks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The principle is simple: build once, identify the result, verify it, and deploy that exact result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Evidence to retain
&lt;/h3&gt;

&lt;p&gt;A release record should connect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Source commit&lt;/li&gt;
&lt;li&gt;Build workflow&lt;/li&gt;
&lt;li&gt;Dependency set&lt;/li&gt;
&lt;li&gt;Test and scan results&lt;/li&gt;
&lt;li&gt;Artifact digest&lt;/li&gt;
&lt;li&gt;Registry location&lt;/li&gt;
&lt;li&gt;Deployment event&lt;/li&gt;
&lt;li&gt;Production environment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This chain of evidence turns a vague statement like "the pipeline deployed it" into a verifiable record.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Can you confirm production matches your expectations?
&lt;/h2&gt;

&lt;p&gt;Supply chain security does not end when an artifact is deployed. Configuration, infrastructure, domains, certificates, exposed client-side code, and runtime services can change what users actually receive.&lt;/p&gt;

&lt;h3&gt;
  
  
  The threat
&lt;/h3&gt;

&lt;p&gt;A secure build can still become an unsafe deployment. Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A production environment using an unexpected image&lt;/li&gt;
&lt;li&gt;A debug endpoint left publicly accessible&lt;/li&gt;
&lt;li&gt;A secret embedded in browser-delivered JavaScript&lt;/li&gt;
&lt;li&gt;A storage bucket or administrative service exposed to the internet&lt;/li&gt;
&lt;li&gt;Missing browser security headers&lt;/li&gt;
&lt;li&gt;A weak TLS or DNS configuration&lt;/li&gt;
&lt;li&gt;A third-party script added outside the reviewed release process&lt;/li&gt;
&lt;li&gt;A stale environment that continues running an old vulnerable component&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Source review alone cannot confirm all of these conditions because some risks appear only after deployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Useful controls
&lt;/h3&gt;

&lt;p&gt;Combine internal build evidence with external verification.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maintain an inventory of production applications, domains, and services.&lt;/li&gt;
&lt;li&gt;Compare deployed artifact identifiers with approved release records.&lt;/li&gt;
&lt;li&gt;Scan public endpoints after meaningful releases.&lt;/li&gt;
&lt;li&gt;Monitor certificates, DNS records, and internet-facing services.&lt;/li&gt;
&lt;li&gt;Review client-side bundles for exposed secrets and unexpected scripts.&lt;/li&gt;
&lt;li&gt;Check important security headers and transport settings.&lt;/li&gt;
&lt;li&gt;Remove abandoned staging systems and temporary services.&lt;/li&gt;
&lt;li&gt;Recheck high-risk issues after remediation.&lt;/li&gt;
&lt;li&gt;Monitor production dependencies continuously, not only at release time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where application security and website security meet. Internal controls explain how the software was produced. External checks show what the deployed system exposes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Evidence to retain
&lt;/h3&gt;

&lt;p&gt;Keep records that answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What artifact is currently deployed?&lt;/li&gt;
&lt;li&gt;When was the public application last checked?&lt;/li&gt;
&lt;li&gt;Which findings were accepted, fixed, or deferred?&lt;/li&gt;
&lt;li&gt;Who owns each unresolved issue?&lt;/li&gt;
&lt;li&gt;Was the fix verified after deployment?&lt;/li&gt;
&lt;li&gt;Are any temporary exceptions still active?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Turn findings into owned work
&lt;/h2&gt;

&lt;p&gt;A long security report is not a remediation plan. Findings need context, ownership, and a deadline.&lt;/p&gt;

&lt;p&gt;For each meaningful issue, record:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Asset:&lt;/strong&gt; What repository, package, pipeline, artifact, or application is affected?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exposure:&lt;/strong&gt; Can an attacker reach or influence it?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Impact:&lt;/strong&gt; What could happen if it were exploited?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confidence:&lt;/strong&gt; Is the finding confirmed, likely, or still under investigation?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Owner:&lt;/strong&gt; Which person or team can make the change?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action:&lt;/strong&gt; What specific control or fix is required?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deadline:&lt;/strong&gt; When should the risk be reduced?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verification:&lt;/strong&gt; How will the team prove the fix worked?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Severity labels are useful, but they are not enough. A critical issue in unreachable test code may be less urgent than a lower-rated secret exposed in a live browser bundle. Prioritization should account for actual exposure and business impact.&lt;/p&gt;

&lt;h2&gt;
  
  
  A compact release review
&lt;/h2&gt;

&lt;p&gt;Before a production release, verify the following:&lt;/p&gt;

&lt;h3&gt;
  
  
  Dependencies
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;New direct dependencies were reviewed.&lt;/li&gt;
&lt;li&gt;Lockfiles match the approved change.&lt;/li&gt;
&lt;li&gt;Known critical issues were assessed for reachability and impact.&lt;/li&gt;
&lt;li&gt;An inventory or SBOM can be generated for the release.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Repository
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The release commit came through the approved review path.&lt;/li&gt;
&lt;li&gt;Sensitive files received the required reviewers.&lt;/li&gt;
&lt;li&gt;No unexplained branch protection bypass occurred.&lt;/li&gt;
&lt;li&gt;Human and machine access is current.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pipeline
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Workflow dependencies are pinned appropriately.&lt;/li&gt;
&lt;li&gt;Jobs use minimum required permissions.&lt;/li&gt;
&lt;li&gt;Untrusted code cannot access production secrets.&lt;/li&gt;
&lt;li&gt;Required checks ran successfully and produced usable results.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Artifact
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The deployed artifact has an immutable identifier.&lt;/li&gt;
&lt;li&gt;Its source and build are traceable.&lt;/li&gt;
&lt;li&gt;The final artifact was scanned.&lt;/li&gt;
&lt;li&gt;Promotion does not rebuild or silently replace it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Production
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The deployed version matches the approved artifact.&lt;/li&gt;
&lt;li&gt;Public endpoints were checked after deployment.&lt;/li&gt;
&lt;li&gt;No secret or administrative interface is unintentionally exposed.&lt;/li&gt;
&lt;li&gt;Important findings have owners and verification steps.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This review does not need to become a large meeting. Mature teams automate the evidence collection and reserve human attention for exceptions, high-impact changes, and risk decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  If a supply chain incident occurs
&lt;/h2&gt;

&lt;p&gt;Preparation determines how quickly a team can respond. During an incident, start with containment and traceability.&lt;/p&gt;

&lt;p&gt;Ask:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Which component, account, workflow, or artifact is affected?&lt;/li&gt;
&lt;li&gt;Which releases include the affected component?&lt;/li&gt;
&lt;li&gt;Can publishing or deployment access be revoked immediately?&lt;/li&gt;
&lt;li&gt;Are credentials exposed or potentially compromised?&lt;/li&gt;
&lt;li&gt;Can the team identify every environment running the artifact?&lt;/li&gt;
&lt;li&gt;Is a known-good version available for rollback?&lt;/li&gt;
&lt;li&gt;What evidence must be preserved before systems are changed?&lt;/li&gt;
&lt;li&gt;How will the repaired release be verified internally and externally?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Do not assume that upgrading a package closes the incident. A compromise may also require credential rotation, artifact replacement, log review, environment cleanup, and confirmation that unauthorized persistence was not added.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with five proofs
&lt;/h2&gt;

&lt;p&gt;If a complete program feels too large, begin by requiring five pieces of evidence for every important production release:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The reviewed source commit&lt;/li&gt;
&lt;li&gt;The dependency inventory&lt;/li&gt;
&lt;li&gt;The completed pipeline checks&lt;/li&gt;
&lt;li&gt;The immutable artifact identifier&lt;/li&gt;
&lt;li&gt;The verified production deployment&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These proofs create a foundation for stronger controls. They also expose weak points quickly. If the team cannot produce one of them, that missing link becomes a practical improvement target.&lt;/p&gt;

&lt;p&gt;Software supply chain security is not a single scanner, checklist, or compliance document. It is the ability to explain and verify how software moved from an idea to a live system.&lt;/p&gt;

&lt;p&gt;Know what entered the build. Protect who can change it. Record how it was produced. Verify what was deployed. Then keep checking the system that users can actually reach.&lt;/p&gt;

</description>
      <category>security</category>
      <category>webdev</category>
      <category>devops</category>
      <category>cybersecurity</category>
    </item>
    <item>
      <title>Before You Deploy an AI-Built Website: A Developer's Launch Review</title>
      <dc:creator>FlawPilot</dc:creator>
      <pubDate>Fri, 09 Oct 2026 07:55:15 +0000</pubDate>
      <link>https://dev.to/flawpilot/before-you-deploy-an-ai-built-website-a-developers-launch-review-487i</link>
      <guid>https://dev.to/flawpilot/before-you-deploy-an-ai-built-website-a-developers-launch-review-487i</guid>
      <description>&lt;p&gt;AI coding tools can take a prompt to a working UI in an afternoon. The preview looks finished, the happy path works, and it is tempting to ship.&lt;/p&gt;

&lt;p&gt;But a preview proves one thing: the intended path works in one controlled environment. It says nothing about whether user A can read user B's data, whether a key is sitting in your JavaScript bundle, or whether staging's &lt;code&gt;noindex&lt;/code&gt; made it to production.&lt;/p&gt;

&lt;p&gt;This is the review we run before deploying generated code. It is not a threat model, pen test, or compliance audit. It is a way to catch the common launch gaps while they are still cheap to fix.&lt;/p&gt;

&lt;h3&gt;
  
  
  Block the release if any of these is true:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;A real secret reaches the browser or the repo history.&lt;/li&gt;
&lt;li&gt;A normal user can reach another user's data or an admin action.&lt;/li&gt;
&lt;li&gt;The core journey (signup, checkout, form) fails on the production URL.&lt;/li&gt;
&lt;li&gt;Production inherited a staging restriction (&lt;code&gt;noindex&lt;/code&gt;, wrong canonical, password wall).&lt;/li&gt;
&lt;li&gt;Nobody can roll back or knows who is watching after launch.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Everything below is how to check these quickly.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Test the deployed journey, not the generated screens
&lt;/h2&gt;

&lt;p&gt;Run the review against the production URL or an environment that mirrors it. Preview builds often differ in caching, asset paths, env vars, and domains.&lt;/p&gt;

&lt;p&gt;Pick the one action the site exists for (contact form, signup, checkout, upload) and complete it end to end. A success toast is not proof. Confirm the data arrived, the email was delivered, and the right system received it.&lt;/p&gt;

&lt;p&gt;Then break it on purpose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Submit empty and malformed values&lt;/li&gt;
&lt;li&gt;Reuse an expired token or old confirmation link&lt;/li&gt;
&lt;li&gt;Reload mid-flow, then use the back button after completion&lt;/li&gt;
&lt;li&gt;Upload a blocked or oversized file&lt;/li&gt;
&lt;li&gt;Cancel or fail a payment in test mode&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A failure should be clear and safe. It should never leak stack traces, internal paths, database errors, or tokens.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Test authentication and authorization separately
&lt;/h2&gt;

&lt;p&gt;Authentication answers "who are you?" Authorization answers "what may you do?" A working login only proves the first.&lt;/p&gt;

&lt;p&gt;Create at least two users with different roles, then try to cross the boundary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Logged in as user A, request a record owned by user B&lt;/span&gt;
curl &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="se"&gt;\_&lt;/span&gt;&lt;span class="s2"&gt;A"&lt;/span&gt; &lt;span class="se"&gt;\\&lt;/span&gt;
  https://example.com/api/invoices/&amp;lt;ID&lt;span class="se"&gt;\_&lt;/span&gt;OWNED&lt;span class="se"&gt;\_&lt;/span&gt;BY&lt;span class="se"&gt;\_&lt;/span&gt;B&amp;gt;

&lt;span class="c"&gt;# Expect 403 or 404. A 200 means broken access control.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also try an admin endpoint as a normal user, change a role value in a request body, and attempt a write with a read-only account.&lt;/p&gt;

&lt;p&gt;Hiding a button in the UI does nothing if the endpoint is open. Enforce ownership on the server, in the query itself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/invoices/:id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;requireAuth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;invoice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;invoice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findFirst&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;ownerId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;invoice&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;invoice&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Multi-tenant apps need extra care: a user from one organization must not be able to read, search, or infer another organization's data.&lt;/p&gt;

&lt;p&gt;Broken access control sits at the top of the &lt;a href="https://owasp.org/Top10/" rel="noopener noreferrer"&gt;OWASP Top 10&lt;/a&gt;, and generated code is a common place for it to hide.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Trace every secret from source to browser
&lt;/h2&gt;

&lt;p&gt;If a value reaches the browser, assume anyone can read it. Frameworks differ on which env vars are bundled into client code, and generated examples do not always say.&lt;/p&gt;

&lt;p&gt;Search your production build output, not just your source:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Adjust the build folder for your framework (dist, build, .next/static, out)&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-rEn&lt;/span&gt; &lt;span class="s2"&gt;"sk&lt;/span&gt;&lt;span class="se"&gt;\_&lt;/span&gt;&lt;span class="s2"&gt;live|AKIA&lt;/span&gt;&lt;span class="se"&gt;\[&lt;/span&gt;&lt;span class="s2"&gt;0-9A-Z]{16}|api&lt;/span&gt;&lt;span class="se"&gt;\[\_&lt;/span&gt;&lt;span class="s2"&gt;-]?key|secret"&lt;/span&gt; dist/ 2&amp;gt;/dev/null

&lt;span class="c"&gt;# Source maps can expose original code&lt;/span&gt;
find dist &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\*&lt;/span&gt;&lt;span class="s2"&gt;.map"&lt;/span&gt;

&lt;span class="c"&gt;# Was a key ever committed?&lt;/span&gt;
git log &lt;span class="nt"&gt;--all&lt;/span&gt; &lt;span class="nt"&gt;--oneline&lt;/span&gt; &lt;span class="nt"&gt;-S&lt;/span&gt;&lt;span class="s2"&gt;"sk&lt;/span&gt;&lt;span class="se"&gt;\_&lt;/span&gt;&lt;span class="s2"&gt;live"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also review network requests in DevTools, build logs, error messages, and example config files.&lt;/p&gt;

&lt;p&gt;If a real credential was exposed, rotate or revoke it. Deleting it from the latest commit does not remove it from Git history, caches, logs, or deployment artifacts. Give each key the minimum permissions it needs and restrict it by origin, environment, or quota where the provider allows.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Prune dependencies and third-party scripts
&lt;/h2&gt;

&lt;p&gt;Generated projects collect packages and scripts across prompts, and some outlive the feature that needed them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm audit &lt;span class="nt"&gt;--omit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dev
npx depcheck
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remove what is unused, review what is left, and apply upgrades in a branch with tests and a rollback path. Do not bulk-upgrade right before release.&lt;/p&gt;

&lt;p&gt;For every third-party script on the deployed page (analytics, chat, ads, widgets), know who owns it, why it is there, and what data it receives.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Inspect the real production response
&lt;/h2&gt;

&lt;p&gt;Your hosting platform, CDN, or proxy can change what the browser actually receives. Look at the live response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Headers on the final response&lt;/span&gt;
curl &lt;span class="nt"&gt;-sI&lt;/span&gt; https://example.com

&lt;span class="c"&gt;# Redirect chain: http, www, and non-www should end on one preferred URL&lt;/span&gt;
curl &lt;span class="nt"&gt;-sIL&lt;/span&gt; http://example.com | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-iE&lt;/span&gt; &lt;span class="s2"&gt;"^(HTTP|location)"&lt;/span&gt;
curl &lt;span class="nt"&gt;-sIL&lt;/span&gt; https://www.example.com | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-iE&lt;/span&gt; &lt;span class="s2"&gt;"^(HTTP|location)"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTPS everywhere, no mixed content&lt;/li&gt;
&lt;li&gt;One preferred host, with short redirect chains&lt;/li&gt;
&lt;li&gt;Cookie flags (&lt;code&gt;Secure&lt;/code&gt;, &lt;code&gt;HttpOnly&lt;/code&gt;, &lt;code&gt;SameSite&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;CORS rules that match your actual clients&lt;/li&gt;
&lt;li&gt;Security headers: &lt;code&gt;Content-Security-Policy&lt;/code&gt;, &lt;code&gt;Strict-Transport-Security&lt;/code&gt;, &lt;code&gt;X-Content-Type-Options&lt;/code&gt;, &lt;code&gt;Referrer-Policy&lt;/code&gt;, and framing controls&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do not paste a strict CSP from another site and deploy it. It can block your own scripts, fonts, payments, or auth provider. Start in report-only mode, watch what it flags, then enforce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; img-src 'self' data:; report-to csp-endpoint
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP" rel="noopener noreferrer"&gt;MDN CSP guide&lt;/a&gt; covers each directive.&lt;/p&gt;

&lt;p&gt;If you use a CDN or proxy, also confirm the origin server is not directly reachable in a way that bypasses it.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Check what crawlers actually receive
&lt;/h2&gt;

&lt;p&gt;Staging settings leak into production more often than you would expect.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Robots directives and canonical on the live page&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://example.com | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-iE&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;meta&lt;/span&gt;&lt;span class="se"&gt;\[&lt;/span&gt;&lt;span class="s2"&gt;^&amp;gt;]+robots|&amp;lt;link&lt;/span&gt;&lt;span class="se"&gt;\[&lt;/span&gt;&lt;span class="s2"&gt;^&amp;gt;]+canonical"&lt;/span&gt;

&lt;span class="c"&gt;# Header-level noindex&lt;/span&gt;
curl &lt;span class="nt"&gt;-sI&lt;/span&gt; https://example.com | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; x-robots-tag

curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://example.com/robots.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify for key pages: correct status code, no accidental &lt;code&gt;noindex&lt;/code&gt;, a canonical pointing to the preferred production URL, unique title and description, one &lt;code&gt;h1&lt;/code&gt;, crawlable internal links, and a sitemap with live URLs only.&lt;/p&gt;

&lt;p&gt;For client-rendered apps, inspect the rendered HTML. If essential copy, links, or metadata only appear after heavy JavaScript runs, a crawler may not see them. Google's &lt;a href="https://developers.google.com/search/docs/crawling-indexing" rel="noopener noreferrer"&gt;indexing docs&lt;/a&gt; explain how rendering and canonicals are handled.&lt;/p&gt;

&lt;p&gt;Also check social previews: a correct canonical can still ship with an Open Graph image from a builder preview domain.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Test performance and accessibility on the real build
&lt;/h2&gt;

&lt;p&gt;Measure the deployed build on a mobile profile and a constrained network, not your laptop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx lighthouse https://example.com &lt;span class="se"&gt;\\&lt;/span&gt;
  &lt;span class="nt"&gt;--only-categories&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;performance,accessibility,seo &lt;span class="se"&gt;\\&lt;/span&gt;
  &lt;span class="nt"&gt;--view&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Common causes of slow generated sites: oversized hero images, unused JavaScript, duplicate UI libraries, many font weights, animation packages for small effects, and blocking third-party widgets. Check loading, responsiveness, and layout stability, then complete the main task by hand. A good aggregate score can hide a form that still feels laggy.&lt;/p&gt;

&lt;p&gt;Automated accessibility checks catch missing labels and contrast issues, but not the whole experience. The &lt;a href="https://www.w3.org/WAI/test-evaluate/tools/selecting/" rel="noopener noreferrer"&gt;W3C WAI&lt;/a&gt; is explicit that tools cannot cover every requirement. Manually check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keyboard-only navigation, focus visibility, and focus order&lt;/li&gt;
&lt;li&gt;Persistent form labels and readable error messages&lt;/li&gt;
&lt;li&gt;Alt text on meaningful images&lt;/li&gt;
&lt;li&gt;Zoom and reflow at small viewports&lt;/li&gt;
&lt;li&gt;Reduced-motion behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  8. Assign owners and make a release decision
&lt;/h2&gt;

&lt;p&gt;A report fixes nothing by itself. Give every release-blocking issue one owner, one deadline, and one piece of evidence:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Critical journeys:&lt;/strong&gt; product or QA, with a completed success and failure run&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access control and app behavior:&lt;/strong&gt; developer, with role-based test results against the production build&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hosting, DNS, TLS, CDN:&lt;/strong&gt; platform owner, with verified live configuration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Indexing and metadata:&lt;/strong&gt; SEO or marketing, with live URL inspection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analytics and forms:&lt;/strong&gt; marketing ops, with confirmed events and delivery&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One person can own several rows. What matters is that ownership is explicit.&lt;/p&gt;

&lt;p&gt;Then sort findings by action rather than a scanner's severity label:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Block the release:&lt;/strong&gt; exposed production credentials, broken authorization, public sensitive data, unsafe payment or account behavior, a critical journey that cannot be completed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fix before public traffic:&lt;/strong&gt; broken forms, accidental indexing blocks, wrong redirects, severe mobile problems, no monitoring on a critical service&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schedule and track:&lt;/strong&gt; lower-impact hardening and cosmetic issues, each with an owner and a date&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Investigate:&lt;/strong&gt; unclear, duplicated, or environment-specific findings. Confirm the affected asset before changing production&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After every fix, retest on the live environment. A merged PR does not prove your CDN, cache, DNS provider, or pipeline delivered the change.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Plan the first hours after deploy
&lt;/h2&gt;

&lt;p&gt;Before release, decide who watches errors and uptime, who checks form and email delivery, who can roll back, and where launch issues are logged. Know how to restore from backup. Keep the domain registrar, DNS, hosting, repo, and email accounts under team control rather than one person's login. Re-run this review after any change to the domain, hosting, framework, auth, analytics, or integrations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automating part of this
&lt;/h2&gt;

&lt;p&gt;Most of the checks above can be scripted or run with free tools: &lt;code&gt;curl&lt;/code&gt;, Lighthouse, &lt;code&gt;npm audit&lt;/code&gt;, &lt;a href="https://www.zaproxy.org/" rel="noopener noreferrer"&gt;OWASP ZAP&lt;/a&gt;, and &lt;a href="https://www.deque.com/axe/" rel="noopener noreferrer"&gt;axe&lt;/a&gt;. Several hosted scanners also cover the public-surface checks (security headers, performance, SEO, infrastructure) in one pass.&lt;/p&gt;

&lt;p&gt;Disclosure: I work on one of them, &lt;a href="https://flawpilot.com/?utm_source=devto&amp;amp;utm_medium=organic&amp;amp;utm_campaign=ai-built-website-launch-review" rel="noopener noreferrer"&gt;FlawPilot&lt;/a&gt;. Whatever you use, keep the limits in mind. A public scan cannot sign in as each role, inspect private business logic, or judge accessibility in full, and source scanning does not replace runtime testing. Treat automated results as inputs to the release decision, not permission to deploy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Production-like URL tested, primary journey works end to end&lt;/li&gt;
&lt;li&gt;[ ] Failure and cancellation paths fail safely&lt;/li&gt;
&lt;li&gt;[ ] Authentication and authorization tested separately, with multiple roles&lt;/li&gt;
&lt;li&gt;[ ] No secrets in the bundle, source maps, logs, or Git history&lt;/li&gt;
&lt;li&gt;[ ] Dependencies and third-party scripts reviewed&lt;/li&gt;
&lt;li&gt;[ ] HTTPS, redirects, cookies, CORS, and headers checked on the live response&lt;/li&gt;
&lt;li&gt;[ ] Important pages indexable, with correct canonicals and metadata&lt;/li&gt;
&lt;li&gt;[ ] Performance tested on the production build under mobile conditions&lt;/li&gt;
&lt;li&gt;[ ] Accessibility tested automatically and manually&lt;/li&gt;
&lt;li&gt;[ ] Every open issue has an owner and a release decision&lt;/li&gt;
&lt;li&gt;[ ] Monitoring and rollback responsibilities are clear&lt;/li&gt;
&lt;li&gt;[ ] Critical fixes verified after deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI changes how fast you can build. It does not change what production has to withstand.&lt;/p&gt;

&lt;p&gt;What is the worst thing you have found in an AI-generated codebase before launch? Curious what others check that is missing from this list.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>devops</category>
      <category>ai</category>
    </item>
    <item>
      <title>A Fast AI-Built App Can Still Miss Basic Security Controls</title>
      <dc:creator>FlawPilot</dc:creator>
      <pubDate>Thu, 01 Oct 2026 09:13:06 +0000</pubDate>
      <link>https://dev.to/flawpilot/a-fast-ai-built-app-can-still-miss-basic-security-controls-2ffe</link>
      <guid>https://dev.to/flawpilot/a-fast-ai-built-app-can-still-miss-basic-security-controls-2ffe</guid>
      <description>&lt;p&gt;An application can load quickly, pass a normal click-through test, and still be unready for production.&lt;/p&gt;

&lt;p&gt;That is not a contradiction. Functional testing and security testing answer different questions.&lt;/p&gt;

&lt;p&gt;A functional test asks whether a user can complete the intended journey. A security review asks what else the application, domain, browser, server, and deployment will allow.&lt;/p&gt;

&lt;p&gt;An anonymized review of one AI-built web application made that difference clear. The app scored 100 out of 100 for performance, yet the broader review found 35 open issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 critical&lt;/li&gt;
&lt;li&gt;6 high severity&lt;/li&gt;
&lt;li&gt;19 medium severity&lt;/li&gt;
&lt;li&gt;9 low severity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The application was not visibly broken. It loaded fast, rendered correctly, and supported its main workflow. Most of the problems existed outside the path a builder would normally test in the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the review measured
&lt;/h2&gt;

&lt;p&gt;The application was assessed across four areas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Performance: 100 out of 100, with no findings&lt;/li&gt;
&lt;li&gt;Security: 70 out of 100, with 16 findings&lt;/li&gt;
&lt;li&gt;Infrastructure: 54 out of 100, with 10 findings&lt;/li&gt;
&lt;li&gt;Search visibility: 46 out of 100, with 9 findings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The combined score was 67 out of 100.&lt;/p&gt;

&lt;p&gt;The perfect performance result was valid. The app handled loading speed, caching, asset delivery, and rendering well. Modern frameworks and AI app builders often provide good defaults for these areas.&lt;/p&gt;

&lt;p&gt;The security and infrastructure findings were also valid. They did not affect the normal user experience, so manual testing had not exposed them.&lt;/p&gt;

&lt;p&gt;This is a common weakness in fast AI-assisted development. The builder checks whether the requested feature works. Nobody checks the surrounding controls unless the release process requires it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Missing DMARC left the domain easier to impersonate
&lt;/h2&gt;

&lt;p&gt;The domain had no DMARC policy.&lt;/p&gt;

&lt;p&gt;DMARC works with SPF and DKIM to help receiving mail systems evaluate messages that claim to come from a domain. It also lets the domain owner specify what should happen when authentication checks fail.&lt;/p&gt;

&lt;p&gt;Without an appropriate policy, attackers have more room to send email that appears connected to the company. That can support phishing against customers, employees, or partners.&lt;/p&gt;

&lt;p&gt;Nothing about this problem appears in the app interface. A registration form, dashboard, or payment flow can work perfectly while the email domain remains poorly protected.&lt;/p&gt;

&lt;p&gt;Teams should review email authentication whenever a new domain is prepared for production, even if the application itself does not send much email yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  The browser had no Content Security Policy
&lt;/h2&gt;

&lt;p&gt;The application did not send a Content Security Policy header.&lt;/p&gt;

&lt;p&gt;CSP tells the browser which sources may provide scripts, styles, frames, images, and other resources. A well-designed policy can limit what malicious code is allowed to execute if an injection weakness or compromised third-party script reaches a page.&lt;/p&gt;

&lt;p&gt;CSP is not a substitute for fixing cross-site scripting. It is an extra restriction that can reduce impact.&lt;/p&gt;

&lt;p&gt;Adding it carelessly can break legitimate application behavior. Start by listing the resources the app needs, test the policy in a non-production environment, and review browser reports before enforcing it.&lt;/p&gt;

&lt;p&gt;The important point is ownership. If nobody is responsible for response headers, the control may never enter the release checklist.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTPS was present, but HSTS was missing
&lt;/h2&gt;

&lt;p&gt;The application used HTTPS but did not send a Strict-Transport-Security header.&lt;/p&gt;

&lt;p&gt;HSTS tells compatible browsers to use HTTPS for future requests to the domain. It reduces the chance that a visitor's first connection will be downgraded to HTTP on an untrusted network.&lt;/p&gt;

&lt;p&gt;A browser padlock confirms the current page uses HTTPS. It does not confirm that HSTS is configured correctly.&lt;/p&gt;

&lt;p&gt;Before enabling HSTS, confirm that the domain and required subdomains work over HTTPS. A long duration or an &lt;code&gt;includeSubDomains&lt;/code&gt; directive can create an outage if part of the domain still depends on HTTP.&lt;/p&gt;

&lt;p&gt;This is a small configuration change with real consequences, so teams should test it instead of copying a header value without understanding its scope.&lt;/p&gt;

&lt;h2&gt;
  
  
  The app could be framed by another site
&lt;/h2&gt;

&lt;p&gt;The review also found no effective clickjacking protection.&lt;/p&gt;

&lt;p&gt;Without a framing restriction, another website may be able to load the application inside an invisible or misleading frame. An attacker can then try to persuade a user to click a real application control while believing they are interacting with something else.&lt;/p&gt;

&lt;p&gt;The preferred modern control is the &lt;code&gt;frame-ancestors&lt;/code&gt; directive in CSP. Some teams also retain &lt;code&gt;X-Frame-Options&lt;/code&gt; for older browser support.&lt;/p&gt;

&lt;p&gt;Applications that intentionally support embedding need a more precise policy. Blocking every frame is not appropriate when approved partner domains must embed the application.&lt;/p&gt;

&lt;p&gt;Again, the correct setting depends on the product. The AI builder cannot infer that business rule from a generic request to create a dashboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Infrastructure findings sat outside the main code path
&lt;/h2&gt;

&lt;p&gt;The review found several other gaps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no CAA record restricting certificate issuance&lt;/li&gt;
&lt;li&gt;no DKIM signature for outgoing email&lt;/li&gt;
&lt;li&gt;server information exposed in responses&lt;/li&gt;
&lt;li&gt;no &lt;code&gt;robots.txt&lt;/code&gt; file for crawler guidance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These findings did not have equal security impact. A missing crawler file should not receive the same response as exposed credentials or broken authorization.&lt;/p&gt;

&lt;p&gt;Their shared cause was a missing review step. The visible product had received attention. Domain, email, server, and deployment configuration had not.&lt;/p&gt;

&lt;p&gt;This distinction matters because teams can waste time if they treat every automated finding as urgent. Severity is a starting point, not the complete decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why vibe coding creates this blind spot
&lt;/h2&gt;

&lt;p&gt;AI coding tools respond to the requirements in the prompt and the context available to them.&lt;/p&gt;

&lt;p&gt;If someone requests a login page, dashboard, database integration, and billing flow, the tool focuses on those capabilities. It may not know the organization's email setup, deployment architecture, data classification, threat model, or access policies.&lt;/p&gt;

&lt;p&gt;Many missing controls do not cause a build failure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a missing security header does not stop the page from rendering&lt;/li&gt;
&lt;li&gt;weak email authentication does not break a dashboard&lt;/li&gt;
&lt;li&gt;excessive cloud permissions do not affect the happy path&lt;/li&gt;
&lt;li&gt;a vulnerable package may continue to work normally&lt;/li&gt;
&lt;li&gt;an exposed secret may remain unused by an attacker for weeks&lt;/li&gt;
&lt;li&gt;a broken database policy may go unnoticed when testing with one account&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why "the app works" cannot be used as evidence that the app is secure.&lt;/p&gt;

&lt;p&gt;The issue is not that AI-generated code is automatically unsafe. The issue is that fast generation often removes the independent review that used to happen between implementation and release.&lt;/p&gt;

&lt;p&gt;Teams need to put that review back into the workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  A public deployment review cannot inspect everything
&lt;/h2&gt;

&lt;p&gt;A review of a live URL can examine publicly visible behavior and configuration, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TLS configuration&lt;/li&gt;
&lt;li&gt;DNS and email authentication records&lt;/li&gt;
&lt;li&gt;HTTP response headers&lt;/li&gt;
&lt;li&gt;public files and browser assets&lt;/li&gt;
&lt;li&gt;exposed server information&lt;/li&gt;
&lt;li&gt;cross-origin behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It cannot inspect a private repository without authorized access.&lt;/p&gt;

&lt;p&gt;Repository analysis answers different questions. It can look for insecure code patterns, secrets committed to Git history, vulnerable dependency versions, and code that is difficult to review safely.&lt;/p&gt;

&lt;p&gt;Both views matter.&lt;/p&gt;

&lt;p&gt;A source repository can appear clean while the deployed environment has weak headers or incorrect DNS records. A live site can appear well configured while its code contains an injection flaw, an outdated dependency, or a key committed in an older revision.&lt;/p&gt;

&lt;p&gt;Treat repository checks and deployment checks as separate release controls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prioritize findings instead of chasing the total count
&lt;/h2&gt;

&lt;p&gt;The number 35 sounds serious, but the total does not tell a team what to fix first.&lt;/p&gt;

&lt;p&gt;Prioritization should consider at least five factors:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What an attacker could do&lt;/li&gt;
&lt;li&gt;Whether the affected path is publicly reachable&lt;/li&gt;
&lt;li&gt;Whether sensitive data or privileged actions are involved&lt;/li&gt;
&lt;li&gt;How widely the issue affects the application&lt;/li&gt;
&lt;li&gt;Whether the proposed fix can be tested and rolled back safely&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Leaked production credentials, public database access, broken authorization, and reachable injection flaws normally take priority over low-impact information disclosure or missing search metadata.&lt;/p&gt;

&lt;p&gt;Easy fixes can still be worth doing early when they reduce meaningful risk. The reviewed application could address several high-severity configuration gaps without rewriting application logic. That did not make every fix risk-free. Header and DNS changes still needed testing and verification.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical pre-release checklist
&lt;/h2&gt;

&lt;p&gt;Before publishing an AI-built web application, verify the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Store production secrets outside source control.&lt;/li&gt;
&lt;li&gt;Scan the complete Git history for previously committed credentials.&lt;/li&gt;
&lt;li&gt;Rotate any exposed secret instead of only deleting the file.&lt;/li&gt;
&lt;li&gt;Test authorization with multiple users and roles.&lt;/li&gt;
&lt;li&gt;Confirm database policies prevent cross-account access.&lt;/li&gt;
&lt;li&gt;Review direct and transitive dependencies for known vulnerabilities.&lt;/li&gt;
&lt;li&gt;Restrict CORS to the origins, methods, and headers the application needs.&lt;/li&gt;
&lt;li&gt;Configure relevant security headers and test them in staging.&lt;/li&gt;
&lt;li&gt;Set up SPF, DKIM, and DMARC for domains that send email.&lt;/li&gt;
&lt;li&gt;Remove unnecessary server and framework disclosures.&lt;/li&gt;
&lt;li&gt;Review repository, CI/CD, cloud, and deployment permissions.&lt;/li&gt;
&lt;li&gt;Scan a representative staging deployment before release.&lt;/li&gt;
&lt;li&gt;Check the production URL after deployment.&lt;/li&gt;
&lt;li&gt;Assign an owner and review date to every accepted risk.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Adjust the checklist to the application. A public portfolio has a different risk profile from a multi-tenant product that stores financial, health, or customer information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recheck after deployment
&lt;/h2&gt;

&lt;p&gt;Security review is not complete when a developer merges a fix.&lt;/p&gt;

&lt;p&gt;Confirm that the corrected configuration reached production. A reverse proxy, hosting platform, content delivery network, or environment variable can make the deployed result different from the local version.&lt;/p&gt;

&lt;p&gt;Run checks again after changes to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;hosting providers&lt;/li&gt;
&lt;li&gt;domains or DNS&lt;/li&gt;
&lt;li&gt;authentication systems&lt;/li&gt;
&lt;li&gt;database policies&lt;/li&gt;
&lt;li&gt;third-party scripts&lt;/li&gt;
&lt;li&gt;dependencies&lt;/li&gt;
&lt;li&gt;deployment workflows&lt;/li&gt;
&lt;li&gt;major application routes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Certificates expire, package vulnerabilities are disclosed, and configuration changes accumulate. A secure launch does not guarantee a secure application six months later.&lt;/p&gt;

&lt;h2&gt;
  
  
  The main lesson
&lt;/h2&gt;

&lt;p&gt;The reviewed application was fast. It was functional. It also missed controls that mattered.&lt;/p&gt;

&lt;p&gt;Those facts can all be true at the same time.&lt;/p&gt;

&lt;p&gt;AI-assisted development reduces the time required to turn an idea into a working application. It does not remove the need to review code, dependencies, permissions, domain settings, deployment configuration, and the final production result.&lt;/p&gt;

&lt;p&gt;Keep the speed advantage. Add a security checkpoint before launch, then verify the application again after it reaches production.&lt;/p&gt;

</description>
      <category>security</category>
      <category>seo</category>
      <category>web</category>
      <category>vibecoding</category>
    </item>
    <item>
      <title>How to choose a SAST tool: 8 open-source options and a broader security platform</title>
      <dc:creator>FlawPilot</dc:creator>
      <pubDate>Thu, 24 Sep 2026 12:02:03 +0000</pubDate>
      <link>https://dev.to/flawpilot/how-to-choose-a-sast-tool-8-open-source-options-and-a-broader-security-platform-2og8</link>
      <guid>https://dev.to/flawpilot/how-to-choose-a-sast-tool-8-open-source-options-and-a-broader-security-platform-2og8</guid>
      <description>&lt;p&gt;Static application security testing helps developers find risky code without running the application. That definition is simple. Choosing a scanner is not.&lt;/p&gt;

&lt;p&gt;A tool may support your programming language but miss the framework patterns that matter in your project. Another may produce useful findings but require more maintenance than your team can manage. A third may work well in continuous integration but provide little help when developers need to understand or fix an alert.&lt;/p&gt;

&lt;p&gt;This guide compares eight open-source SAST tools and FlawPilot, a broader code and application security platform. The goal is to help you build a shortlist based on your codebase, workflow, and security needs.&lt;/p&gt;

&lt;p&gt;Disclosure: The author is affiliated with FlawPilot. It is included in third position and assessed using the same practical criteria as the other options.&lt;/p&gt;

&lt;h2&gt;
  
  
  What SAST checks
&lt;/h2&gt;

&lt;p&gt;SAST examines source code, bytecode, or build artifacts without sending test traffic to a running application. Depending on the engine and language, it may detect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unsafe input handling&lt;/li&gt;
&lt;li&gt;Injection paths&lt;/li&gt;
&lt;li&gt;Hardcoded credentials&lt;/li&gt;
&lt;li&gt;Weak cryptographic choices&lt;/li&gt;
&lt;li&gt;Unsafe deserialization&lt;/li&gt;
&lt;li&gt;Path traversal risks&lt;/li&gt;
&lt;li&gt;Cross-site scripting paths&lt;/li&gt;
&lt;li&gt;Risky functions or insecure code patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many SAST tools can run on a developer's machine, during a pull request, or in a continuous integration pipeline. They often identify the file and line connected to a finding, which gives the developer a place to begin the investigation.&lt;/p&gt;

&lt;p&gt;That finding is not proof of exploitation. The scanner may not understand every validation step, authorization control, runtime condition, or business rule. A developer still needs to check whether the code is reachable, whether an attacker can control the input, and what the impact would be.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why source scanning and live testing are different
&lt;/h2&gt;

&lt;p&gt;SAST reads code. Dynamic or live application testing interacts with a running system.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;Source scanning&lt;/th&gt;
&lt;th&gt;Live application scanning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;What does it inspect?&lt;/td&gt;
&lt;td&gt;Source code, bytecode, or build artifacts&lt;/td&gt;
&lt;td&gt;A running website, API, or web application&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;When can it run?&lt;/td&gt;
&lt;td&gt;During development and continuous integration&lt;/td&gt;
&lt;td&gt;In a test environment, before launch, or after deployment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What context does it see?&lt;/td&gt;
&lt;td&gt;Internal code paths and data flow&lt;/td&gt;
&lt;td&gt;Public behavior, responses, services, and configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What can it miss?&lt;/td&gt;
&lt;td&gt;Runtime settings and external exposure&lt;/td&gt;
&lt;td&gt;Internal code that is not reachable during the test&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;One method cannot replace the other. A source scanner may identify an unsafe query construction. A live scanner may identify missing security headers, weak transport settings, or an exposed service. Teams that build internet-facing applications usually need both views.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tool comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Best fit&lt;/th&gt;
&lt;th&gt;Main focus&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Semgrep Community Edition&lt;/td&gt;
&lt;td&gt;Multi-language repositories and custom rules&lt;/td&gt;
&lt;td&gt;Pattern-based source analysis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeQL&lt;/td&gt;
&lt;td&gt;Projects hosted in GitHub workflows&lt;/td&gt;
&lt;td&gt;Semantic analysis and code queries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FlawPilot&lt;/td&gt;
&lt;td&gt;Teams that want source and deployed-application checks&lt;/td&gt;
&lt;td&gt;Code scanning, live checks, and AI Fix prompts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bandit&lt;/td&gt;
&lt;td&gt;Python projects&lt;/td&gt;
&lt;td&gt;Python security rules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brakeman&lt;/td&gt;
&lt;td&gt;Ruby on Rails applications&lt;/td&gt;
&lt;td&gt;Rails-aware static analysis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gosec&lt;/td&gt;
&lt;td&gt;Go services and applications&lt;/td&gt;
&lt;td&gt;Go-specific security checks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SpotBugs with Find Security Bugs&lt;/td&gt;
&lt;td&gt;Java and JVM projects&lt;/td&gt;
&lt;td&gt;Bytecode analysis with security detectors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MobSF&lt;/td&gt;
&lt;td&gt;Mobile application assessment&lt;/td&gt;
&lt;td&gt;Mobile static and dynamic analysis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PMD&lt;/td&gt;
&lt;td&gt;Java-heavy projects with code-quality needs&lt;/td&gt;
&lt;td&gt;General static rules with selected security checks&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Capabilities, licenses, and supported languages can change. Confirm current details before adopting a tool across multiple repositories.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Semgrep Community Edition
&lt;/h2&gt;

&lt;p&gt;Semgrep Community Edition scans source code with rules that describe insecure or unwanted patterns. It supports many languages, though the depth of support is not identical across all of them.&lt;/p&gt;

&lt;p&gt;Its main advantage is flexibility. A team can use community rules, adjust existing rules, or write checks for patterns specific to its own code. Developers can run it locally and add it to a pull-request or continuous integration workflow.&lt;/p&gt;

&lt;p&gt;That flexibility requires ownership. Someone needs to choose the rules, test them against the codebase, remove irrelevant checks, and maintain custom rules as frameworks change. Enabling a large rule collection without tuning can create noise.&lt;/p&gt;

&lt;p&gt;Semgrep is worth considering when you have several languages, want editable rules, and have someone who can maintain the rule set.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. CodeQL
&lt;/h2&gt;

&lt;p&gt;CodeQL creates a database representation of a codebase and lets security queries analyze relationships and data flow. This approach can identify problems that simple pattern matching may not find.&lt;/p&gt;

&lt;p&gt;It fits naturally into GitHub-based development. Findings can appear in code-scanning workflows and pull requests for supported languages. Security engineers can also write custom queries for organization-specific risks.&lt;/p&gt;

&lt;p&gt;The tradeoff is complexity. Advanced query development requires knowledge of the CodeQL language and its libraries. Some compiled projects also need correct build configuration before analysis can work well.&lt;/p&gt;

&lt;p&gt;CodeQL is a strong candidate when repositories already use GitHub and the team needs deeper semantic analysis. Check the current licensing and availability conditions for your repository type and plan.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. FlawPilot
&lt;/h2&gt;

&lt;p&gt;FlawPilot covers source code and the deployed application. Teams can connect a repository for code scanning and scan a website, web application, or SaaS product before or after launch.&lt;/p&gt;

&lt;p&gt;The code scan looks for insecure code, exposed secrets, and vulnerable dependencies. The live scan checks publicly visible security, performance, infrastructure, and SEO signals. This combination helps a developer compare what exists in the repository with what the deployed environment exposes.&lt;/p&gt;

&lt;p&gt;For supported findings, FlawPilot supplies an AI Fix prompt. A developer can copy that prompt into a coding assistant to receive finding-specific remediation guidance. The developer should review the resulting change, run the relevant tests, and scan again before deployment.&lt;/p&gt;

&lt;p&gt;FlawPilot may suit founders and development teams that want prioritized explanations, repository checks, and live scanning in one workflow. It does not replace a manual penetration test. Automated checks can miss business-logic problems, complex authorization failures, authenticated paths, and attacks that depend on several weaknesses.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Bandit
&lt;/h2&gt;

&lt;p&gt;Bandit scans Python abstract syntax trees and applies security-focused plugins. Its checks cover patterns such as hardcoded passwords, unsafe subprocess use, weak cryptography, and dangerous function calls.&lt;/p&gt;

&lt;p&gt;The narrow focus is useful for Python teams. Bandit is easy to run locally or inside continuous integration, and it can produce structured output for other development tools.&lt;/p&gt;

&lt;p&gt;Bandit still needs tuning. A rule may report code that is safe in the actual application context. Teams should document suppressions and review them instead of allowing an ignore list to grow without ownership.&lt;/p&gt;

&lt;p&gt;Bandit does not check whether installed Python packages contain known vulnerabilities. Pair it with dependency analysis when assessing a Python project.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Brakeman
&lt;/h2&gt;

&lt;p&gt;Brakeman is designed for Ruby on Rails. It understands Rails conventions and reviews application code without starting the application server.&lt;/p&gt;

&lt;p&gt;Its framework knowledge helps it identify Rails-related injection, redirect, cross-site scripting, and configuration risks. It can run from the command line and in automated build workflows.&lt;/p&gt;

&lt;p&gt;Brakeman is a focused choice, not a complete scanner for a mixed technology stack. A system with a Rails backend, a separate frontend, infrastructure files, and cloud services will require other checks.&lt;/p&gt;

&lt;p&gt;Teams should tune warning confidence and review ignored findings after important code changes. A warning that seemed irrelevant in one release may matter after the surrounding logic changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Gosec
&lt;/h2&gt;

&lt;p&gt;Gosec examines Go source code using security rules built around Go analysis packages. It can identify risky permissions, hardcoded credentials, weak cryptography, unsafe integer conversions, and other Go-specific patterns.&lt;/p&gt;

&lt;p&gt;It fits into Go development workflows and can export results in formats used by code-scanning systems. That makes it practical for services that already run tests, formatting, and analysis in continuous integration.&lt;/p&gt;

&lt;p&gt;Gosec is different from a general Go linter. A linter usually emphasizes correctness, consistency, and maintainability. Gosec adds security rules, but teams still need separate dependency analysis and testing of the running service.&lt;/p&gt;

&lt;p&gt;Review each rule against the application. A command-line utility and a public API have different exposure and may need different rule settings.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. SpotBugs with Find Security Bugs
&lt;/h2&gt;

&lt;p&gt;SpotBugs analyzes Java bytecode for patterns associated with programming defects. The Find Security Bugs plugin adds security detectors for Java web and Android applications and can also support relevant patterns in other JVM languages.&lt;/p&gt;

&lt;p&gt;This combination fits Maven and Gradle workflows. It is useful for teams that want general defect checks and security rules during the same build process.&lt;/p&gt;

&lt;p&gt;Scan quality depends on build quality. Missing classes or an incomplete type hierarchy can reduce the analyzer's understanding of the application. Treat those build warnings as scan problems rather than harmless messages.&lt;/p&gt;

&lt;p&gt;SpotBugs alone is not a complete application-security scanner. Make sure the security plugin is installed and configured if security analysis is the objective.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. MobSF
&lt;/h2&gt;

&lt;p&gt;Mobile Security Framework, commonly called MobSF, is designed for Android, iOS, and Windows mobile application assessment. It can perform static and dynamic analysis, depending on the application artifact and test setup.&lt;/p&gt;

&lt;p&gt;MobSF can inspect permissions, certificates, application components, embedded files, and mobile platform configuration. That makes it different from scanners aimed at ordinary web application source code.&lt;/p&gt;

&lt;p&gt;The broad mobile coverage requires more setup than a small language-specific scanner. Dynamic analysis needs a suitable environment, and the results need review by someone who understands the mobile platform and the application.&lt;/p&gt;

&lt;p&gt;Mobile security also includes backend APIs, authentication, data handling, dependencies, and high-risk user flows. MobSF should form one part of that process.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. PMD
&lt;/h2&gt;

&lt;p&gt;PMD checks source code for programming problems, duplicated code, maintainability issues, and selected security patterns. It is strongly associated with Java, although it has modules for other languages.&lt;/p&gt;

&lt;p&gt;It works well when a team wants one rule system for code quality and some security checks. Java projects can add it to common build workflows and create project-specific rules.&lt;/p&gt;

&lt;p&gt;PMD is not as security-focused as Bandit, Brakeman, or Gosec. Treat its security rules as an extra layer. A Java application that needs deeper security analysis may pair PMD with a dedicated security tool.&lt;/p&gt;

&lt;p&gt;Avoid enabling every rule at once. Select checks that apply to the codebase, then expand the rule set as the team learns how to handle the output.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to build a useful shortlist
&lt;/h2&gt;

&lt;p&gt;Tool selection should begin with your repository. Popularity and long feature lists are poor substitutes for testing a scanner against real project code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Match the language and framework
&lt;/h3&gt;

&lt;p&gt;Confirm that the scanner supports the language version and framework you use. Basic syntax support does not always mean deep framework-aware analysis.&lt;/p&gt;

&lt;p&gt;For a mixed stack, decide whether one multi-language scanner provides enough coverage or whether each major language needs a focused tool. A focused scanner often gives better framework context, while a multi-language tool can reduce operational work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Decide where feedback should appear
&lt;/h3&gt;

&lt;p&gt;Choose when developers need results. Options include the editor, a local command, a pull request, a continuous integration job, or a scheduled scan.&lt;/p&gt;

&lt;p&gt;Begin with reporting. Blocking every build on the first day can disrupt delivery if the scanner reports old issues or irrelevant patterns. After tuning the rules and reviewing the existing findings, block only new results that meet a clear severity and confidence threshold.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test a representative repository
&lt;/h3&gt;

&lt;p&gt;Run each shortlisted tool against code that reflects your normal architecture. Then review:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whether the findings are relevant&lt;/li&gt;
&lt;li&gt;Whether each result points to a useful code location&lt;/li&gt;
&lt;li&gt;How often the team sees false positives&lt;/li&gt;
&lt;li&gt;Whether the explanation helps a developer investigate&lt;/li&gt;
&lt;li&gt;Whether the output works with existing systems&lt;/li&gt;
&lt;li&gt;How much time the scan adds to the pipeline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do not compare tools using the total number of alerts. A scanner that reports more issues is not automatically better. Review the accuracy and usefulness of those findings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check rule controls and suppressions
&lt;/h3&gt;

&lt;p&gt;The team needs a way to disable irrelevant rules, exclude generated files, record accepted risks, and create project-specific checks when necessary.&lt;/p&gt;

&lt;p&gt;Every suppression should have a reason and an owner. Review accepted risks after major architecture changes or framework upgrades. Otherwise, an old exception can hide a new problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Review maintenance and licensing
&lt;/h3&gt;

&lt;p&gt;Check release activity, supported language versions, open issues, documentation, and the health of the contributor community. Also review the license for the scanner, plugins, and rule packs.&lt;/p&gt;

&lt;p&gt;Open source does not mean there is no operating cost. Installation, upgrades, continuous integration jobs, rule maintenance, result triage, and developer support all require time.&lt;/p&gt;

&lt;h2&gt;
  
  
  A staged rollout for development teams
&lt;/h2&gt;

&lt;p&gt;A gradual rollout gives the team time to understand the scanner before it controls releases.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Select one active repository with supported languages.&lt;/li&gt;
&lt;li&gt;Run the scanner in reporting mode.&lt;/li&gt;
&lt;li&gt;Review the first results with a developer who knows the code.&lt;/li&gt;
&lt;li&gt;Disable irrelevant rules and document justified suppressions.&lt;/li&gt;
&lt;li&gt;Fix high-confidence findings with meaningful impact.&lt;/li&gt;
&lt;li&gt;Record a baseline for accepted existing findings.&lt;/li&gt;
&lt;li&gt;Block new critical findings once the output is reliable.&lt;/li&gt;
&lt;li&gt;Review tool versions, rules, and suppressions on a schedule.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This process separates existing security debt from newly introduced problems. The team can stop new high-risk issues while handling older findings through planned work.&lt;/p&gt;

&lt;h2&gt;
  
  
  What SAST does not cover
&lt;/h2&gt;

&lt;p&gt;Static analysis cannot see every security problem. A complete testing process may also require:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dependency analysis&lt;/li&gt;
&lt;li&gt;Secret scanning&lt;/li&gt;
&lt;li&gt;Infrastructure-as-code checks&lt;/li&gt;
&lt;li&gt;Container image scanning&lt;/li&gt;
&lt;li&gt;API security testing&lt;/li&gt;
&lt;li&gt;Live application scanning&lt;/li&gt;
&lt;li&gt;Manual testing of authorization and business logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Choose the testing mix based on the application. A public content website, an authenticated SaaS product, and a financial mobile application do not have the same exposure or impact.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Which open-source SAST tool should I choose?
&lt;/h3&gt;

&lt;p&gt;Choose according to the codebase. Semgrep supports many languages and custom rules. Bandit focuses on Python, Brakeman on Ruby on Rails, Gosec on Go, and MobSF on mobile applications. Test shortlisted tools on your own repository before deciding.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can SAST find every vulnerability?
&lt;/h3&gt;

&lt;p&gt;No. SAST can find insecure patterns and some risky data flows, but it may miss runtime configuration, vulnerable dependencies, authorization failures, exposed services, and business-logic flaws.&lt;/p&gt;

&lt;h3&gt;
  
  
  When should a team run SAST?
&lt;/h3&gt;

&lt;p&gt;Run it while developers write and review code, then repeat the scan in continuous integration. Start in reporting mode and introduce release blocking after the team has tuned the rules.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is dependency scanning the same as SAST?
&lt;/h3&gt;

&lt;p&gt;No. SAST analyzes code written for the application. Dependency scanning checks third-party packages and versions against known vulnerability information. Most projects need both.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is SAST enough before launch?
&lt;/h3&gt;

&lt;p&gt;No. Test secrets, dependencies, authentication, authorization, APIs, infrastructure configuration, and the deployed environment. High-risk systems may also need manual penetration testing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can SAST scan AI-generated code?
&lt;/h3&gt;

&lt;p&gt;Yes, if the scanner supports the generated languages and frameworks. Review AI-generated code using the same security controls as human-written code. Developers must still confirm findings and test the deployed application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final guidance
&lt;/h2&gt;

&lt;p&gt;The right SAST tool is the one your team can run, understand, tune, and maintain. Start with language support and workflow fit. Test the output against a real repository before creating release rules.&lt;/p&gt;

&lt;p&gt;Static analysis gives developers visibility into code risks. Dependency checks, secret scanning, live testing, and manual review cover problems that source analysis cannot see. Use the combination that matches the application's exposure and risk.&lt;/p&gt;

</description>
      <category>vibecoding</category>
      <category>security</category>
      <category>infrastructure</category>
      <category>ai</category>
    </item>
    <item>
      <title>A Developer-Friendly Workflow for Triaging Website Security Alerts</title>
      <dc:creator>FlawPilot</dc:creator>
      <pubDate>Fri, 18 Sep 2026 07:40:14 +0000</pubDate>
      <link>https://dev.to/flawpilot/a-developer-friendly-workflow-for-triaging-website-security-alerts-3o90</link>
      <guid>https://dev.to/flawpilot/a-developer-friendly-workflow-for-triaging-website-security-alerts-3o90</guid>
      <description>&lt;p&gt;A security scanner reports a missing header, an exposed key, an unsafe cookie, and a certificate warning. Which one should the team fix first?&lt;/p&gt;

&lt;p&gt;The severity label helps, but it cannot answer that question by itself. A scanner does not know whether the affected asset is public, whether the credential is still valid, how many users depend on the service, or whether anyone is exploiting the weakness.&lt;/p&gt;

&lt;p&gt;Developers need a repeatable way to turn scanner output into engineering work. The workflow below covers the full path: capture the evidence, validate it, decide whether the problem is an incident, assign an owner, make a safe change, and verify production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Normalize the alert before discussing priority
&lt;/h2&gt;

&lt;p&gt;Security tools describe findings in different ways. Before comparing them, put each alert into the same record format.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;finding&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Public&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;API&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;key&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;found&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;in&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;client-side&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;JavaScript"&lt;/span&gt;
  &lt;span class="na"&gt;asset&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://example.com/assets/app.js"&lt;/span&gt;
  &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;production"&lt;/span&gt;
  &lt;span class="na"&gt;detected_at&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YYYY-MM-DD&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;HH:MM&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;UTC"&lt;/span&gt;
  &lt;span class="na"&gt;scanner_severity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;high"&lt;/span&gt;
  &lt;span class="na"&gt;evidence&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Key&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;pattern&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;file&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;location&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;from&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;scan"&lt;/span&gt;

&lt;span class="na"&gt;triage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;publicly_reachable&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;authentication_required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="na"&gt;sensitive_system_affected&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unknown"&lt;/span&gt;
  &lt;span class="na"&gt;active_misuse_observed&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unknown"&lt;/span&gt;
  &lt;span class="na"&gt;temporary_control_available&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="na"&gt;response&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unassigned"&lt;/span&gt;
  &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;new"&lt;/span&gt;
  &lt;span class="na"&gt;containment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;not&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;started"&lt;/span&gt;
  &lt;span class="na"&gt;permanent_fix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;not&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;started"&lt;/span&gt;
  &lt;span class="na"&gt;production_retest&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pending"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not place the full value of a secret, session token, or sensitive record in a general-purpose ticket. Record enough evidence to identify the issue, then store sensitive evidence in a restricted system.&lt;/p&gt;

&lt;p&gt;This common format prevents several mistakes. It separates the scanner's assessment from the team's assessment. It also makes missing information visible instead of letting people assume that someone else checked it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validate the finding against the correct asset
&lt;/h2&gt;

&lt;p&gt;Validation answers two questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does the reported condition still exist?&lt;/li&gt;
&lt;li&gt;Does the evidence point to the actual cause?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Start with the exact URL, hostname, file, port, certificate, DNS record, cookie, or response header named in the report. Confirm that it belongs to the intended environment.&lt;/p&gt;

&lt;p&gt;Production and staging may behave differently because of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CDN or reverse-proxy configuration&lt;/li&gt;
&lt;li&gt;Environment-specific headers&lt;/li&gt;
&lt;li&gt;Redirects between hostnames&lt;/li&gt;
&lt;li&gt;Browser or edge caching&lt;/li&gt;
&lt;li&gt;Different certificates&lt;/li&gt;
&lt;li&gt;Feature flags&lt;/li&gt;
&lt;li&gt;Old deployment assets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For an HTTP header finding, inspect the response returned by the public production URL. For a DNS finding, query the authoritative record rather than relying on an old screenshot. For a client-side exposure, inspect the deployed asset instead of checking only the current source branch.&lt;/p&gt;

&lt;p&gt;Do not dismiss a finding because the page loads correctly. Missing cookie flags, loose cross-origin rules, and weak response headers often have no visible effect on the interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate a security finding from a security incident
&lt;/h2&gt;

&lt;p&gt;A finding reports an unsafe or uncertain condition. An incident involves suspected or confirmed misuse, unauthorized access, data exposure, or service disruption.&lt;/p&gt;

&lt;p&gt;A missing &lt;code&gt;Content-Security-Policy&lt;/code&gt; header is normally a remediation task. A public credential with unexpected activity may require incident response.&lt;/p&gt;

&lt;p&gt;Look for evidence such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication events nobody recognizes&lt;/li&gt;
&lt;li&gt;Requests made with an exposed credential&lt;/li&gt;
&lt;li&gt;Unexpected administrative changes&lt;/li&gt;
&lt;li&gt;Access to data outside an expected pattern&lt;/li&gt;
&lt;li&gt;Unexplained traffic spikes or service disruption&lt;/li&gt;
&lt;li&gt;Cloud, hosting, or repository alerts connected to the finding&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you see these signs, preserve relevant logs before making changes that could destroy evidence. Escalate according to the organization's incident process. An external website scan cannot determine what happened inside private accounts, logs, or authenticated workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prioritize with context, not severity alone
&lt;/h2&gt;

&lt;p&gt;Use the scanner severity as one input. Then review four contextual factors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reachability
&lt;/h3&gt;

&lt;p&gt;Can an unauthenticated person reach the affected asset from the public internet? A production endpoint that anyone can access usually deserves more attention than a private development service.&lt;/p&gt;

&lt;h3&gt;
  
  
  Impact
&lt;/h3&gt;

&lt;p&gt;What could a successful misuse affect? Give more weight to findings connected to user sessions, privileged accounts, production credentials, payment paths, personal data, or administrative functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Preconditions
&lt;/h3&gt;

&lt;p&gt;What must happen before the weakness can be used? A flaw that requires an authenticated administrator and an unusual configuration has different urgency from a working secret inside a public JavaScript bundle.&lt;/p&gt;

&lt;h3&gt;
  
  
  Current evidence
&lt;/h3&gt;

&lt;p&gt;Is the risk theoretical, reproducible, or already being misused? Evidence of active misuse moves the work out of normal backlog prioritization.&lt;/p&gt;

&lt;p&gt;After this review, place the finding into one of four action groups:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Contain now:&lt;/strong&gt; suspected misuse, exposed credentials, unauthorized access, or active disruption&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fix next:&lt;/strong&gt; public weakness with meaningful impact and a practical path to misuse&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schedule:&lt;/strong&gt; missing defense or weak configuration with limited current exposure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Investigate:&lt;/strong&gt; stale, duplicated, environment-specific, or unclear evidence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This classification is an engineering aid. It does not replace contractual, regulatory, or legal response requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Assign the person who controls the affected system
&lt;/h2&gt;

&lt;p&gt;An alert sent to an entire channel often has no owner. Assign one person to coordinate the next action and confirm that they accepted it.&lt;/p&gt;

&lt;p&gt;Ownership usually follows the control:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Application developers own authentication logic, cookie settings, and application-level cross-origin behavior.&lt;/li&gt;
&lt;li&gt;Platform or hosting owners handle response headers, redirects, certificates, public services, and edge configuration.&lt;/li&gt;
&lt;li&gt;Domain or email administrators handle DNSSEC, CAA, SPF, DKIM, and DMARC.&lt;/li&gt;
&lt;li&gt;The developer and service-account owner should work together when a credential is exposed.&lt;/li&gt;
&lt;li&gt;A security or incident-response specialist should guide work when misuse or data exposure is possible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The coordinator does not need to make every change. Their job is to keep the alert from becoming an unowned message thread.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contain immediate risk before completing the repair
&lt;/h2&gt;

&lt;p&gt;Containment reduces exposure while the team works on the root cause.&lt;/p&gt;

&lt;p&gt;If a credential is public, revoke or rotate it. Deleting the value from the latest source file is not sufficient. Copies may remain in build artifacts, browser downloads, CDN caches, deployment history, logs, or Git history.&lt;/p&gt;

&lt;p&gt;After rotation, restrict the replacement credential where possible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Limit its permissions&lt;/li&gt;
&lt;li&gt;Restrict allowed domains or IP addresses&lt;/li&gt;
&lt;li&gt;Set usage limits&lt;/li&gt;
&lt;li&gt;Separate production and development credentials&lt;/li&gt;
&lt;li&gt;Enable provider-side monitoring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If a route or service appears to be under active attack, a temporary response may include disabling the route, restricting access, adding a narrow web application firewall rule, or rolling back a release.&lt;/p&gt;

&lt;p&gt;Containment is not closure. Keep the task open until the team fixes the cause and verifies the live system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the smallest safe change
&lt;/h2&gt;

&lt;p&gt;Broad configuration changes can break authentication, payments, analytics, embedded tools, or third-party scripts.&lt;/p&gt;

&lt;p&gt;Content Security Policy is a common example. Copying a strict policy from an unrelated site may block resources your application needs. Build the policy around the actual scripts, frames, styles, fonts, and connections used by your application. Test the affected user journeys before enforcing it in production.&lt;/p&gt;

&lt;p&gt;Apply the same discipline to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cross-origin resource sharing rules&lt;/li&gt;
&lt;li&gt;Cookie attributes&lt;/li&gt;
&lt;li&gt;Redirect behavior&lt;/li&gt;
&lt;li&gt;Cache controls&lt;/li&gt;
&lt;li&gt;TLS and certificate changes&lt;/li&gt;
&lt;li&gt;DNS records&lt;/li&gt;
&lt;li&gt;Storage permissions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use staging when it represents production accurately. Prepare a rollback path for changes that affect traffic, authentication, or external integrations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retest the public result after deployment
&lt;/h2&gt;

&lt;p&gt;A merged pull request does not prove that the finding disappeared from production.&lt;/p&gt;

&lt;p&gt;The application may still serve an old asset or cached response. The change may exist only in staging. A configuration file may not be connected to the active service.&lt;/p&gt;

&lt;p&gt;Use this verification sequence:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Deploy the change through the normal release process.&lt;/li&gt;
&lt;li&gt;Repeat the original check against the same production asset.&lt;/li&gt;
&lt;li&gt;Confirm that the original evidence is gone.&lt;/li&gt;
&lt;li&gt;Test the user journey that depends on the changed control.&lt;/li&gt;
&lt;li&gt;Check for new warnings or broken behavior.&lt;/li&gt;
&lt;li&gt;Attach the new evidence to the ticket.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Close the task only when the production result matches the intended state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use a reusable remediation issue template
&lt;/h2&gt;

&lt;p&gt;The following Markdown template works in most issue trackers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Finding&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; Title:
&lt;span class="p"&gt;-&lt;/span&gt; Affected asset:
&lt;span class="p"&gt;-&lt;/span&gt; Environment:
&lt;span class="p"&gt;-&lt;/span&gt; Detected at:
&lt;span class="p"&gt;-&lt;/span&gt; Scanner severity:
&lt;span class="p"&gt;-&lt;/span&gt; Evidence location:

&lt;span class="gu"&gt;## Validation&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; [ ] Correct asset and environment confirmed
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Finding reproduced or independently verified
&lt;span class="p"&gt;-&lt;/span&gt; [ ] False-positive conditions reviewed
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Sensitive evidence stored securely

&lt;span class="gu"&gt;## Triage&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; Publicly reachable: Yes / No / Unknown
&lt;span class="p"&gt;-&lt;/span&gt; Authentication required: Yes / No / Unknown
&lt;span class="p"&gt;-&lt;/span&gt; Potential impact:
&lt;span class="p"&gt;-&lt;/span&gt; Preconditions:
&lt;span class="p"&gt;-&lt;/span&gt; Signs of active misuse: Yes / No / Unknown
&lt;span class="p"&gt;-&lt;/span&gt; Action group: Contain now / Fix next / Schedule / Investigate

&lt;span class="gu"&gt;## Ownership&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; Coordinator:
&lt;span class="p"&gt;-&lt;/span&gt; Technical owner:
&lt;span class="p"&gt;-&lt;/span&gt; Target date:
&lt;span class="p"&gt;-&lt;/span&gt; Escalation contact:

&lt;span class="gu"&gt;## Response&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; Containment action:
&lt;span class="p"&gt;-&lt;/span&gt; Root cause:
&lt;span class="p"&gt;-&lt;/span&gt; Permanent fix:
&lt;span class="p"&gt;-&lt;/span&gt; Rollback plan:

&lt;span class="gu"&gt;## Verification&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; Production deployment:
&lt;span class="p"&gt;-&lt;/span&gt; Original check repeated:
&lt;span class="p"&gt;-&lt;/span&gt; User journey tested:
&lt;span class="p"&gt;-&lt;/span&gt; New issues found:
&lt;span class="p"&gt;-&lt;/span&gt; Evidence attached:
&lt;span class="p"&gt;-&lt;/span&gt; Final status:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adjust the fields to match the team's incident process and access controls. Avoid copying secrets or personal data into the issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Define the workflow before the next alert
&lt;/h2&gt;

&lt;p&gt;Write down who reviews new findings, where the team records them, and which conditions start an incident response. Document who can rotate credentials, change DNS, update hosting configuration, and deploy emergency fixes.&lt;/p&gt;

&lt;p&gt;The policy should also define how the team accepts a known risk and when the same asset will be checked again. A finding should not disappear simply because the current sprint ended.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://csrc.nist.gov/pubs/sp/800/61/r3/final" rel="noopener noreferrer"&gt;NIST SP 800-61 Revision 3&lt;/a&gt; connects preparation, detection, response, and recovery. A small team may combine several roles, but it still needs clear ownership and an escalation path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing thought
&lt;/h2&gt;

&lt;p&gt;Scanner output is evidence, not a completed decision. Validate the affected asset, add technical and business context, and assign a person who can move the work forward.&lt;/p&gt;

&lt;p&gt;For urgent exposure, contain first. For normal remediation, make a controlled change and retest the public system. The alert is resolved only when production evidence confirms the fix.&lt;/p&gt;




&lt;p&gt;This article is adapted from an &lt;a href="https://flawpilot.com/blog/how-to-respond-to-website-security-alerts" rel="noopener noreferrer"&gt;original guide published on FlawPilot&lt;/a&gt;. It contains no affiliate links or paid placement.&lt;/p&gt;

</description>
      <category>security</category>
      <category>webdev</category>
      <category>cybersecurity</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Lovable App Security We Scanned a Real App and Found 29 Open Issues</title>
      <dc:creator>FlawPilot</dc:creator>
      <pubDate>Fri, 14 Aug 2026 12:29:29 +0000</pubDate>
      <link>https://dev.to/flawpilot/lovable-app-security-we-scanned-a-real-app-and-found-29-open-issues-4hj1</link>
      <guid>https://dev.to/flawpilot/lovable-app-security-we-scanned-a-real-app-and-found-29-open-issues-4hj1</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxcmt6hej70ia942uz9gr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxcmt6hej70ia942uz9gr.png" alt=" " width="800" height="521"&gt;&lt;/a&gt;Quick answer: Lovable app security's most common failure isn't a missing header. It's an unset Supabase Row-Level Security policy. Skip it and the app still works, because the query still succeeds, just for anyone, not only its owner. We scanned a real Lovable app and found exactly that gap, live.&lt;/p&gt;

&lt;p&gt;Picture the app you shipped last sprint. You described a dashboard, Lovable wired up the tables, the auth, the UI, and it all just worked the first time you clicked through it. That's the whole appeal. It's also exactly why nobody goes back and checks the one setting that doesn't announce itself when it's missing. So we did. We took a real, live Lovable app, built the way most Lovable apps get built (fast, from a prompt, shipped the same week), and ran it through &lt;a href="https://flawpilot.com?utm_source=devto&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lovable-app-security" rel="noopener noreferrer"&gt;FlawPilot&lt;/a&gt;, a free scan that checks a site's &lt;a href="https://flawpilot.com/use-cases/security?utm_source=devto&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lovable-app-security" rel="noopener noreferrer"&gt;security&lt;/a&gt;, &lt;a href="https://flawpilot.com/use-cases/performance?utm_source=devto&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lovable-app-security" rel="noopener noreferrer"&gt;performance&lt;/a&gt;, &lt;a href="https://flawpilot.com/use-cases/infrastructure?utm_source=devto&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lovable-app-security" rel="noopener noreferrer"&gt;infrastructure&lt;/a&gt;, and &lt;a href="https://flawpilot.com/use-cases/seo?utm_source=devto&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lovable-app-security" rel="noopener noreferrer"&gt;SEO&lt;/a&gt; in about two minutes, no login required. We won't name the app, but every number below is real, pulled straight from its report.&lt;/p&gt;

&lt;h2&gt;
  
  
  The scorecard
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;63 out of 100. "At risk."&lt;/strong&gt; 252 points out of a possible 400, and 29 things sitting open: 1 critical, 5 high, 15 medium, 8 low.&lt;/p&gt;

&lt;p&gt;Split out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security: 55/100.&lt;/strong&gt; At risk. 13 findings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance: 96/100.&lt;/strong&gt; Excellent. 2 findings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure: 58/100.&lt;/strong&gt; At risk. 9 findings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SEO &amp;amp; Discoverability: 62/100.&lt;/strong&gt; Needs attention. 5 findings.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nothing was defaced. The app looked, and behaved, exactly like it was supposed to. That's the part worth sitting with: every screen worked, every click did the right thing, and the one critical finding on this report had never once shown up as a bug.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it got right
&lt;/h2&gt;

&lt;p&gt;96/100 on performance is close to a clean sweep. Lovable's scaffolding leans on Vite and React defaults that are already fast out of the box: quick first paint, sensible bundle size, nothing render-blocking that shouldn't be.&lt;/p&gt;

&lt;p&gt;Which is exactly the trap. A fast, polished frontend is the thing you notice with your own eyes, so it's the thing that gets credited as "done." Everything below is the kind of gap that only shows up once something outside the team, a scanner, a bot, or someone who isn't supposed to, goes looking for it on purpose.&lt;/p&gt;

&lt;h2&gt;
  
  
  What was hiding underneath
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A Supabase table had no Row-Level Security policy at all.&lt;/strong&gt; Rated Critical, and it's the finding that matters most on this whole report. Lovable apps run on Supabase by default, and Supabase enforces access at the database layer through RLS policies, not through the app's own login screen. Turn RLS on for a table and the database itself checks who's allowed to see which row. Leave it off, and the table is exactly as open as the &lt;code&gt;anon&lt;/code&gt; key that ships in every Lovable app's JS bundle: open to anyone who opens dev tools and watches a single network request. This app's login screen worked correctly the whole time. The database behind it never checked whether the person asking was allowed to see the data they were asking for.&lt;/p&gt;

&lt;p&gt;The fix, in Supabase, is two SQL statements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Enable Row-Level Security on the table&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="n"&gt;ENABLE&lt;/span&gt; &lt;span class="k"&gt;ROW&lt;/span&gt; &lt;span class="k"&gt;LEVEL&lt;/span&gt; &lt;span class="k"&gt;SECURITY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Scope reads to the row's own owner&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;POLICY&lt;/span&gt; &lt;span class="nv"&gt;"Users can view their own orders"&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;FOR&lt;/span&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt;
&lt;span class="k"&gt;USING&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No rewrite, no data migration, just a policy that tells the database who's allowed to see which row instead of trusting the app's UI to gate it for you. Repeat per table, per operation (&lt;code&gt;SELECT&lt;/code&gt;, &lt;code&gt;INSERT&lt;/code&gt;, &lt;code&gt;UPDATE&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt;) as needed.&lt;/p&gt;

&lt;p&gt;The rest of the report was more familiar territory:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No DMARC record&lt;/strong&gt;: anyone could send email pretending to be this domain (High)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No &lt;code&gt;Content-Security-Policy&lt;/code&gt; header&lt;/strong&gt;: an injected script has nowhere to be stopped (High)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No &lt;code&gt;Strict-Transport-Security&lt;/code&gt; header&lt;/strong&gt;: first request can get downgraded to plain HTTP (High)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No clickjacking protection&lt;/strong&gt;: the app can be framed invisibly inside another page (High)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No CAA record&lt;/strong&gt;: any certificate authority could issue a cert for the domain (Medium)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No DKIM signature&lt;/strong&gt;: outgoing mail at real risk of landing in spam (Medium)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Missing &lt;code&gt;sitemap.xml&lt;/code&gt;, thin meta descriptions&lt;/strong&gt;: dragged the SEO score to 62 (Medium)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verbose error pages left on&lt;/strong&gt;: handing back stack traces to anyone who triggers one (Medium)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this showed up while clicking through the app. All of it shows up the moment something outside the team, a scanner, a bot, an attacker, bothers to check.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this is the default, not a fluke
&lt;/h2&gt;

&lt;p&gt;That combination, an unset RLS policy sitting next to missing headers and no DMARC, is close to the single most repeated pattern across Lovable apps specifically. Lovable isn't careless, it's optimizing for "the prompt works," and a Supabase table without an RLS policy still returns exactly the data you asked for in testing. The query succeeds either way. Nothing about that failure looks like a failure until someone sends a request the app wasn't expecting.&lt;/p&gt;

&lt;p&gt;This isn't hypothetical. In March 2025, this exact gap, missing RLS in Lovable-generated apps, was catalogued as &lt;strong&gt;CVE-2025-48757&lt;/strong&gt; (CVSS base score 8.26, High), and left more than 170 live production apps with databases any unauthenticated visitor could read, write to, or delete from, just by inspecting the app's own network requests. Nobody shipped a bug that broke anything. The gap was a security control nobody had reason to think about, sitting quietly under apps that worked perfectly for months.&lt;/p&gt;

&lt;p&gt;The broader research backs this up. Veracode's GenAI Code Security testing has run over 100 models across 80 coding tasks over four years, and the average pass rate on a security review has held at roughly 56%, meaning close to 44% of AI-generated code fails a review outright. A 2023 Stanford study (Perry et al., ACM CCS) found the same pattern at the human level: developers using an AI coding assistant wrote measurably less secure code than developers working without one, and felt &lt;em&gt;more&lt;/em&gt; confident about it, not less. The role that used to catch an unset RLS policy, a senior engineer flagging it in code review, mostly doesn't exist in a Lovable workflow, because there's often no review step between describing the app and the app going live.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to actually fix this
&lt;/h2&gt;

&lt;p&gt;A severity label is only useful if it turns into something you actually do. Here's how FlawPilot handles that on this exact report.&lt;/p&gt;

&lt;p&gt;Every finding gets grouped by area and dropped into a ranked &lt;strong&gt;"What to do next"&lt;/strong&gt; list, not a raw dump of jargon. Item one was the RLS finding, and next to it, in plain English: &lt;em&gt;enable Row-Level Security on this table and add a policy scoping rows to the authenticated user.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Four of the five High findings here (CSP, HSTS, clickjacking, DMARC) are pure configuration, no application logic involved. The RLS fix is a Supabase policy, not a rewrite. Clear those five and close out the CAA and DKIM gaps next to them, and a security score that opened at 55 is realistically headed for the 90s.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it on your own app
&lt;/h2&gt;

&lt;p&gt;No setup, no coding, no passwords required. Drop in a URL, and in about two minutes you get a full scorecard: security, performance, infrastructure, and SEO, each out of 100, every finding in plain English, with a toggle between a plain-language view and the full technical one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://flawpilot.com/?utm_source=devto&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lovable-app-security" rel="noopener noreferrer"&gt;Scan your Lovable app for free →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is Lovable secure by default?&lt;/strong&gt;&lt;br&gt;
Not fully. Lovable handles HTTPS and gets you a working auth flow fast, but Row-Level Security on your Supabase tables is opt-in, and HTTP security headers, DMARC, and DNS hardening aren't configured automatically either.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's the single most common Lovable security issue?&lt;/strong&gt;&lt;br&gt;
A Supabase table with no Row-Level Security policy, also the most severe, since it can leave underlying data readable or writable by anyone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does scanning my site give FlawPilot access to my Supabase project?&lt;/strong&gt;&lt;br&gt;
No. The scan only checks publicly accessible signals, the same things any browser or bot on the internet can already see. It never touches your Supabase dashboard, your database directly, or your credentials.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I fix this myself without hiring anyone?&lt;/strong&gt;&lt;br&gt;
Header, DNS, and email-authentication fixes usually live in your hosting or DNS provider's dashboard. The RLS fix lives in your Supabase project's SQL editor or policy UI and takes minutes once you know which table needs it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How often should I actually check this?&lt;/strong&gt;&lt;br&gt;
Before anything you'd call a real release, and again any time you add a new table, since a new table means RLS is opt-in again.&lt;/p&gt;




&lt;p&gt;The app worked the whole time. The database behind it never once did. That gap is the part worth remembering long after the specific header names and CVE numbers fade: "it works" and "it's secure" get checked by two different questions, and only one of them shows up on screen.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>supabase</category>
      <category>security</category>
    </item>
  </channel>
</rss>
