<?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>Forem: Ben</title>
    <description>The latest articles on Forem by Ben (@benwilkins).</description>
    <link>https://forem.com/benwilkins</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3186146%2Fc568c61a-3606-46e5-8825-15244a8e29b0.png</url>
      <title>Forem: Ben</title>
      <link>https://forem.com/benwilkins</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/benwilkins"/>
    <language>en</language>
    <item>
      <title>The Security Holes AI Always Creates (And How to Spot Them)</title>
      <dc:creator>Ben</dc:creator>
      <pubDate>Fri, 06 Jun 2025 08:12:03 +0000</pubDate>
      <link>https://forem.com/benwilkins/the-security-holes-ai-always-creates-and-how-to-spot-them-5h68</link>
      <guid>https://forem.com/benwilkins/the-security-holes-ai-always-creates-and-how-to-spot-them-5h68</guid>
      <description>&lt;p&gt;AI is incredible at writing code fast. It's terrible at writing secure code.&lt;/p&gt;

&lt;p&gt;After months of reviewing AI-generated code, I've noticed the same security holes appear over and over. Here are the patterns that keep showing up, and how to catch them before they become problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Input Validation? What Input Validation?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What AI does:&lt;/strong&gt;&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="c1"&gt;// AI loves writing this&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&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;body&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;age&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="nf"&gt;save&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;&lt;strong&gt;The problem:&lt;/strong&gt; No validation whatsoever. AI treats user input like trusted data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What you'll actually get:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Empty strings breaking your database&lt;/li&gt;
&lt;li&gt;Malicious scripts in name fields&lt;/li&gt;
&lt;li&gt;Negative ages and impossible dates&lt;/li&gt;
&lt;li&gt;Emails like "definitely-not-an-email"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How to spot it:&lt;/strong&gt; Look for any endpoint that takes &lt;code&gt;req.body&lt;/code&gt; data and uses it directly without checking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick fix:&lt;/strong&gt;&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;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&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;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Add this validation AI never includes&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;name&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100&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;400&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="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid name&lt;/span&gt;&lt;span class="dl"&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;email&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@&lt;/span&gt;&lt;span class="dl"&gt;'&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;400&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="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid email&lt;/span&gt;&lt;span class="dl"&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;age&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;150&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;400&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="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid age&lt;/span&gt;&lt;span class="dl"&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;age&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="nf"&gt;save&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;h2&gt;
  
  
  2. SQL Injection Paradise
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What AI does:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# AI's favorite database pattern
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM users WHERE id = &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; Direct string interpolation with user input.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens:&lt;/strong&gt; Someone sends &lt;code&gt;user_id = "1; DROP TABLE users; --"&lt;/code&gt; and your database disappears.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to spot it:&lt;/strong&gt; Any database query that uses f-strings, string concatenation, or template literals with user input.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick fix:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="c1"&gt;# Use parameterized queries
&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM users WHERE id = ?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&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;h2&gt;
  
  
  3. Authentication That Doesn't Authenticate
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What AI does:&lt;/strong&gt;&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="c1"&gt;// AI's idea of "security"&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isAuthenticated&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="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;return&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;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authorization&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bearer valid-token&lt;/span&gt;&lt;span class="dl"&gt;'&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;&lt;strong&gt;The problem:&lt;/strong&gt; Hardcoded tokens, predictable session IDs, or no expiration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real examples I've seen:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Session tokens that are just the username&lt;/li&gt;
&lt;li&gt;JWTs with no expiration date&lt;/li&gt;
&lt;li&gt;API keys hardcoded in the frontend&lt;/li&gt;
&lt;li&gt;"Admin" role based on URL parameters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How to spot it:&lt;/strong&gt; Any auth code that looks too simple or uses predictable values.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to look for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hardcoded secrets in the code&lt;/li&gt;
&lt;li&gt;Tokens that don't expire&lt;/li&gt;
&lt;li&gt;Client-side role checking only&lt;/li&gt;
&lt;li&gt;Predictable session identifiers&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Error Messages That Tell Attackers Everything
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What AI does:&lt;/strong&gt;&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;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;'&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="k"&gt;try&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;user&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;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;email&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;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&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;user&lt;/span&gt;&lt;span class="p"&gt;)&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;401&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="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;No user found with that email&lt;/span&gt;&lt;span class="dl"&gt;'&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;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;checkPassword&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;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;))&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;401&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="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Incorrect password for user@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&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;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&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="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt; &lt;span class="p"&gt;});&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;&lt;strong&gt;The problem:&lt;/strong&gt; These errors tell attackers which emails exist in your system and provide debugging info they shouldn't see.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to spot it:&lt;/strong&gt; Error messages that reveal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Database schema details&lt;/li&gt;
&lt;li&gt;File paths&lt;/li&gt;
&lt;li&gt;Whether users exist&lt;/li&gt;
&lt;li&gt;Internal system information&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Quick fix:&lt;/strong&gt; Use generic error messages for authentication failures.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. CORS Wildcards Everywhere
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What AI does:&lt;/strong&gt;&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="c1"&gt;// AI's solution to CORS errors&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;span class="na"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="na"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; This allows any website to make authenticated requests to your API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What this enables:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cross-site request forgery&lt;/li&gt;
&lt;li&gt;Data theft from any malicious website&lt;/li&gt;
&lt;li&gt;Unauthorized API access&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How to spot it:&lt;/strong&gt; Look for &lt;code&gt;origin: '*'&lt;/code&gt; or missing CORS configuration entirely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick fix:&lt;/strong&gt; Specify exact origins you trust:&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;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;span class="na"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://yourdomain.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://www.yourdomain.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="na"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. Secrets in Plain Sight
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What AI does:&lt;/strong&gt;&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="c1"&gt;// AI loves putting secrets directly in code&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="na"&gt;dbPassword&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;super-secret-password-123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ak-1234567890abcdef&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="na"&gt;jwtSecret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-jwt-secret&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; These end up in version control, logs, and error messages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to spot it:&lt;/strong&gt; Any hardcoded passwords, API keys, or sensitive configuration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick fix:&lt;/strong&gt; Use environment variables:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="na"&gt;dbPassword&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="na"&gt;jwtSecret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JWT_SECRET&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Pattern
&lt;/h2&gt;

&lt;p&gt;AI writes code like it's running in a perfect, trusted environment. It doesn't think about malicious users, edge cases, or security threats.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The AI mindset:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All input is valid and well-intentioned&lt;/li&gt;
&lt;li&gt;Network requests always succeed&lt;/li&gt;
&lt;li&gt;Users won't try to break things&lt;/li&gt;
&lt;li&gt;Error messages help developers (not attackers)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The reality:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Users will try every possible input&lt;/li&gt;
&lt;li&gt;Attackers actively look for vulnerabilities&lt;/li&gt;
&lt;li&gt;Error messages become reconnaissance tools&lt;/li&gt;
&lt;li&gt;Everything that can break will break&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick Security Checklist
&lt;/h2&gt;

&lt;p&gt;When reviewing AI-generated code, always check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;strong&gt;Input validation:&lt;/strong&gt; Does it check user input before using it?&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;SQL injection:&lt;/strong&gt; Are database queries parameterized?&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Authentication:&lt;/strong&gt; Are tokens secure and do they expire?&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Error handling:&lt;/strong&gt; Do errors reveal sensitive information?&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;CORS policy:&lt;/strong&gt; Is it more restrictive than &lt;code&gt;origin: '*'&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Secrets:&lt;/strong&gt; Are they in environment variables, not hardcoded?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Working With AI Securely
&lt;/h2&gt;

&lt;p&gt;AI is still incredibly useful for coding - you just need to understand its security blind spots.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The typical workflow:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Let AI write the functional code&lt;/li&gt;
&lt;li&gt;Review it specifically for these security patterns&lt;/li&gt;
&lt;li&gt;Ask AI to fix the security issues you find&lt;/li&gt;
&lt;li&gt;Test the edge cases AI didn't consider&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The goal isn't to avoid AI - it's to understand its limitations and compensate for them.&lt;/p&gt;

&lt;p&gt;At &lt;a href="https://pythagora.ai" rel="noopener noreferrer"&gt;Pythagora&lt;/a&gt;, we've built security reviews directly into the AI development process. Instead of requiring developers to manually catch these patterns, our platform identifies common security issues as code is generated and suggests fixes automatically.&lt;/p&gt;

&lt;p&gt;Because security shouldn't be an afterthought you have to remember - it should be integrated into the development workflow from the start.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;AI writes fast code, not secure code. Know the difference.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>5 Prompts That Make Any AI App More Secure</title>
      <dc:creator>Ben</dc:creator>
      <pubDate>Wed, 28 May 2025 14:48:51 +0000</pubDate>
      <link>https://forem.com/benwilkins/5-prompts-that-make-any-ai-app-more-secure-2fka</link>
      <guid>https://forem.com/benwilkins/5-prompts-that-make-any-ai-app-more-secure-2fka</guid>
      <description>&lt;p&gt;AI platforms are great at building functional apps quickly, but they often skip basic security measures. Here are five copy-paste prompts that will add essential security to any AI-generated application.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Input Sanitization
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt; AI platforms rarely validate user input properly, leaving your app vulnerable to injection attacks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Copy this prompt:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Add input validation to all forms that:
- Removes HTML tags and script elements from text inputs
- Validates email formats before saving
- Limits text input length to reasonable maximums
- Escapes special characters in database queries
- Shows specific error messages for invalid input
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What this prevents:&lt;/strong&gt; XSS attacks, SQL injection, and data corruption from malicious or malformed input.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Proper Authentication
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt; Basic login/logout isn't enough. Most AI apps have weak session management and password policies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Copy this prompt:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Implement secure authentication with:
- Password requirements: minimum 8 characters, mix of letters and numbers
- Account lockout after 5 failed login attempts
- Session timeout after 30 minutes of inactivity
- Secure password reset via email verification
- Force logout when user role changes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What this prevents:&lt;/strong&gt; Brute force attacks, session hijacking, and unauthorized access.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Access Control
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt; AI platforms often create apps where any logged-in user can access any data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Copy this prompt:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Add role-based access control where:
- Users can only view and edit their own data
- Admins require separate login confirmation for sensitive actions
- API endpoints check user permissions before returning data
- Direct URL access to restricted pages redirects to login
- Database queries filter results by user ownership automatically
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What this prevents:&lt;/strong&gt; Data breaches, unauthorized data access, and privilege escalation.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Secure Data Storage
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt; Sensitive data often gets stored in plain text, visible to anyone with database access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Copy this prompt:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Secure sensitive data by:
- Hashing all passwords with bcrypt before database storage
- Encrypting personally identifiable information (PII) like emails and phone numbers
- Never storing credit card or payment information directly
- Adding database constraints to prevent duplicate sensitive records
- Creating audit logs for all data access and modifications
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What this prevents:&lt;/strong&gt; Data breaches exposing user passwords and personal information.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. API Security
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt; AI-generated APIs often lack rate limiting and proper error handling, making them easy targets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Copy this prompt:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Secure all API endpoints with:
- Rate limiting: maximum 100 requests per user per minute
- Authentication required for all data modification endpoints
- Generic error messages that don't reveal system information
- CORS headers configured for your specific domain only
- Request logging for monitoring suspicious activity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What this prevents:&lt;/strong&gt; DDoS attacks, API abuse, and information disclosure through error messages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Security Test
&lt;/h2&gt;

&lt;p&gt;After implementing these prompts, test your security improvements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Try submitting forms with: &lt;code&gt;&amp;lt;script&amp;gt;alert('test')&amp;lt;/script&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Attempt to access another user's data by changing IDs in URLs&lt;/li&gt;
&lt;li&gt;Test password reset with invalid email addresses&lt;/li&gt;
&lt;li&gt;Make rapid API requests to trigger rate limiting&lt;/li&gt;
&lt;li&gt;Check error messages don't reveal sensitive system details&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why These Prompts Work
&lt;/h2&gt;

&lt;p&gt;AI platforms understand security concepts but don't implement them by default because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They prioritize speed over security in demos&lt;/li&gt;
&lt;li&gt;Security adds complexity that might confuse beginners&lt;/li&gt;
&lt;li&gt;They assume you'll add security later (most people don't)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By explicitly requesting these security measures, you're telling the AI to prioritize protection over simplicity.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Doesn't Cover
&lt;/h2&gt;

&lt;p&gt;These prompts handle the basics, but production apps need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTPS/SSL certificates (usually handled by hosting)&lt;/li&gt;
&lt;li&gt;Regular security updates and patches&lt;/li&gt;
&lt;li&gt;Penetration testing for serious applications&lt;/li&gt;
&lt;li&gt;Compliance requirements (GDPR, HIPAA, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For simple projects and MVPs, these five prompts provide solid baseline security without requiring deep security expertise.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Security Mindset
&lt;/h2&gt;

&lt;p&gt;Security isn't about perfect protection but rather about making your app a harder target than the alternatives. These prompts raise the bar enough to deter casual attacks and protect against common vulnerabilities.&lt;/p&gt;

&lt;p&gt;At &lt;a href="https://pythagora.ai" rel="noopener noreferrer"&gt;Pythagora&lt;/a&gt;, we build these security measures into the development process by default, rather than requiring separate prompts. Security shouldn't be an afterthought - it should be integrated from the first line of code.&lt;/p&gt;

&lt;p&gt;But regardless of which platform you use, adding these five prompts to your development workflow will make your AI-generated apps significantly more secure with minimal effort.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Pythagora 2.0 launches in June 2025 with security-first development practices built directly into the AI workflow.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>security</category>
      <category>learning</category>
    </item>
    <item>
      <title>A Practical Guide to Debugging AI-Built Applications</title>
      <dc:creator>Ben</dc:creator>
      <pubDate>Mon, 26 May 2025 13:38:41 +0000</pubDate>
      <link>https://forem.com/benwilkins/a-practical-guide-to-debugging-ai-built-applications-4dn9</link>
      <guid>https://forem.com/benwilkins/a-practical-guide-to-debugging-ai-built-applications-4dn9</guid>
      <description>&lt;p&gt;Your AI-generated app was working perfectly yesterday. Today, it's throwing errors, displaying blank pages, or worse - silently failing without any indication of what went wrong.&lt;/p&gt;

&lt;p&gt;This scenario plays out thousands of times every day across AI development platforms. The app generation part works brilliantly, but when things break, most users are left stranded.&lt;/p&gt;

&lt;p&gt;Unlike traditional development where you have full access to logs, database queries, and debugging tools, AI platforms often leave you guessing about what's happening under the hood.&lt;/p&gt;

&lt;p&gt;If you've already done some basic testing (we covered practical testing strategies in our guide to &lt;a href="https://blog.pythagora.ai/will-your-ai-app-break-in-production-3-ways-to-test-it/" rel="noopener noreferrer"&gt;identifying production issues&lt;/a&gt;), you might have found problems but still struggle to understand why they're happening or how to fix them systematically.&lt;/p&gt;

&lt;p&gt;This guide covers practical debugging strategies that work within the constraints of AI development platforms, plus what to look for in tools that actually help you solve problems instead of just generating code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Debugging Problem with AI Platforms
&lt;/h2&gt;

&lt;p&gt;Most AI development tools excel at the initial build but provide almost no visibility into what happens when things go wrong. You might get an error message if you're lucky, but usually no way to understand why it happened or how to fix it without starting over.&lt;/p&gt;

&lt;p&gt;Common debugging dead ends include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generic error messages that don't point to the actual problem&lt;/li&gt;
&lt;li&gt;No access to server logs when backend issues occur&lt;/li&gt;
&lt;li&gt;Limited visibility into database operations when data relationships break&lt;/li&gt;
&lt;li&gt;No way to inspect the actual code execution when logic fails&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This creates the infamous "rebuild from scratch" cycle that destroys so many promising AI-generated projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging Strategy 1: Error Message Archaeology
&lt;/h2&gt;

&lt;p&gt;Even when error messages are cryptic, they often contain clues if you know how to read them. Here's how to extract useful information from unhelpful error messages.&lt;/p&gt;

&lt;h3&gt;
  
  
  What to look for:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;HTTP status codes (even if hidden in developer tools):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;400 errors = bad request (usually form data issues)&lt;/li&gt;
&lt;li&gt;401/403 errors = authentication/permission problems&lt;/li&gt;
&lt;li&gt;404 errors = missing resources or broken URLs&lt;/li&gt;
&lt;li&gt;500 errors = server-side problems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Other clues:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Specific field names mentioned in error messages&lt;/li&gt;
&lt;li&gt;Database-related keywords like "foreign key," "constraint," "duplicate," or "null"&lt;/li&gt;
&lt;li&gt;API endpoint references that might indicate integration issues&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to dig deeper:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open browser developer tools (F12 in most browsers)&lt;/li&gt;
&lt;li&gt;Check the Console tab for JavaScript errors&lt;/li&gt;
&lt;li&gt;Look at the Network tab to see which requests are failing&lt;/li&gt;
&lt;li&gt;Examine the Response tab for server error details&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Even if you don't understand all the technical details, documenting these specifics helps when asking the LLM for help or trying to fix issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging Strategy 2: Data Detective Work
&lt;/h2&gt;

&lt;p&gt;Many AI app failures stem from data problems that aren't immediately obvious. Learning to investigate your data systematically can save hours of frustration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check data integrity:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Export your data (if possible) and examine it in a spreadsheet (hack: Ask the AI tool to create you a button that allows you to export all the data)&lt;/li&gt;
&lt;li&gt;Look for patterns in records that cause errors vs. those that work&lt;/li&gt;
&lt;li&gt;Check for empty fields in required columns&lt;/li&gt;
&lt;li&gt;Identify special characters that might be breaking parsing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Test data relationships:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create a simple test case with minimal data&lt;/li&gt;
&lt;li&gt;Add complexity gradually until you find the breaking point&lt;/li&gt;
&lt;li&gt;Document the exact data combination that causes the failure&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Common data issues in AI apps:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Missing foreign key relationships (child records pointing to non-existent parents)&lt;/li&gt;
&lt;li&gt;Circular dependencies (A references B, B references C, C references A)&lt;/li&gt;
&lt;li&gt;Data type mismatches (numbers stored as text, dates in wrong formats)&lt;/li&gt;
&lt;li&gt;Encoding problems (special characters not handled properly)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Debugging Strategy 3: The Isolation Method
&lt;/h2&gt;

&lt;p&gt;When everything seems to be broken, isolating variables helps you identify the root cause systematically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Process:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Start with the simplest possible version of the failing feature&lt;/li&gt;
&lt;li&gt;Add one complexity at a time until you reproduce the error&lt;/li&gt;
&lt;li&gt;Document each step that works and the step that breaks things&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Example: Login system debugging
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Test with a brand new user account (eliminates data corruption)&lt;/li&gt;
&lt;li&gt;Test with the simplest possible login credentials (eliminates special character issues)&lt;/li&gt;
&lt;li&gt;Test immediately after account creation (eliminates timing issues)&lt;/li&gt;
&lt;li&gt;Add complexity (special characters, longer passwords, etc.) one element at a time&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This methodical approach helps you pinpoint whether the issue is with the authentication logic, data validation, session management, or something else entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging Strategy 4: Replication and Documentation
&lt;/h2&gt;

&lt;p&gt;One of the most valuable debugging skills is creating reliable reproduction steps. This not only helps you understand the problem but also makes it easier to verify when it's fixed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a debugging notebook with:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Exact steps to reproduce the issue&lt;/li&gt;
&lt;li&gt;Expected vs. actual behavior&lt;/li&gt;
&lt;li&gt;Browser and device information&lt;/li&gt;
&lt;li&gt;Screenshots or screen recordings of the problem&lt;/li&gt;
&lt;li&gt;Any error messages (including those in developer tools)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Make the problem consistent:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Can you make the error happen every time?&lt;/li&gt;
&lt;li&gt;Does it happen with specific data, or randomly?&lt;/li&gt;
&lt;li&gt;Does it affect all users or just certain ones?&lt;/li&gt;
&lt;li&gt;Is it browser-specific or device-specific?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Consistent reproduction is often 80% of the debugging battle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging Strategy 5: Working Backwards from Success
&lt;/h2&gt;

&lt;p&gt;Sometimes it's easier to understand what's broken by examining what's working correctly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Process:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Find a similar feature that works in your application&lt;/li&gt;
&lt;li&gt;Compare the working vs. broken implementations&lt;/li&gt;
&lt;li&gt;Look for differences in data structure, user flow, or complexity&lt;/li&gt;
&lt;li&gt;Apply the working pattern to the broken feature&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This approach is particularly useful with AI-generated code because similar features often use similar patterns. If user registration works but password reset doesn't, comparing the two flows can reveal the specific difference causing the problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  When DIY Debugging Isn't Enough
&lt;/h2&gt;

&lt;p&gt;These manual debugging strategies will solve many issues, but they have limitations. As your application grows more complex, you'll need better tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Signs you need better debugging tools:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You're spending more time debugging than building features&lt;/li&gt;
&lt;li&gt;The same types of errors keep recurring&lt;/li&gt;
&lt;li&gt;You can't see what's happening in your database&lt;/li&gt;
&lt;li&gt;Error messages don't provide actionable information&lt;/li&gt;
&lt;li&gt;You're rebuilding features instead of fixing them&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What to look for in AI development platforms:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Real-time logs that show you exactly what's happening&lt;/li&gt;
&lt;li&gt;Database inspection tools for understanding data relationships&lt;/li&gt;
&lt;li&gt;Interactive breakpoints that let you pause execution and examine variables&lt;/li&gt;
&lt;li&gt;Error tracking that categorizes and prioritizes issues&lt;/li&gt;
&lt;li&gt;Version control so you can revert problematic changes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Building Applications That Debug Themselves
&lt;/h2&gt;

&lt;p&gt;The best debugging strategy is building applications that provide visibility from the start. This means choosing platforms that treat debugging as a core feature, not an afterthought.&lt;/p&gt;

&lt;p&gt;At &lt;a href="https://pythagora.ai" rel="noopener noreferrer"&gt;Pythagora&lt;/a&gt;, we've seen too many promising AI-generated projects die because users couldn't understand what was going wrong when issues inevitably arose. That's why we built debugging capabilities directly into the development process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visual breakpoints show you exactly where your application is failing and why&lt;/li&gt;
&lt;li&gt;Comprehensive logging turns cryptic errors into actionable information&lt;/li&gt;
&lt;li&gt;Step-by-step debugging walks you through issues without requiring deep technical knowledge&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal isn't to prevent all bugs - that's impossible. The goal is to make bugs understandable and fixable when they occur.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging is a Skill, Not Magic
&lt;/h2&gt;

&lt;p&gt;Good debugging comes down to systematic thinking, careful observation, and persistence - not deep technical knowledge.&lt;/p&gt;

&lt;p&gt;The techniques in this guide will help you solve many issues on your own. But the bigger breakthrough comes when you choose development tools that make debugging collaborative rather than a solo struggle against cryptic error messages.&lt;/p&gt;

&lt;p&gt;When you can see what's happening in your application, understand why errors occur, and fix specific issues without starting over, debugging transforms from a frustrating roadblock into a manageable part of the development process.&lt;/p&gt;

&lt;p&gt;Your AI-generated application will have bugs. The question is whether you have the tools and strategies to overcome them when they appear.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This article is part of our series on building applications that make it to production. &lt;a href="https://pythagora.ai" rel="noopener noreferrer"&gt;Pythagora&lt;/a&gt; integrates powerful debugging tools directly into the AI development workflow, making it easier to identify and fix issues without starting over. Pythagora 2.0 launches in June 2025, bringing even more advanced debugging capabilities.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>programming</category>
      <category>career</category>
    </item>
    <item>
      <title>Will Your AI Generated App Break in Production? 3 Ways to Test It</title>
      <dc:creator>Ben</dc:creator>
      <pubDate>Tue, 20 May 2025 15:14:14 +0000</pubDate>
      <link>https://forem.com/benwilkins/will-your-ai-generated-app-break-in-production-3-ways-to-test-it-4il6</link>
      <guid>https://forem.com/benwilkins/will-your-ai-generated-app-break-in-production-3-ways-to-test-it-4il6</guid>
      <description>&lt;p&gt;If you've built an application using AI tools, you've probably experienced that initial rush of seeing your idea transform into working software. The UI looks slick, basic features respond as expected, and the demo impresses everyone in the room and then.. problems start.&lt;/p&gt;

&lt;p&gt;Real users interact with your app. Actual data flows through your system. Multiple people try to use it simultaneously.&lt;/p&gt;

&lt;p&gt;And that's when most AI-generated applications break down. What worked in a controlled demo often fails when faced with real-world conditions.&lt;/p&gt;

&lt;p&gt;You can spot many of these problems before they derail your project. Here are three testing strategies that don't require a CS degree but can save your project from the all-too-common fate of never making it to launch.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Break Your Data Relationships on Purpose
&lt;/h2&gt;

&lt;p&gt;One of the most common failure points in AI-generated applications occurs when different types of data need to interact. These relationships often work perfectly in demos but break down under real-world conditions.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to test it:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Create complex, interconnected data:&lt;/strong&gt; Rather than testing with simple, isolated information, create data that connects across different parts of your application.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Example:&lt;/em&gt; If you're building a project management tool, create a project with multiple tasks, assign those tasks to different team members, and add comments from various users to each task.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deliberately push edge cases:&lt;/strong&gt; Test what happens when your data hits unusual but realistic scenarios. Try these specific tests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Delete a parent item that has child items attached&lt;/li&gt;
&lt;li&gt;Create circular references (A depends on B, which depends on C, which depends on A)&lt;/li&gt;
&lt;li&gt;Create duplicate entries with slightly different formats (e.g., "John Doe" and "John Doe" with two spaces)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Check for cascading effects:&lt;/strong&gt; When you make changes in one place, verify that related information updates correctly elsewhere.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Example:&lt;/em&gt; If you change a user's name, does it update correctly everywhere that user is referenced? Or does it break in certain views?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to look for:&lt;/strong&gt; Error messages, missing data, or inconsistent information across different views. When your application mishandles these scenarios during testing, it will definitely break when real users are involved.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Simulate Concurrent User Activity
&lt;/h2&gt;

&lt;p&gt;AI app builders typically test your application with a single user in mind. But real applications often have multiple people using them simultaneously, which can reveal critical issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to test it:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Use multiple browsers or incognito windows:&lt;/strong&gt; Open your application in several different browser sessions, each logged in as a different user.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Make simultaneous changes to the same data:&lt;/strong&gt; Have each "user" try to edit the same information at roughly the same time.&lt;/p&gt;

&lt;p&gt;Try these specific scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Two users updating the same record simultaneously&lt;/li&gt;
&lt;li&gt;One user deleting a record while another is editing it&lt;/li&gt;
&lt;li&gt;Multiple users creating items with identical names or attributes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Rapid-fire actions:&lt;/strong&gt; Perform actions quickly without waiting for each operation to complete.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Example:&lt;/em&gt; Rapidly click the "save" button multiple times, or submit several forms in quick succession without waiting for confirmation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to look for:&lt;/strong&gt; Data inconsistencies, error messages, or situations where one user's changes override another's without warning. Pay special attention to whether your application properly locks resources during updates or provides appropriate warnings about conflicts.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Test with Realistic Data Volumes
&lt;/h2&gt;

&lt;p&gt;AI-generated apps often work beautifully with the handful of sample/mocked items you create during development. But what happens when you add hundreds of records or upload larger files?&lt;/p&gt;

&lt;h3&gt;
  
  
  How to test it:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Bulk import realistic data:&lt;/strong&gt; Rather than manually creating a few test records, import a substantial dataset that resembles what you'll actually use.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Practical approach:&lt;/em&gt; Export data from your current systems (spreadsheets, existing tools) and import it into your new application. Even a CSV with 100-200 rows will reveal issues that wouldn't appear with just 5-10 test items.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test search and filtering functionality:&lt;/strong&gt; Once you have a larger dataset, verify that finding information works as expected.&lt;/p&gt;

&lt;p&gt;Try these specific tests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search for items with special characters or unusual formatting&lt;/li&gt;
&lt;li&gt;Apply complex filters that should return only a small subset of data&lt;/li&gt;
&lt;li&gt;Sort large lists and check if the ordering is correct&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Check loading times and responsiveness:&lt;/strong&gt; Monitor how the application performs as data volumes increase.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Example:&lt;/em&gt; Time how long it takes to load a list with 10 items versus 100 items. If the difference is dramatic, you may have scaling issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to look for:&lt;/strong&gt; Slow performance, timeout errors, or features that simply stop working with larger datasets. These issues indicate that your application won't scale well as your usage grows.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Means For Your Project
&lt;/h2&gt;

&lt;p&gt;So your tests uncovered problems. Good. That's exactly what needed to happen before real users found them instead.&lt;/p&gt;

&lt;p&gt;Most AI platforms are built for that first "wow moment," not for what comes next. The tools that actually help you ship are the ones that acknowledge bugs happen and give you ways to fix them.&lt;/p&gt;

&lt;p&gt;When shopping for AI development platforms, dig beyond the impressive demos. Ask pointed questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can I see logs when something breaks?&lt;/li&gt;
&lt;li&gt;How do I inspect the database when relationships malfunction?&lt;/li&gt;
&lt;li&gt;What debugging tools are available?&lt;/li&gt;
&lt;li&gt;Can I fix one component without rebuilding the entire app?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The platforms that skip these questions are the same ones whose apps rarely make it past the demo stage.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Pythagora Approaches These Challenges
&lt;/h2&gt;

&lt;p&gt;At &lt;a href="https://pythagora.ai" rel="noopener noreferrer"&gt;Pythagora&lt;/a&gt;, we've built our platform specifically to address these transition points where other AI tools break down. Instead of just generating code and leaving you stranded when issues arise, &lt;a href="https://pythagora.ai" rel="noopener noreferrer"&gt;Pythagora&lt;/a&gt; provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real debugging tools with breakpoints and logs that show you exactly where things are breaking&lt;/li&gt;
&lt;li&gt;Database inspection tools so you can see how your data relationships are actually functioning&lt;/li&gt;
&lt;li&gt;Step-by-step guidance through common error patterns, explained in terms that make sense whether you code or not&lt;/li&gt;
&lt;li&gt;The ability to make targeted fixes without starting over from scratch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We don't pretend software development is a perfectly straight line from idea to production. Instead, we give you the tools to navigate the inevitable twists and turns, helping you identify issues early and resolve them quickly.&lt;/p&gt;

&lt;p&gt;In software development, you'll encounter problems. What matters is having the right tools to solve them when you do.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This article is the first in our series on building applications that make it to production. &lt;a href="https://pythagora.ai" rel="noopener noreferrer"&gt;Pythagora&lt;/a&gt; 2.0 launches in June 2025, bringing even more powerful tools for the complete development journey.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>pythagora</category>
      <category>vibecoding</category>
    </item>
  </channel>
</rss>
