<?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: Mansoor Mirza</title>
    <description>The latest articles on DEV Community by Mansoor Mirza (@itsmirza).</description>
    <link>https://dev.to/itsmirza</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%2F4195312%2F4e8d8893-cf2c-4450-bbf7-c593a6464a3f.jpg</url>
      <title>DEV Community: Mansoor Mirza</title>
      <link>https://dev.to/itsmirza</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/itsmirza"/>
    <language>en</language>
    <item>
      <title>I scanned 62 live AI-built apps from Show HN. Here's what they miss before launch</title>
      <dc:creator>Mansoor Mirza</dc:creator>
      <pubDate>Tue, 20 Oct 2026 04:25:11 +0000</pubDate>
      <link>https://dev.to/itsmirza/i-scanned-62-live-ai-built-apps-from-show-hn-heres-what-they-miss-before-launch-3lng</link>
      <guid>https://dev.to/itsmirza/i-scanned-62-live-ai-built-apps-from-show-hn-heres-what-they-miss-before-launch-3lng</guid>
      <description>&lt;p&gt;I build &lt;a href="https://shipitsafe.dev" rel="noopener noreferrer"&gt;ShipSafe&lt;/a&gt;, a launch-readiness scanner for apps made with Lovable, Bolt, v0, Replit and friends. Before I told anyone it was useful, I wanted real data, so I pointed it at other people's launches.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Method (and what I did &lt;em&gt;not&lt;/em&gt; do).&lt;/strong&gt; I pulled every Show HN post that linked to a &lt;code&gt;*.lovable.app&lt;/code&gt;, &lt;code&gt;*.replit.app&lt;/code&gt; or &lt;code&gt;*.bolt.host&lt;/code&gt; URL (101 apps) and ran each through the same passive checks the free scan uses: one page load, response headers, &lt;code&gt;robots.txt&lt;/code&gt;, &lt;code&gt;sitemap.xml&lt;/code&gt;, the HTML and the public JS bundle. No logins, no form submissions, no probing endpoints, no exploitation. I'm not naming any app; this is aggregate only.&lt;/p&gt;

&lt;h2&gt;
  
  
  The headline numbers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;101 apps&lt;/strong&gt; posted to Show HN; &lt;strong&gt;100&lt;/strong&gt; answered.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;38 of 100 were already dead&lt;/strong&gt; (HTTP 404 on the home page). Replit was hit hardest: &lt;strong&gt;32 of 44&lt;/strong&gt; Replit links were gone, vs 6 of 55 Lovable links. Free hosting that sleeps or expires is a real launch risk.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;62 live apps averaged 73.5/100&lt;/strong&gt; (median 76, range 45–92). Only &lt;strong&gt;1&lt;/strong&gt; scored 90+; &lt;strong&gt;14&lt;/strong&gt; scored under 70.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;8.5 findings per app&lt;/strong&gt; on average.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leaked secrets: 0.&lt;/strong&gt; I specifically looked for API keys and tokens in the HTML and JS bundles (OpenAI, Stripe secret keys, AWS, service-role keys, etc.) and found none. Good news, and honestly not what I expected. The problems were elsewhere.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Finding&lt;/th&gt;
&lt;th&gt;Live apps affected&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Missing security headers (CSP, HSTS, X-Frame-Options…)&lt;/td&gt;
&lt;td&gt;62 / 62 (100%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No error monitoring&lt;/td&gt;
&lt;td&gt;59 (95%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No canonical URL&lt;/td&gt;
&lt;td&gt;57 (92%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No sitemap.xml&lt;/td&gt;
&lt;td&gt;54 (87%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No analytics&lt;/td&gt;
&lt;td&gt;54 (87%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No privacy policy / terms / contact link&lt;/td&gt;
&lt;td&gt;35 (56%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No favicon&lt;/td&gt;
&lt;td&gt;33 (53%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supabase in use: Row Level Security must be verified&lt;/td&gt;
&lt;td&gt;32 (52%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No robots.txt&lt;/td&gt;
&lt;td&gt;16 (26%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Incomplete Open Graph tags&lt;/td&gt;
&lt;td&gt;14 (23%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Server reveals its tech stack&lt;/td&gt;
&lt;td&gt;11 (18%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Oversized JS bundle&lt;/td&gt;
&lt;td&gt;9 (15%)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A fairness note: on &lt;code&gt;*.lovable.app&lt;/code&gt; and &lt;code&gt;*.bolt.host&lt;/code&gt; the platform controls the response headers, so 47 of the 62 header findings are not the builder's fault. They go away (or become yours to fix) once you move to a custom domain. That's exactly when people forget them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 5 problems worth fixing before you launch
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Supabase without verified Row Level Security (52%)
&lt;/h3&gt;

&lt;p&gt;Half the live apps ship a Supabase client in the browser. That's normal: the anon key is &lt;em&gt;meant&lt;/em&gt; to be public. But it means &lt;strong&gt;your RLS policies are the only thing between a stranger and your tables&lt;/strong&gt;. A passive scan can't (and shouldn't) test them, so treat this as a checklist item, not a verdict. Tables created by the AI without policies, or with &lt;code&gt;using (true)&lt;/code&gt;, are the classic vibe-coded data leak.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; In Supabase → Table Editor, every table should show "RLS enabled", and every policy should scope rows to &lt;code&gt;auth.uid()&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AI prompt:&lt;/strong&gt; "List every Supabase table this app uses. For each, enable Row Level Security and write policies so users can only select, insert, update and delete rows where &lt;code&gt;user_id = auth.uid()&lt;/code&gt;. Show me the SQL, and flag any table that is intentionally public. Never use the service-role key in client code."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then test it: open your app in a private window, logged out, and try to read data from the browser console with the anon key. You should get nothing back.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Missing security headers (100%)
&lt;/h3&gt;

&lt;p&gt;No &lt;code&gt;Content-Security-Policy&lt;/code&gt;, &lt;code&gt;Strict-Transport-Security&lt;/code&gt;, &lt;code&gt;X-Frame-Options&lt;/code&gt;/&lt;code&gt;frame-ancestors&lt;/code&gt;, &lt;code&gt;X-Content-Type-Options&lt;/code&gt; or &lt;code&gt;Referrer-Policy&lt;/code&gt;. Without them your app can be framed for clickjacking and any injected script runs freely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; On a custom domain behind Vercel/Netlify/Cloudflare, add them in config.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AI prompt:&lt;/strong&gt; "Add these response headers to every route: Strict-Transport-Security: max-age=63072000; includeSubDomains; preload, X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, X-Frame-Options: DENY, Permissions-Policy: camera=(), microphone=(), geolocation=(), and a Content-Security-Policy that only allows the domains this app actually loads scripts, styles, images and API calls from. Put them in vercel.json (or netlify.toml / _headers) and list every third-party domain you included in the CSP."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Start CSP in &lt;code&gt;Content-Security-Policy-Report-Only&lt;/code&gt; mode if you're nervous about breaking things.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. No privacy policy, terms or contact (56%)
&lt;/h3&gt;

&lt;p&gt;More than half of live apps collect emails or logins but have no privacy policy, no terms and no way to reach a human. That's a GDPR problem the day an EU user signs up, it's a blocker for Stripe/Gumroad review and app stores, and visitors notice.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AI prompt:&lt;/strong&gt; "Create /privacy and /terms pages for this app. It collects: [email, name, usage data]. It uses: [Supabase, Stripe, OpenAI, analytics tool]. Write plain-English pages that say what's collected, why, which processors receive it, how long it's kept, and how to request deletion at [your email]. Link both pages and a contact email in the footer of every page."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Have a human read it. It's a starting point, not legal advice.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Flying blind: no error monitoring (95%) and no analytics (87%)
&lt;/h3&gt;

&lt;p&gt;Almost nobody had Sentry (or similar) wired up, so when the launch traffic hits and something breaks, the founder finds out from an angry comment. And 87% had no analytics, so they can't tell whether Show HN sent 20 visitors or 2,000.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AI prompt:&lt;/strong&gt; "Add Sentry error monitoring to this app for both the frontend and any server/edge functions, with source maps uploaded on build and the DSN read from an environment variable. Also add [Plausible / PostHog / Vercel Analytics] page-view tracking. Don't log personal data in error reports."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  5. Invisible to search and social: no sitemap (87%), canonical (92%), robots.txt, OG tags
&lt;/h3&gt;

&lt;p&gt;Single-page apps from AI builders often ship one &lt;code&gt;index.html&lt;/code&gt; with no &lt;code&gt;sitemap.xml&lt;/code&gt;, no canonical link and half-filled Open Graph tags, so links shared on X, Slack or LinkedIn show a blank card. Two apps still had the default title "Lovable App".&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AI prompt:&lt;/strong&gt; "Make this app shareable and indexable: set a unique &lt;/p&gt;
 and meta description per page, add a canonical link tag, full Open Graph and Twitter card tags with a 1200×630 image, a favicon, a robots.txt that allows crawling and points to the sitemap, and a sitemap.xml listing every public route."&amp;lt;/p&amp;gt;
&amp;lt;/blockquote&amp;gt;
&amp;lt;h2&amp;gt;
  &amp;lt;a name="bonus-keep-your-app-alive" href="#bonus-keep-your-app-alive" class="anchor"&amp;gt;
  &amp;lt;/a&amp;gt;
  Bonus: keep your app alive
&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;38% of the apps in this study were dead weeks or months after their Show HN. If you launch on a free tier, put it on a custom domain, check what happens when the free plan sleeps or expires, and add a free uptime monitor.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;
  &amp;lt;a name="what-surprised-me" href="#what-surprised-me" class="anchor"&amp;gt;
  &amp;lt;/a&amp;gt;
  What surprised me
&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;I went in expecting leaked API keys everywhere. I found none. The AI builders have gotten much better at keeping secrets out of the frontend. What they &amp;lt;em&amp;gt;don't&amp;lt;/em&amp;gt; do is the boring launch checklist: headers, legal pages, monitoring, SEO basics and, most importantly, checking the database permissions behind that public Supabase key.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;
  &amp;lt;a name="check-your-own-app" href="#check-your-own-app" class="anchor"&amp;gt;
  &amp;lt;/a&amp;gt;
  Check your own app
&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;If you want to run the same checks on your app before you post it, the scan at &amp;lt;a href="https://shipitsafe.dev"&amp;gt;shipitsafe.dev&amp;lt;/a&amp;gt; is free and takes about 30 seconds. It gives you a score and the list of issues. There's an optional $9 report with step-by-step fixes and AI prompts for each one, but the free scan alone covers everything in this post.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Happy (safe) shipping. Questions about the method are welcome in the comments.&amp;lt;/p&amp;gt;

&lt;/blockquote&gt;

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