<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>chs.us — Carl Sampson</title><link>https://chs.us/</link><description>Application security engineer writing about web vulnerabilities, Python security tooling, and vulnerability research.</description><image><title>chs.us</title><url>https://chs.us/og-image.png</url><link>https://chs.us/</link></image><language>en-us</language><managingEditor>carl.sampson@gmail.com (Carl Sampson)</managingEditor><webMaster>carl.sampson@gmail.com (Carl Sampson)</webMaster><lastBuildDate>Wed, 06 May 2026 10:00:00 +0000</lastBuildDate><atom:link href="https://chs.us/series/owasp-top-10-series/index.xml" rel="self" type="application/rss+xml"/><item><title>OWASP A01: Broken Access Control Prevention Guide</title><link>https://chs.us/2026/06/owasp-a01-broken-access-control-prevention/</link><pubDate>Wed, 06 May 2026 10:00:00 +0000</pubDate><author>carl.sampson@gmail.com (Carl Sampson)</author><guid>https://chs.us/2026/06/owasp-a01-broken-access-control-prevention/</guid><description>Broken access control tops the OWASP 2025 list. IDOR, privilege escalation, and the authorization checks that actually hold, with real code.</description><category>Security</category><category>Owasp</category><category>Access-Control</category><category>Idor</category><category>Ssrf</category><category>Web-Security</category><category>Application-Security</category><category>Authorization</category><content:encoded><![CDATA[<p>I&rsquo;ve been hunting access control bugs for over a decade, and let me tell you - they&rsquo;re everywhere. When OWASP moved broken access control to #1 in 2025 and merged <a href="/guides/ssrf/">SSRF</a> into this category, I wasn&rsquo;t surprised. I was relieved that the security community finally caught up to what I&rsquo;ve been seeing in the wild.</p>
<p>94% of applications tested have broken access control issues. That&rsquo;s not a typo - it&rsquo;s a security apocalypse hiding in plain sight.</p>
<h2 id="quick-answer-what-is-broken-access-control">Quick Answer: What is Broken Access Control?</h2>
<p><strong>Broken Access Control occurs when applications fail to properly restrict what authenticated users can access, resulting in:</strong></p>
<ul>
<li><strong>Unauthorized data access</strong> - viewing other users&rsquo; sensitive information</li>
<li><strong>Privilege escalation</strong> - regular users gaining admin capabilities</li>
<li><strong>Direct object manipulation</strong> - changing IDs to access forbidden resources</li>
<li><strong>Server-side request forgery</strong> - making unauthorized requests from the server</li>
<li><strong>Function-level bypasses</strong> - accessing admin functions without proper authorization</li>
</ul>
<p><strong>Impact:</strong> Complete data breaches, account takeovers, and system compromise affecting millions of users.</p>
<div class="owasp-series-navigation">
  <div class="series-header">
    <h3>🛡️ OWASP Top 10 2025 Series</h3>
    <p>Complete guides to modern web application security vulnerabilities</p>
  </div>

  <div class="series-content">
    <div class="pillar-page">
      <h4>📚 Complete Guide</h4>
      <a href="/2026/05/owasp-top-10-2025-complete-developer-security-guide/">
        <strong>OWASP Top 10 2025: Complete Developer Guide</strong><br>
        <span class="description">Comprehensive overview of all vulnerabilities, rankings, and modern threat landscape</span>
      </a>
    </div>

    <div class="vulnerability-guides">
      <h4>🎯 Individual Vulnerability Guides</h4>
      <div class="guide-grid">
        <a href="/2026/06/owasp-a01-broken-access-control-prevention/" class="current">
          <strong>A01:</strong> Broken Access Control
          <span class="status">Includes SSRF</span>
        </a>
        <a href="/2026/05/owasp-a02-security-misconfiguration-prevention/">
          <strong>A02:</strong> Security Misconfiguration
          <span class="status">Jumped to #2</span>
        </a>
        <a href="/2026/06/owasp-a03-software-supply-chain-failures-prevention/">
          <strong>A03:</strong> Software Supply Chain Failures
          <span class="status">New in 2025</span>
        </a>
        <a href="/2026/06/owasp-a04-cryptographic-failures-prevention/">
          <strong>A04:</strong> Cryptographic Failures
        </a>
        <a href="/2026/06/owasp-a05-injection-prevention/">
          <strong>A05:</strong> Injection
        </a>
        <div class="coming-soon">
          <strong>A06:</strong> Vulnerable Components <span class="status-coming">Coming Next</span>
        </div>
        <div class="coming-soon">
          <strong>A07:</strong> Authentication Failures <span class="status-coming">Coming Soon</span>
        </div>
        <div class="coming-soon">
          <strong>A08:</strong> Integrity Failures <span class="status-coming">Coming Soon</span>
        </div>
        <div class="coming-soon">
          <strong>A09:</strong> Logging & Monitoring <span class="status-coming">Coming Soon</span>
        </div>
        <div class="coming-soon">
          <strong>A10:</strong> Exception Handling <span class="status-coming">Coming Soon</span>
        </div>
      </div>
    </div>
  </div>

  <div class="series-footer">
    <p><strong>👨‍💻 Written by Carl Sampson</strong> • Security researcher with 15+ years experience • OWASP Indianapolis Chapter founder</p>
  </div>
</div>

<style>
.owasp-series-navigation {
  background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
  border: 1px solid #cbd5e0;
  border-radius: 8px;
  padding: 24px;
  margin: 32px 0;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}

.series-header h3 {
  color: #1a202c;
  margin: 0 0 8px 0;
  font-size: 1.25rem;
  font-weight: 700;
}

.series-header p {
  color: #4a5568;
  margin: 0 0 24px 0;
  font-style: italic;
}

.pillar-page {
  margin-bottom: 24px;
  padding-bottom: 20px;
  border-bottom: 2px solid #e2e8f0;
}

.pillar-page h4, .vulnerability-guides h4 {
  color: #2d3748;
  margin: 0 0 12px 0;
  font-size: 1.1rem;
  font-weight: 600;
}

.pillar-page a {
  display: block;
  padding: 16px;
  background: #ffffff;
  border: 1px solid #e2e8f0;
  border-radius: 6px;
  text-decoration: none;
  color: #2d3748;
  transition: all 0.2s ease;
}

.pillar-page a:hover, .pillar-page a.current {
  border-color: #3182ce;
  box-shadow: 0 2px 4px rgba(49, 130, 206, 0.1);
}

.pillar-page a.current {
  background: #ebf8ff;
  border-color: #3182ce;
}

.pillar-page .description {
  color: #718096;
  font-size: 0.9rem;
  margin-top: 4px;
}

.guide-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 12px;
}

.guide-grid a {
  display: block;
  padding: 12px 16px;
  background: #ffffff;
  border: 1px solid #e2e8f0;
  border-radius: 6px;
  text-decoration: none;
  color: #2d3748;
  transition: all 0.2s ease;
  position: relative;
}

.guide-grid a:hover, .guide-grid a.current {
  border-color: #3182ce;
  transform: translateY(-1px);
  box-shadow: 0 2px 4px rgba(49, 130, 206, 0.1);
}

.guide-grid a.current {
  background: #ebf8ff;
  border-color: #3182ce;
}

.guide-grid strong {
  color: #1a202c;
  font-weight: 600;
}

.coming-soon {
  display: block;
  padding: 12px 16px;
  background: #f7fafc;
  border: 1px solid #e2e8f0;
  border-radius: 6px;
  color: #718096;
  position: relative;
  opacity: 0.7;
}

.coming-soon strong {
  color: #4a5568;
  font-weight: 600;
}

.status {
  display: inline-block;
  background: #fed7d7;
  color: #9b2c2c;
  font-size: 0.75rem;
  padding: 2px 6px;
  border-radius: 4px;
  margin-left: 8px;
  font-weight: 500;
}

.status-coming {
  display: inline-block;
  background: #edf2f7;
  color: #4a5568;
  font-size: 0.75rem;
  padding: 2px 6px;
  border-radius: 4px;
  margin-left: 8px;
  font-weight: 500;
}

.status:contains("New") {
  background: #c6f6d5;
  color: #276749;
}

.status:contains("Jumped") {
  background: #fef5e7;
  color: #975a16;
}

.series-footer {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid #e2e8f0;
}

.series-footer p {
  color: #718096;
  font-size: 0.9rem;
  margin: 0;
  text-align: center;
}

 
@media (prefers-color-scheme: dark) {
  .owasp-series-navigation {
    background: linear-gradient(135deg, #1a202c 0%, #2d3748 100%);
    border-color: #4a5568;
  }

  .series-header h3, .pillar-page h4, .vulnerability-guides h4 {
    color: #f7fafc;
  }

  .series-header p, .pillar-page .description, .series-footer p {
    color: #a0aec0;
  }

  .pillar-page a, .guide-grid a {
    background: #2d3748;
    border-color: #4a5568;
    color: #f7fafc;
  }

  .pillar-page a:hover, .guide-grid a:hover,
  .pillar-page a.current, .guide-grid a.current {
    background: #2c5282;
    border-color: #3182ce;
  }

  .guide-grid strong {
    color: #f7fafc;
  }

  .coming-soon {
    background: #2d3748;
    border-color: #4a5568;
    color: #a0aec0;
  }

  .coming-soon strong {
    color: #cbd5e0;
  }

  .status-coming {
    background: #4a5568;
    color: #a0aec0;
  }
}
</style>
<hr>
<h2 id="why-broken-access-control-became-1">Why Broken Access Control Became #1</h2>
<p>When I first started doing security reviews, access control bugs were treated as &ldquo;medium severity&rdquo; issues. Fast forward to 2026, and they&rsquo;re the #1 threat. Here&rsquo;s why:</p>
<h3 id="the-perfect-storm"><strong>The Perfect Storm</strong></h3>
<ul>
<li><strong>Modern architectures</strong> with microservices make consistent authorization hard</li>
<li><strong>API-first development</strong> exposes more endpoints with inconsistent protection</li>
<li><strong>Frontend assumptions</strong> that security happens in the browser (spoiler: it doesn&rsquo;t)</li>
<li><strong>DevOps pressure</strong> leading to &ldquo;we&rsquo;ll add authorization later&rdquo; (spoiler: they never do)</li>
</ul>
<p>The shift to distributed systems means developers are building 20+ services that all need to implement authorization correctly. They don&rsquo;t.</p>
<hr>
<h2 id="how-ssrf-fits-into-access-control-2025-update">How SSRF Fits Into Access Control (2025 Update)</h2>
<p>OWASP 2025 consolidated Server-Side Request Forgery (SSRF) into A01 because that&rsquo;s how attacks actually work. I rarely see isolated SSRF - it&rsquo;s always part of an access control bypass chain.</p>
<h3 id="real-attack-chain-i"><strong>Real Attack Chain I&rsquo;ve Seen:</strong></h3>
<ol>
<li><strong>SSRF</strong> - Attacker tricks app into making internal requests</li>
<li><strong>Network Bypass</strong> - Accesses internal services via SSRF</li>
<li><strong>Privilege Escalation</strong> - Uses internal endpoints to elevate permissions</li>
<li><strong>Data Exfiltration</strong> - Downloads sensitive data using newfound access</li>
</ol>
<p>SSRF isn&rsquo;t just about reading files - it&rsquo;s about circumventing the entire access control model by attacking from a &ldquo;trusted&rdquo; internal position.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Vulnerable: User can specify any URL</span>
</span></span><span class="line"><span class="cl"><span class="nd">@app.route</span><span class="p">(</span><span class="s1">&#39;/fetch-image&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">fetch_image</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="n">url</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;url&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># This is broken access control via SSRF</span>
</span></span><span class="line"><span class="cl">    <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>  
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">response</span><span class="o">.</span><span class="n">content</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Attack: http://localhost:8080/admin/users</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Result: Attacker accesses admin endpoint via SSRF</span>
</span></span></code></pre></div><hr>
<h2 id="the-access-control-disaster-categories">The Access Control Disaster Categories</h2>
<h3 id="1-insecure-direct-object-references-idor"><strong>1. Insecure Direct Object References (IDOR)</strong></h3>
<p>This is the bread and butter of access control bugs. User changes an ID parameter and suddenly they&rsquo;re looking at someone else&rsquo;s data.</p>
<p><strong>What I See Constantly:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="c1">// Broken: No authorization check
</span></span></span><span class="line"><span class="cl"><span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/api/documents/:id&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">doc</span> <span class="o">=</span> <span class="nx">database</span><span class="p">.</span><span class="nx">getDocument</span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">id</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nx">res</span><span class="p">.</span><span class="nx">json</span><span class="p">(</span><span class="nx">doc</span><span class="p">);</span> <span class="c1">// Any authenticated user can access any document
</span></span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Secure: Proper authorization
</span></span></span><span class="line"><span class="cl"><span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/api/documents/:id&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">doc</span> <span class="o">=</span> <span class="nx">database</span><span class="p">.</span><span class="nx">getDocument</span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">id</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">doc</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="nx">res</span><span class="p">.</span><span class="nx">status</span><span class="p">(</span><span class="mi">404</span><span class="p">).</span><span class="nx">json</span><span class="p">({</span><span class="nx">error</span><span class="o">:</span> <span class="s1">&#39;Not found&#39;</span><span class="p">});</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1">// Check if user owns this document or has permission
</span></span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nx">doc</span><span class="p">.</span><span class="nx">owner_id</span> <span class="o">!==</span> <span class="nx">req</span><span class="p">.</span><span class="nx">user</span><span class="p">.</span><span class="nx">id</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nx">req</span><span class="p">.</span><span class="nx">user</span><span class="p">.</span><span class="nx">hasRole</span><span class="p">(</span><span class="s1">&#39;admin&#39;</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="nx">res</span><span class="p">.</span><span class="nx">status</span><span class="p">(</span><span class="mi">403</span><span class="p">).</span><span class="nx">json</span><span class="p">({</span><span class="nx">error</span><span class="o">:</span> <span class="s1">&#39;Access denied&#39;</span><span class="p">});</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="nx">res</span><span class="p">.</span><span class="nx">json</span><span class="p">(</span><span class="nx">doc</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p><strong>Real Example from My Reviews:</strong><br>
Found an app where changing <code>/api/invoices/123</code> to <code>/api/invoices/124</code> gave access to other companies&rsquo; financial data. The developers assumed the frontend would &ldquo;only show your own invoices.&rdquo; The API had zero authorization checks.</p>
<h3 id="2-privilege-escalation"><strong>2. Privilege Escalation</strong></h3>
<p>Regular users gaining admin access by manipulating requests or exploiting flawed role checks.</p>
<p><strong>Horizontal vs Vertical Escalation:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Horizontal: Access other users&#39; data at same privilege level</span>
</span></span><span class="line"><span class="cl"><span class="c1"># URL: /user/profile/456 (should only access your own profile)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Vertical: Gain higher privileges</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Manipulating role parameter in requests</span>
</span></span><span class="line"><span class="cl"><span class="c1"># POST /api/users/update</span>
</span></span><span class="line"><span class="cl"><span class="c1"># {&#34;user_id&#34;: 123, &#34;role&#34;: &#34;admin&#34;}  # Should not be allowed</span>
</span></span></code></pre></div><p><strong>Framework-Specific Issues I&rsquo;ve Found:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-django" data-lang="django"><span class="line"><span class="cl"><span class="x"># Django - Broken
</span></span></span><span class="line"><span class="cl"><span class="x">def user_profile(request, user_id):
</span></span></span><span class="line"><span class="cl"><span class="x">    user = User.objects.get(id=user_id)  # No permission check
</span></span></span><span class="line"><span class="cl"><span class="x">    return render(request, &#39;profile.html&#39;, {&#39;user&#39;: user})
</span></span></span><span class="line"><span class="cl"><span class="x">
</span></span></span><span class="line"><span class="cl"><span class="x"># Django - Secure
</span></span></span><span class="line"><span class="cl"><span class="x">def user_profile(request, user_id):
</span></span></span><span class="line"><span class="cl"><span class="x">    user = get_object_or_404(User, id=user_id)
</span></span></span><span class="line"><span class="cl"><span class="x">    
</span></span></span><span class="line"><span class="cl"><span class="x">    # Check ownership or admin permission
</span></span></span><span class="line"><span class="cl"><span class="x">    if user != request.user and not request.user.is_staff:
</span></span></span><span class="line"><span class="cl"><span class="x">        raise PermissionDenied
</span></span></span><span class="line"><span class="cl"><span class="x">        
</span></span></span><span class="line"><span class="cl"><span class="x">    return render(request, &#39;profile.html&#39;, {&#39;user&#39;: user})
</span></span></span></code></pre></div><h3 id="3-missing-function-level-access-control"><strong>3. Missing Function-Level Access Control</strong></h3>
<p>Admin functions that are &ldquo;hidden&rdquo; in the frontend but completely unprotected on the backend.</p>
<p><strong>Classic Example:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="c1">// Frontend shows admin menu only to admins
</span></span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="p">(</span><span class="nx">user</span><span class="p">.</span><span class="nx">role</span> <span class="o">===</span> <span class="s1">&#39;admin&#39;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">showAdminMenu</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// But the API endpoints have no protection
</span></span></span><span class="line"><span class="cl"><span class="nx">app</span><span class="p">.</span><span class="k">delete</span><span class="p">(</span><span class="s1">&#39;/api/users/:id&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// No role check - any authenticated user can delete anyone
</span></span></span><span class="line"><span class="cl">    <span class="nx">User</span><span class="p">.</span><span class="nx">deleteOne</span><span class="p">({</span><span class="nx">_id</span><span class="o">:</span> <span class="nx">req</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">id</span><span class="p">});</span>
</span></span><span class="line"><span class="cl">    <span class="nx">res</span><span class="p">.</span><span class="nx">status</span><span class="p">(</span><span class="mi">200</span><span class="p">).</span><span class="nx">send</span><span class="p">(</span><span class="s1">&#39;User deleted&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p><strong>What Attackers Do:</strong></p>
<ul>
<li>Inspect browser dev tools to find hidden API endpoints</li>
<li>Use tools like Burp Suite to enumerate admin functions</li>
<li>Guess common admin endpoint patterns (<code>/admin/</code>, <code>/api/admin/</code>, <code>/manage/</code>)</li>
</ul>
<h3 id="4-access-control-via-ssrf"><strong>4. Access Control Via SSRF</strong></h3>
<p>The reason OWASP consolidated these categories - SSRF is often just an access control bypass with extra steps.</p>
<p><strong>Attack Patterns I&rsquo;ve Documented:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Vulnerable webhook handler</span>
</span></span><span class="line"><span class="cl"><span class="nd">@app.route</span><span class="p">(</span><span class="s1">&#39;/webhook&#39;</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;POST&#39;</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">handle_webhook</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="n">url</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">json</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;callback_url&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">data</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;event&#39;</span><span class="p">:</span> <span class="s1">&#39;processed&#39;</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1"># Attacker sets callback_url to internal endpoint</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># http://localhost:8080/admin/delete-user?id=victim</span>
</span></span><span class="line"><span class="cl">    <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">json</span><span class="o">=</span><span class="n">data</span><span class="p">)</span>
</span></span></code></pre></div><p><strong>Cloud Metadata Attacks:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Attacker provides this URL to SSRF-vulnerable endpoint</span>
</span></span><span class="line"><span class="cl">http://169.254.169.254/latest/meta-data/iam/security-credentials/
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># App makes request from trusted internal position</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Result: Attacker gets AWS credentials with elevated permissions</span>
</span></span></code></pre></div><hr>
<h2 id="real-world-attack-scenarios">Real-World Attack Scenarios</h2>
<h3 id="scenario-1-e-commerce-account-takeover"><strong>Scenario 1: E-commerce Account Takeover</strong></h3>
<p><strong>Application:</strong> Online store with user accounts and order history</p>
<p><strong>Vulnerability:</strong> <a href="/guides/idor/">IDOR</a> in order API endpoint</p>
<p><strong>Attack:</strong></p>
<ol>
<li>User logs in and views their orders: <code>/api/orders?user_id=1234</code></li>
<li>Attacker changes parameter: <code>/api/orders?user_id=5678</code></li>
<li>Gets other user&rsquo;s order history including:
<ul>
<li>Shipping addresses</li>
<li>Payment methods (partial)</li>
<li>Order patterns and preferences</li>
</ul>
</li>
</ol>
<p><strong>Impact:</strong> Privacy violation, potential identity theft, competitive intelligence</p>
<p><strong>Code Fix:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Broken</span>
</span></span><span class="line"><span class="cl"><span class="nd">@app.route</span><span class="p">(</span><span class="s1">&#39;/api/orders&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">get_orders</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="n">user_id</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;user_id&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">orders</span> <span class="o">=</span> <span class="n">database</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;SELECT * FROM orders WHERE user_id = </span><span class="si">{</span><span class="n">user_id</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">jsonify</span><span class="p">(</span><span class="n">orders</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Fixed</span>
</span></span><span class="line"><span class="cl"><span class="nd">@app.route</span><span class="p">(</span><span class="s1">&#39;/api/orders&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nd">@login_required</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">get_orders</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># Only return current user&#39;s orders</span>
</span></span><span class="line"><span class="cl">    <span class="n">orders</span> <span class="o">=</span> <span class="n">database</span><span class="o">.</span><span class="n">query</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;SELECT * FROM orders WHERE user_id = </span><span class="si">%s</span><span class="s2">&#34;</span><span class="p">,</span> 
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="n">current_user</span><span class="o">.</span><span class="n">id</span><span class="p">,)</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">jsonify</span><span class="p">(</span><span class="n">orders</span><span class="p">)</span>
</span></span></code></pre></div><h3 id="scenario-2-healthcare-data-breach"><strong>Scenario 2: Healthcare Data Breach</strong></h3>
<p><strong>Application:</strong> Patient portal for medical records</p>
<p><strong>Vulnerability:</strong> Missing access control on file download endpoint</p>
<p><strong>Attack:</strong></p>
<ol>
<li>Patient downloads their lab result: <code>/download/lab-result/patient_123_lab_456.pdf</code></li>
<li>Attacker enumerates: <code>/download/lab-result/patient_124_lab_457.pdf</code></li>
<li>Downloads thousands of medical records by incrementing IDs</li>
</ol>
<p><strong>Impact:</strong> HIPAA violation, massive privacy breach, potential blackmail</p>
<p><strong>Prevention:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="c1">// Secure file download with proper authorization</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nd">@GetMapping</span><span class="p">(</span><span class="s">&#34;/download/lab-result/{fileName}&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="n">ResponseEntity</span><span class="o">&lt;</span><span class="n">Resource</span><span class="o">&gt;</span><span class="w"> </span><span class="nf">downloadFile</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nd">@PathVariable</span><span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="n">fileName</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Authentication</span><span class="w"> </span><span class="n">auth</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Extract patient ID from filename</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">String</span><span class="w"> </span><span class="n">patientId</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">extractPatientIdFromFilename</span><span class="p">(</span><span class="n">fileName</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Check if current user can access this patient&#39;s data</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">authService</span><span class="p">.</span><span class="na">canAccessPatientData</span><span class="p">(</span><span class="n">auth</span><span class="p">.</span><span class="na">getName</span><span class="p">(),</span><span class="w"> </span><span class="n">patientId</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">throw</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">AccessDeniedException</span><span class="p">(</span><span class="s">&#34;Cannot access patient data&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Return file only after authorization check</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Resource</span><span class="w"> </span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">fileService</span><span class="p">.</span><span class="na">loadFile</span><span class="p">(</span><span class="n">fileName</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="n">ResponseEntity</span><span class="p">.</span><span class="na">ok</span><span class="p">(</span><span class="n">file</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h3 id="scenario-3-corporate-espionage-via-ssrf"><strong>Scenario 3: Corporate Espionage via SSRF</strong></h3>
<p><strong>Application:</strong> Document management system with URL preview feature</p>
<p><strong>Vulnerability:</strong> SSRF in document preview function</p>
<p><strong>Attack:</strong></p>
<ol>
<li>App provides URL preview: <code>/preview?url=https://example.com/doc.pdf</code></li>
<li>Attacker submits: <code>/preview?url=http://internal-wiki.company.com/secrets</code></li>
<li>App fetches internal documentation from trusted position</li>
<li>Attacker receives sensitive company information</li>
</ol>
<p><strong>Impact:</strong> Corporate secrets exposed, competitive disadvantage, potential SEC violations</p>
<p><strong>Mitigation:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">ipaddress</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">urllib.parse</span> <span class="kn">import</span> <span class="n">urlparse</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">is_safe_url</span><span class="p">(</span><span class="n">url</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Validate URL to prevent SSRF&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">parsed</span> <span class="o">=</span> <span class="n">urlparse</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># Only allow HTTPS</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">parsed</span><span class="o">.</span><span class="n">scheme</span> <span class="o">!=</span> <span class="s1">&#39;https&#39;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="kc">False</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">        <span class="c1"># Block private IP ranges</span>
</span></span><span class="line"><span class="cl">        <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">ip</span> <span class="o">=</span> <span class="n">ipaddress</span><span class="o">.</span><span class="n">ip_address</span><span class="p">(</span><span class="n">parsed</span><span class="o">.</span><span class="n">hostname</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="n">ip</span><span class="o">.</span><span class="n">is_private</span> <span class="ow">or</span> <span class="n">ip</span><span class="o">.</span><span class="n">is_loopback</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="k">return</span> <span class="kc">False</span>
</span></span><span class="line"><span class="cl">        <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">pass</span>  <span class="c1"># Hostname, not IP</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">        <span class="c1"># Allowlist domains only</span>
</span></span><span class="line"><span class="cl">        <span class="n">allowed_domains</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;trusted-partner.com&#39;</span><span class="p">,</span> <span class="s1">&#39;public-docs.example.com&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">parsed</span><span class="o">.</span><span class="n">hostname</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">allowed_domains</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="kc">False</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl">    <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="kc">False</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">@app.route</span><span class="p">(</span><span class="s1">&#39;/preview&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">preview_url</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="n">url</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;url&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="ow">not</span> <span class="n">is_safe_url</span><span class="p">(</span><span class="n">url</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">jsonify</span><span class="p">({</span><span class="s1">&#39;error&#39;</span><span class="p">:</span> <span class="s1">&#39;Invalid URL&#39;</span><span class="p">}),</span> <span class="mi">400</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">response</span><span class="o">.</span><span class="n">content</span>
</span></span></code></pre></div><hr>
<h2 id="framework-specific-prevention">Framework-Specific Prevention</h2>
<h3 id="django-security-patterns"><strong>Django Security Patterns</strong></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Use Django&#39;s built-in permission system</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">django.contrib.auth.decorators</span> <span class="kn">import</span> <span class="n">login_required</span><span class="p">,</span> <span class="n">permission_required</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">django.core.exceptions</span> <span class="kn">import</span> <span class="n">PermissionDenied</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">django.shortcuts</span> <span class="kn">import</span> <span class="n">get_object_or_404</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">@login_required</span>
</span></span><span class="line"><span class="cl"><span class="nd">@permission_required</span><span class="p">(</span><span class="s1">&#39;myapp.can_view_sensitive_data&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">sensitive_view</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">object_id</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">obj</span> <span class="o">=</span> <span class="n">get_object_or_404</span><span class="p">(</span><span class="n">MyModel</span><span class="p">,</span> <span class="n">pk</span><span class="o">=</span><span class="n">object_id</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1"># Additional ownership check</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">obj</span><span class="o">.</span><span class="n">owner</span> <span class="o">!=</span> <span class="n">request</span><span class="o">.</span><span class="n">user</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">is_staff</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">raise</span> <span class="n">PermissionDenied</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">render</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="s1">&#39;template.html&#39;</span><span class="p">,</span> <span class="p">{</span><span class="s1">&#39;object&#39;</span><span class="p">:</span> <span class="n">obj</span><span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Model-level security</span>
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Document</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">title</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">content</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">TextField</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">owner</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="n">User</span><span class="p">,</span> <span class="n">on_delete</span><span class="o">=</span><span class="n">models</span><span class="o">.</span><span class="n">CASCADE</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">user_can_access</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">owner</span> <span class="o">==</span> <span class="n">user</span> <span class="ow">or</span> <span class="n">user</span><span class="o">.</span><span class="n">has_perm</span><span class="p">(</span><span class="s1">&#39;myapp.access_all_documents&#39;</span><span class="p">)</span>
</span></span></code></pre></div><h3 id="flask-authorization-patterns"><strong>Flask Authorization Patterns</strong></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">wraps</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">abort</span><span class="p">,</span> <span class="n">g</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">requires_ownership</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Decorator to check resource ownership&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="nd">@wraps</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">decorated_function</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">resource_id</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">resource</span> <span class="o">=</span> <span class="n">Resource</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">get_or_404</span><span class="p">(</span><span class="n">resource_id</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">resource</span><span class="o">.</span><span class="n">owner_id</span> <span class="o">!=</span> <span class="n">g</span><span class="o">.</span><span class="n">current_user</span><span class="o">.</span><span class="n">id</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">abort</span><span class="p">(</span><span class="mi">403</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">f</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">decorated_function</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">@app.route</span><span class="p">(</span><span class="s1">&#39;/documents/&lt;int:id&gt;&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nd">@login_required</span>
</span></span><span class="line"><span class="cl"><span class="nd">@requires_ownership</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">view_document</span><span class="p">(</span><span class="nb">id</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">document</span> <span class="o">=</span> <span class="n">Document</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">get_or_404</span><span class="p">(</span><span class="nb">id</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s1">&#39;document.html&#39;</span><span class="p">,</span> <span class="n">document</span><span class="o">=</span><span class="n">document</span><span class="p">)</span>
</span></span></code></pre></div><h3 id="expressjs-security-middleware"><strong>Express.js Security Middleware</strong></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">authMiddleware</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// Ensure user owns resource
</span></span></span><span class="line"><span class="cl">    <span class="nx">requireOwnership</span><span class="o">:</span> <span class="p">(</span><span class="nx">resourceType</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="kr">async</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">,</span> <span class="nx">next</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="kr">const</span> <span class="nx">resourceId</span> <span class="o">=</span> <span class="nx">req</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">id</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="kr">const</span> <span class="nx">resource</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">database</span><span class="p">[</span><span class="nx">resourceType</span><span class="p">].</span><span class="nx">findById</span><span class="p">(</span><span class="nx">resourceId</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">resource</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="k">return</span> <span class="nx">res</span><span class="p">.</span><span class="nx">status</span><span class="p">(</span><span class="mi">404</span><span class="p">).</span><span class="nx">json</span><span class="p">({</span><span class="nx">error</span><span class="o">:</span> <span class="s1">&#39;Resource not found&#39;</span><span class="p">});</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="nx">resource</span><span class="p">.</span><span class="nx">userId</span> <span class="o">!==</span> <span class="nx">req</span><span class="p">.</span><span class="nx">user</span><span class="p">.</span><span class="nx">id</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nx">req</span><span class="p">.</span><span class="nx">user</span><span class="p">.</span><span class="nx">isAdmin</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="k">return</span> <span class="nx">res</span><span class="p">.</span><span class="nx">status</span><span class="p">(</span><span class="mi">403</span><span class="p">).</span><span class="nx">json</span><span class="p">({</span><span class="nx">error</span><span class="o">:</span> <span class="s1">&#39;Access denied&#39;</span><span class="p">});</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">            <span class="nx">req</span><span class="p">.</span><span class="nx">resource</span> <span class="o">=</span> <span class="nx">resource</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="nx">next</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1">// Check specific permission
</span></span></span><span class="line"><span class="cl">    <span class="nx">requirePermission</span><span class="o">:</span> <span class="p">(</span><span class="nx">permission</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">,</span> <span class="nx">next</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">req</span><span class="p">.</span><span class="nx">user</span><span class="p">.</span><span class="nx">permissions</span><span class="p">.</span><span class="nx">includes</span><span class="p">(</span><span class="nx">permission</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="k">return</span> <span class="nx">res</span><span class="p">.</span><span class="nx">status</span><span class="p">(</span><span class="mi">403</span><span class="p">).</span><span class="nx">json</span><span class="p">({</span><span class="nx">error</span><span class="o">:</span> <span class="s1">&#39;Insufficient permissions&#39;</span><span class="p">});</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="nx">next</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Usage
</span></span></span><span class="line"><span class="cl"><span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/documents/:id&#39;</span><span class="p">,</span> 
</span></span><span class="line"><span class="cl">    <span class="nx">authenticateUser</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">authMiddleware</span><span class="p">.</span><span class="nx">requireOwnership</span><span class="p">(</span><span class="s1">&#39;documents&#39;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">res</span><span class="p">.</span><span class="nx">json</span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">resource</span><span class="p">);</span> <span class="c1">// Pre-authorized in middleware
</span></span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">);</span>
</span></span></code></pre></div><h3 id="spring-boot-security-configuration"><strong>Spring Boot Security Configuration</strong></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="nd">@Configuration</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nd">@EnableGlobalMethodSecurity</span><span class="p">(</span><span class="n">prePostEnabled</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">true</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">SecurityConfig</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nd">@Bean</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">public</span><span class="w"> </span><span class="n">SecurityFilterChain</span><span class="w"> </span><span class="nf">filterChain</span><span class="p">(</span><span class="n">HttpSecurity</span><span class="w"> </span><span class="n">http</span><span class="p">)</span><span class="w"> </span><span class="kd">throws</span><span class="w"> </span><span class="n">Exception</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="n">http</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">authorizeHttpRequests</span><span class="p">(</span><span class="n">authz</span><span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="n">authz</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">.</span><span class="na">requestMatchers</span><span class="p">(</span><span class="s">&#34;/api/admin/**&#34;</span><span class="p">).</span><span class="na">hasRole</span><span class="p">(</span><span class="s">&#34;ADMIN&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">.</span><span class="na">requestMatchers</span><span class="p">(</span><span class="s">&#34;/api/user/**&#34;</span><span class="p">).</span><span class="na">hasRole</span><span class="p">(</span><span class="s">&#34;USER&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">.</span><span class="na">anyRequest</span><span class="p">().</span><span class="na">authenticated</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">sessionManagement</span><span class="p">(</span><span class="n">session</span><span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="n">session</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">.</span><span class="na">sessionCreationPolicy</span><span class="p">(</span><span class="n">SessionCreationPolicy</span><span class="p">.</span><span class="na">STATELESS</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">build</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Method-level security</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nd">@RestController</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">DocumentController</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nd">@GetMapping</span><span class="p">(</span><span class="s">&#34;/api/documents/{id}&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nd">@PreAuthorize</span><span class="p">(</span><span class="s">&#34;@documentService.canUserAccess(#id, authentication.name)&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">public</span><span class="w"> </span><span class="n">Document</span><span class="w"> </span><span class="nf">getDocument</span><span class="p">(</span><span class="nd">@PathVariable</span><span class="w"> </span><span class="n">Long</span><span class="w"> </span><span class="n">id</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="n">documentService</span><span class="p">.</span><span class="na">findById</span><span class="p">(</span><span class="n">id</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nd">@Service</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">DocumentService</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">public</span><span class="w"> </span><span class="kt">boolean</span><span class="w"> </span><span class="nf">canUserAccess</span><span class="p">(</span><span class="n">Long</span><span class="w"> </span><span class="n">documentId</span><span class="p">,</span><span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="n">username</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">Document</span><span class="w"> </span><span class="n">doc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">documentRepository</span><span class="p">.</span><span class="na">findById</span><span class="p">(</span><span class="n">documentId</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">User</span><span class="w"> </span><span class="n">user</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">userRepository</span><span class="p">.</span><span class="na">findByUsername</span><span class="p">(</span><span class="n">username</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="n">doc</span><span class="p">.</span><span class="na">getOwner</span><span class="p">().</span><span class="na">equals</span><span class="p">(</span><span class="n">user</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">user</span><span class="p">.</span><span class="na">hasRole</span><span class="p">(</span><span class="s">&#34;ADMIN&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><hr>
<h2 id="advanced-attack-techniques">Advanced Attack Techniques</h2>
<h3 id="jwt-token-manipulation"><strong>JWT Token Manipulation</strong></h3>
<blockquote>
<p>🧪 <strong>Try it:</strong> The <a href="/tools/jwt/"><strong>JWT Attack Playground</strong></a> lets you forge the exact token below — decode it, strip the signature, and watch a vulnerable verifier wave it through.</p>
</blockquote>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="c1">// Vulnerable JWT handling
</span></span></span><span class="line"><span class="cl"><span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/admin/users&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">token</span> <span class="o">=</span> <span class="nx">req</span><span class="p">.</span><span class="nx">headers</span><span class="p">.</span><span class="nx">authorization</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">)[</span><span class="mi">1</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">decoded</span> <span class="o">=</span> <span class="nx">jwt</span><span class="p">.</span><span class="nx">decode</span><span class="p">(</span><span class="nx">token</span><span class="p">);</span> <span class="c1">// No verification!
</span></span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nx">decoded</span><span class="p">.</span><span class="nx">role</span> <span class="o">===</span> <span class="s1">&#39;admin&#39;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// Attacker can craft their own JWT with admin role
</span></span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="nx">res</span><span class="p">.</span><span class="nx">json</span><span class="p">(</span><span class="nx">getAllUsers</span><span class="p">());</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="nx">res</span><span class="p">.</span><span class="nx">status</span><span class="p">(</span><span class="mi">403</span><span class="p">).</span><span class="nx">send</span><span class="p">(</span><span class="s1">&#39;Admin only&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Secure JWT handling
</span></span></span><span class="line"><span class="cl"><span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/admin/users&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">token</span> <span class="o">=</span> <span class="nx">req</span><span class="p">.</span><span class="nx">headers</span><span class="p">.</span><span class="nx">authorization</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">)[</span><span class="mi">1</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kr">const</span> <span class="nx">decoded</span> <span class="o">=</span> <span class="nx">jwt</span><span class="p">.</span><span class="nx">verify</span><span class="p">(</span><span class="nx">token</span><span class="p">,</span> <span class="nx">JWT_SECRET</span><span class="p">);</span> <span class="c1">// Proper verification
</span></span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1">// Additional role check from database
</span></span></span><span class="line"><span class="cl">        <span class="kr">const</span> <span class="nx">user</span> <span class="o">=</span> <span class="nx">database</span><span class="p">.</span><span class="nx">getUserById</span><span class="p">(</span><span class="nx">decoded</span><span class="p">.</span><span class="nx">userId</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">user</span> <span class="o">||</span> <span class="nx">user</span><span class="p">.</span><span class="nx">role</span> <span class="o">!==</span> <span class="s1">&#39;admin&#39;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="nx">res</span><span class="p">.</span><span class="nx">status</span><span class="p">(</span><span class="mi">403</span><span class="p">).</span><span class="nx">send</span><span class="p">(</span><span class="s1">&#39;Admin access required&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="nx">res</span><span class="p">.</span><span class="nx">json</span><span class="p">(</span><span class="nx">getAllUsers</span><span class="p">());</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">res</span><span class="p">.</span><span class="nx">status</span><span class="p">(</span><span class="mi">401</span><span class="p">).</span><span class="nx">send</span><span class="p">(</span><span class="s1">&#39;Invalid token&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><h3 id="graphql-authorization-bypass"><strong>GraphQL Authorization Bypass</strong></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="c1">// Vulnerable GraphQL resolver
</span></span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">resolvers</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">Query</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">user</span><span class="o">:</span> <span class="p">(</span><span class="nx">parent</span><span class="p">,</span> <span class="p">{</span> <span class="nx">id</span> <span class="p">})</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="c1">// No authorization check
</span></span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="nx">database</span><span class="p">.</span><span class="nx">getUserById</span><span class="p">(</span><span class="nx">id</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Secure GraphQL with context-based authorization
</span></span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">resolvers</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">Query</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">user</span><span class="o">:</span> <span class="p">(</span><span class="nx">parent</span><span class="p">,</span> <span class="p">{</span> <span class="nx">id</span> <span class="p">},</span> <span class="nx">context</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="c1">// Check if user can access this profile
</span></span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="nx">id</span> <span class="o">!==</span> <span class="nx">context</span><span class="p">.</span><span class="nx">currentUser</span><span class="p">.</span><span class="nx">id</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nx">context</span><span class="p">.</span><span class="nx">currentUser</span><span class="p">.</span><span class="nx">isAdmin</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="k">throw</span> <span class="k">new</span> <span class="nx">ForbiddenError</span><span class="p">(</span><span class="s1">&#39;Cannot access other user profiles&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="nx">database</span><span class="p">.</span><span class="nx">getUserById</span><span class="p">(</span><span class="nx">id</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><h3 id="api-version-bypass"><strong>API Version Bypass</strong></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="c1">// Newer API version with security
</span></span></span><span class="line"><span class="cl"><span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/api/v2/documents/:id&#39;</span><span class="p">,</span> <span class="nx">authorize</span><span class="p">,</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// Proper authorization implemented
</span></span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Older API version without security (forgotten)
</span></span></span><span class="line"><span class="cl"><span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/api/v1/documents/:id&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// No authorization - attackers use old version
</span></span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">doc</span> <span class="o">=</span> <span class="nx">database</span><span class="p">.</span><span class="nx">getDocument</span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">id</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nx">res</span><span class="p">.</span><span class="nx">json</span><span class="p">(</span><span class="nx">doc</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><hr>
<h2 id="testing-for-access-control-vulnerabilities">Testing for Access Control Vulnerabilities</h2>
<h3 id="automated-testing-tools"><strong>Automated Testing Tools</strong></h3>
<p><strong>Burp Suite Extensions:</strong></p>
<ul>
<li><strong>Autorize</strong> - Automatically tests authorization for all requests</li>
<li><strong>AuthMatrix</strong> - Matrix-based authorization testing</li>
<li><strong>AutoRepeater</strong> - Repeats requests with different user contexts</li>
</ul>
<p><strong>OWASP ZAP Scripts:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># ZAP script to test IDOR</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">scan</span><span class="p">(</span><span class="n">ps</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">src</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">uri</span> <span class="o">=</span> <span class="n">msg</span><span class="o">.</span><span class="n">getRequestHeader</span><span class="p">()</span><span class="o">.</span><span class="n">getURI</span><span class="p">()</span><span class="o">.</span><span class="n">toString</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1"># Look for ID parameters</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="s1">&#39;?id=&#39;</span> <span class="ow">in</span> <span class="n">uri</span> <span class="ow">or</span> <span class="s1">&#39;/id/&#39;</span> <span class="ow">in</span> <span class="n">uri</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># Extract ID</span>
</span></span><span class="line"><span class="cl">        <span class="n">original_id</span> <span class="o">=</span> <span class="n">extract_id_from_uri</span><span class="p">(</span><span class="n">uri</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># Try different IDs</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="n">test_id</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1000</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="n">test_id</span> <span class="o">!=</span> <span class="n">original_id</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">test_uri</span> <span class="o">=</span> <span class="n">uri</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">original_id</span><span class="p">),</span> <span class="nb">str</span><span class="p">(</span><span class="n">test_id</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">                
</span></span><span class="line"><span class="cl">                <span class="c1"># Send request with different ID</span>
</span></span><span class="line"><span class="cl">                <span class="n">test_msg</span> <span class="o">=</span> <span class="n">msg</span><span class="o">.</span><span class="n">cloneRequest</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">                <span class="n">test_msg</span><span class="o">.</span><span class="n">getRequestHeader</span><span class="p">()</span><span class="o">.</span><span class="n">setURI</span><span class="p">(</span><span class="n">test_uri</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                
</span></span><span class="line"><span class="cl">                <span class="n">response</span> <span class="o">=</span> <span class="n">sender</span><span class="o">.</span><span class="n">sendAndReceive</span><span class="p">(</span><span class="n">test_msg</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                
</span></span><span class="line"><span class="cl">                <span class="c1"># Check if unauthorized access occurred</span>
</span></span><span class="line"><span class="cl">                <span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">getResponseHeader</span><span class="p">()</span><span class="o">.</span><span class="n">getStatusCode</span><span class="p">()</span> <span class="o">==</span> <span class="mi">200</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                    <span class="n">ps</span><span class="o">.</span><span class="n">raiseAlert</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                        <span class="n">risk</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span> 
</span></span><span class="line"><span class="cl">                        <span class="n">confidence</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                        <span class="n">name</span><span class="o">=</span><span class="s2">&#34;Possible IDOR Vulnerability&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                        <span class="n">description</span><span class="o">=</span><span class="sa">f</span><span class="s2">&#34;Access granted to </span><span class="si">{</span><span class="n">test_uri</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">                    <span class="p">)</span>
</span></span></code></pre></div><h3 id="manual-testing-checklist"><strong>Manual Testing Checklist</strong></h3>
<p><strong>Identity and Authentication:</strong></p>
<ul>
<li><input disabled="" type="checkbox"> Change user ID parameters in URLs and requests</li>
<li><input disabled="" type="checkbox"> Try accessing other users&rsquo; resources by guessing IDs</li>
<li><input disabled="" type="checkbox"> Test with sequential, predictable IDs (1, 2, 3&hellip;)</li>
<li><input disabled="" type="checkbox"> Test with GUIDs/UUIDs if used</li>
</ul>
<p><strong>Session Management:</strong></p>
<ul>
<li><input disabled="" type="checkbox"> Try using another user&rsquo;s session token</li>
<li><input disabled="" type="checkbox"> Test <a href="/guides/session-management/">session fixation</a> attacks</li>
<li><input disabled="" type="checkbox"> Check for session sharing between users</li>
</ul>
<p><strong>Direct Object References:</strong></p>
<ul>
<li><input disabled="" type="checkbox"> Change file names in download URLs</li>
<li><input disabled="" type="checkbox"> Modify document/record IDs in API calls</li>
<li><input disabled="" type="checkbox"> Test both numeric and string-based identifiers</li>
</ul>
<p><strong>Function Level Access:</strong></p>
<ul>
<li><input disabled="" type="checkbox"> Access admin functions with regular user account</li>
<li><input disabled="" type="checkbox"> Try hidden admin URLs (common patterns)</li>
<li><input disabled="" type="checkbox"> Test API endpoints that might lack authorization</li>
</ul>
<p><strong>SSRF Testing:</strong></p>
<ul>
<li><input disabled="" type="checkbox"> Submit internal URLs to any URL input fields</li>
<li><input disabled="" type="checkbox"> Test localhost, 127.0.0.1, and internal IP ranges</li>
<li><input disabled="" type="checkbox"> Try cloud metadata endpoints (169.254.169.254)</li>
<li><input disabled="" type="checkbox"> Test file:// protocol for local file access</li>
</ul>
<p><strong>API Testing:</strong></p>
<ul>
<li><input disabled="" type="checkbox"> Test all API versions for authorization differences</li>
<li><input disabled="" type="checkbox"> Check HTTP methods (GET/POST/PUT/DELETE) for consistency</li>
<li><input disabled="" type="checkbox"> Test bulk operations for authorization bypasses</li>
</ul>
<hr>
<h2 id="building-robust-access-control">Building Robust Access Control</h2>
<h3 id="defense-in-depth-strategy"><strong>Defense in Depth Strategy</strong></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">AccessControlFramework</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">policies</span> <span class="o">=</span> <span class="n">PolicyEngine</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">audit</span> <span class="o">=</span> <span class="n">AuditLogger</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">check_access</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">resource</span><span class="p">,</span> <span class="n">action</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;&#34;&#34;Multi-layer access control check&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># Layer 1: Authentication</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="ow">not</span> <span class="n">user</span><span class="o">.</span><span class="n">is_authenticated</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">audit</span><span class="o">.</span><span class="n">log_access_denied</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">resource</span><span class="p">,</span> <span class="s2">&#34;Not authenticated&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="kc">False</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># Layer 2: Resource ownership</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">resource</span><span class="p">,</span> <span class="s1">&#39;owner&#39;</span><span class="p">)</span> <span class="ow">and</span> <span class="n">resource</span><span class="o">.</span><span class="n">owner</span> <span class="o">!=</span> <span class="n">user</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="c1"># Check if user has explicit permission</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_explicit_permission</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">resource</span><span class="p">,</span> <span class="n">action</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">                <span class="bp">self</span><span class="o">.</span><span class="n">audit</span><span class="o">.</span><span class="n">log_access_denied</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">resource</span><span class="p">,</span> <span class="s2">&#34;Not owner&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="k">return</span> <span class="kc">False</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># Layer 3: Role-based permissions</span>
</span></span><span class="line"><span class="cl">        <span class="n">required_role</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_required_role</span><span class="p">(</span><span class="n">resource</span><span class="p">,</span> <span class="n">action</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="ow">not</span> <span class="n">user</span><span class="o">.</span><span class="n">has_role</span><span class="p">(</span><span class="n">required_role</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">audit</span><span class="o">.</span><span class="n">log_access_denied</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">resource</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&#34;Missing role: </span><span class="si">{</span><span class="n">required_role</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="kc">False</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># Layer 4: Attribute-based policies</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">policies</span><span class="o">.</span><span class="n">evaluate</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">resource</span><span class="p">,</span> <span class="n">action</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">audit</span><span class="o">.</span><span class="n">log_access_denied</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">resource</span><span class="p">,</span> <span class="s2">&#34;Policy violation&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="kc">False</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># Layer 5: Rate limiting</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_rate_limited</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">action</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">audit</span><span class="o">.</span><span class="n">log_access_denied</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">resource</span><span class="p">,</span> <span class="s2">&#34;Rate limited&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="kc">False</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">audit</span><span class="o">.</span><span class="n">log_access_granted</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">resource</span><span class="p">,</span> <span class="n">action</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="kc">True</span>
</span></span></code></pre></div><h3 id="principle-of-least-privilege"><strong>Principle of Least Privilege</strong></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="c1">// Bad: Give broad permissions
</span></span></span><span class="line"><span class="cl"><span class="nx">user</span><span class="p">.</span><span class="nx">permissions</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;read_all&#39;</span><span class="p">,</span> <span class="s1">&#39;write_all&#39;</span><span class="p">,</span> <span class="s1">&#39;delete_all&#39;</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Good: Specific, granular permissions
</span></span></span><span class="line"><span class="cl"><span class="nx">user</span><span class="p">.</span><span class="nx">permissions</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;read_own_documents&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;write_own_documents&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;read_shared_documents&#39;</span>
</span></span><span class="line"><span class="cl"><span class="p">];</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Permission checking
</span></span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">canUserAccess</span><span class="p">(</span><span class="nx">user</span><span class="p">,</span> <span class="nx">resource</span><span class="p">,</span> <span class="nx">action</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">requiredPermission</span> <span class="o">=</span> <span class="sb">`</span><span class="si">${</span><span class="nx">action</span><span class="si">}</span><span class="sb">_</span><span class="si">${</span><span class="nx">resource</span><span class="p">.</span><span class="nx">type</span><span class="si">}</span><span class="sb">`</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1">// Check specific permission
</span></span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nx">user</span><span class="p">.</span><span class="nx">permissions</span><span class="p">.</span><span class="nx">includes</span><span class="p">(</span><span class="nx">requiredPermission</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1">// Check ownership-based permission
</span></span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nx">resource</span><span class="p">.</span><span class="nx">owner</span> <span class="o">===</span> <span class="nx">user</span><span class="p">.</span><span class="nx">id</span> <span class="o">&amp;&amp;</span> 
</span></span><span class="line"><span class="cl">        <span class="nx">user</span><span class="p">.</span><span class="nx">permissions</span><span class="p">.</span><span class="nx">includes</span><span class="p">(</span><span class="sb">`</span><span class="si">${</span><span class="nx">action</span><span class="si">}</span><span class="sb">_own_</span><span class="si">${</span><span class="nx">resource</span><span class="p">.</span><span class="nx">type</span><span class="si">}</span><span class="sb">`</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h3 id="secure-by-default-architecture"><strong>Secure by Default Architecture</strong></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Django model with built-in access control</span>
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">SecureModel</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Base model with automatic access control&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">owner</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="n">User</span><span class="p">,</span> <span class="n">on_delete</span><span class="o">=</span><span class="n">models</span><span class="o">.</span><span class="n">CASCADE</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">created_at</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateTimeField</span><span class="p">(</span><span class="n">auto_now_add</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">visibility</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">max_length</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">choices</span><span class="o">=</span><span class="p">[(</span><span class="s1">&#39;private&#39;</span><span class="p">,</span> <span class="s1">&#39;Private&#39;</span><span class="p">),</span> <span class="p">(</span><span class="s1">&#39;shared&#39;</span><span class="p">,</span> <span class="s1">&#39;Shared&#39;</span><span class="p">),</span> <span class="p">(</span><span class="s1">&#39;public&#39;</span><span class="p">,</span> <span class="s1">&#39;Public&#39;</span><span class="p">)],</span>
</span></span><span class="line"><span class="cl">        <span class="n">default</span><span class="o">=</span><span class="s1">&#39;private&#39;</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">abstract</span> <span class="o">=</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">user_can_read</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">owner</span> <span class="o">==</span> <span class="n">user</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">visibility</span> <span class="o">==</span> <span class="s1">&#39;public&#39;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">visibility</span> <span class="o">==</span> <span class="s1">&#39;shared&#39;</span> <span class="ow">and</span> <span class="n">user</span><span class="o">.</span><span class="n">is_authenticated</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">user</span><span class="o">.</span><span class="n">has_perm</span><span class="p">(</span><span class="s1">&#39;app.read_all_objects&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">user_can_write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">owner</span> <span class="o">==</span> <span class="n">user</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">user</span><span class="o">.</span><span class="n">has_perm</span><span class="p">(</span><span class="s1">&#39;app.write_all_objects&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Custom manager that filters by permissions</span>
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">SecureManager</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Manager</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">for_user</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">action</span><span class="o">=</span><span class="s1">&#39;read&#39;</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;&#34;&#34;Return only objects user can access&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">user</span><span class="o">.</span><span class="n">has_perm</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;app.</span><span class="si">{</span><span class="n">action</span><span class="si">}</span><span class="s1">_all_objects&#39;</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_queryset</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">action</span> <span class="o">==</span> <span class="s1">&#39;read&#39;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_queryset</span><span class="p">()</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                <span class="n">Q</span><span class="p">(</span><span class="n">owner</span><span class="o">=</span><span class="n">user</span><span class="p">)</span> <span class="o">|</span> 
</span></span><span class="line"><span class="cl">                <span class="n">Q</span><span class="p">(</span><span class="n">visibility</span><span class="o">=</span><span class="s1">&#39;public&#39;</span><span class="p">)</span> <span class="o">|</span>
</span></span><span class="line"><span class="cl">                <span class="n">Q</span><span class="p">(</span><span class="n">visibility</span><span class="o">=</span><span class="s1">&#39;shared&#39;</span><span class="p">,</span> <span class="n">owner__isnull</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_queryset</span><span class="p">()</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">owner</span><span class="o">=</span><span class="n">user</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Document</span><span class="p">(</span><span class="n">SecureModel</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">title</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">200</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">content</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">TextField</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="n">objects</span> <span class="o">=</span> <span class="n">SecureManager</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span>
</span></span></code></pre></div><hr>
<h2 id="monitoring-and-detection">Monitoring and Detection</h2>
<h3 id="access-control-logging"><strong>Access Control Logging</strong></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">logging</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">wraps</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Set up access control logger</span>
</span></span><span class="line"><span class="cl"><span class="n">access_logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s1">&#39;access_control&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">access_logger</span><span class="o">.</span><span class="n">setLevel</span><span class="p">(</span><span class="n">logging</span><span class="o">.</span><span class="n">INFO</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">handler</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">FileHandler</span><span class="p">(</span><span class="s1">&#39;access_control.log&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">formatter</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">Formatter</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;</span><span class="si">%(asctime)s</span><span class="s1"> - </span><span class="si">%(levelname)s</span><span class="s1"> - </span><span class="si">%(message)s</span><span class="s1">&#39;</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">handler</span><span class="o">.</span><span class="n">setFormatter</span><span class="p">(</span><span class="n">formatter</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">access_logger</span><span class="o">.</span><span class="n">addHandler</span><span class="p">(</span><span class="n">handler</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">log_access_attempt</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Decorator to log all access attempts&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="nd">@wraps</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">decorated_function</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">request</span> <span class="o">=</span> <span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">args</span> <span class="k">else</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="n">access_info</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;timestamp&#39;</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">utcnow</span><span class="p">()</span><span class="o">.</span><span class="n">isoformat</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;user_id&#39;</span><span class="p">:</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="s1">&#39;user_id&#39;</span><span class="p">,</span> <span class="s1">&#39;anonymous&#39;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;ip_address&#39;</span><span class="p">:</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="s1">&#39;remote_addr&#39;</span><span class="p">,</span> <span class="s1">&#39;unknown&#39;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;endpoint&#39;</span><span class="p">:</span> <span class="n">f</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;method&#39;</span><span class="p">:</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="s1">&#39;method&#39;</span><span class="p">,</span> <span class="s1">&#39;unknown&#39;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;user_agent&#39;</span><span class="p">:</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="s1">&#39;user_agent&#39;</span><span class="p">,</span> <span class="s1">&#39;unknown&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">result</span> <span class="o">=</span> <span class="n">f</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="n">access_info</span><span class="p">[</span><span class="s1">&#39;status&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;granted&#39;</span>
</span></span><span class="line"><span class="cl">            <span class="n">access_logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;ACCESS_GRANTED: </span><span class="si">{</span><span class="n">access_info</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="n">result</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">        <span class="k">except</span> <span class="n">PermissionDenied</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">access_info</span><span class="p">[</span><span class="s1">&#39;status&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;denied&#39;</span>
</span></span><span class="line"><span class="cl">            <span class="n">access_info</span><span class="p">[</span><span class="s1">&#39;reason&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="n">access_logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;ACCESS_DENIED: </span><span class="si">{</span><span class="n">access_info</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="k">raise</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">        <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">access_info</span><span class="p">[</span><span class="s1">&#39;status&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;error&#39;</span>
</span></span><span class="line"><span class="cl">            <span class="n">access_info</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="n">access_logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;ACCESS_ERROR: </span><span class="si">{</span><span class="n">access_info</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="k">raise</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">decorated_function</span>
</span></span></code></pre></div><h3 id="anomaly-detection"><strong>Anomaly Detection</strong></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">AccessAnomalyDetector</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">redis_client</span> <span class="o">=</span> <span class="n">redis</span><span class="o">.</span><span class="n">Redis</span><span class="p">(</span><span class="n">host</span><span class="o">=</span><span class="s1">&#39;localhost&#39;</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="mi">6379</span><span class="p">,</span> <span class="n">db</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">detect_unusual_access</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user_id</span><span class="p">,</span> <span class="n">resource_id</span><span class="p">,</span> <span class="n">action</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;&#34;&#34;Detect unusual access patterns&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># Track access frequency</span>
</span></span><span class="line"><span class="cl">        <span class="n">key</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&#34;access_freq:</span><span class="si">{</span><span class="n">user_id</span><span class="si">}</span><span class="s2">:</span><span class="si">{</span><span class="n">action</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">current_count</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">redis_client</span><span class="o">.</span><span class="n">incr</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">redis_client</span><span class="o">.</span><span class="n">expire</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="mi">3600</span><span class="p">)</span>  <span class="c1"># 1 hour window</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># Alert if too many requests</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">current_count</span> <span class="o">&gt;</span> <span class="mi">100</span><span class="p">:</span>  <span class="c1"># Threshold</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">send_alert</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;User </span><span class="si">{</span><span class="n">user_id</span><span class="si">}</span><span class="s2"> made </span><span class="si">{</span><span class="n">current_count</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">action</span><span class="si">}</span><span class="s2"> requests in last hour&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># Track resource access patterns</span>
</span></span><span class="line"><span class="cl">        <span class="n">resource_key</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&#34;resource_access:</span><span class="si">{</span><span class="n">user_id</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">redis_client</span><span class="o">.</span><span class="n">sadd</span><span class="p">(</span><span class="n">resource_key</span><span class="p">,</span> <span class="n">resource_id</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">redis_client</span><span class="o">.</span><span class="n">expire</span><span class="p">(</span><span class="n">resource_key</span><span class="p">,</span> <span class="mi">86400</span><span class="p">)</span>  <span class="c1"># 24 hour window</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="n">unique_resources</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">redis_client</span><span class="o">.</span><span class="n">scard</span><span class="p">(</span><span class="n">resource_key</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># Alert if accessing too many different resources</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">unique_resources</span> <span class="o">&gt;</span> <span class="mi">1000</span><span class="p">:</span>  <span class="c1"># Threshold</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">send_alert</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;User </span><span class="si">{</span><span class="n">user_id</span><span class="si">}</span><span class="s2"> accessed </span><span class="si">{</span><span class="n">unique_resources</span><span class="si">}</span><span class="s2"> different resources in 24h&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">detect_privilege_escalation</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user_id</span><span class="p">,</span> <span class="n">attempted_action</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;&#34;&#34;Detect potential privilege escalation attempts&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># Track permission escalation attempts</span>
</span></span><span class="line"><span class="cl">        <span class="n">escalation_key</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&#34;escalation_attempts:</span><span class="si">{</span><span class="n">user_id</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># Common admin actions that regular users shouldn&#39;t attempt</span>
</span></span><span class="line"><span class="cl">        <span class="n">admin_actions</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;delete_user&#39;</span><span class="p">,</span> <span class="s1">&#39;modify_permissions&#39;</span><span class="p">,</span> <span class="s1">&#39;access_admin_panel&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">attempted_action</span> <span class="ow">in</span> <span class="n">admin_actions</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">redis_client</span><span class="o">.</span><span class="n">incr</span><span class="p">(</span><span class="n">escalation_key</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">redis_client</span><span class="o">.</span><span class="n">expire</span><span class="p">(</span><span class="n">escalation_key</span><span class="p">,</span> <span class="mi">86400</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">            <span class="n">attempts</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">redis_client</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">escalation_key</span><span class="p">)</span> <span class="ow">or</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="n">attempts</span> <span class="o">&gt;=</span> <span class="mi">5</span><span class="p">:</span>  <span class="c1"># Multiple escalation attempts</span>
</span></span><span class="line"><span class="cl">                <span class="bp">self</span><span class="o">.</span><span class="n">send_alert</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;User </span><span class="si">{</span><span class="n">user_id</span><span class="si">}</span><span class="s2"> attempted privilege escalation </span><span class="si">{</span><span class="n">attempts</span><span class="si">}</span><span class="s2"> times&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="bp">self</span><span class="o">.</span><span class="n">temporary_lockout</span><span class="p">(</span><span class="n">user_id</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">send_alert</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;&#34;&#34;Send security alert to monitoring system&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># Integration with your alerting system</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;SECURITY ALERT: </span><span class="si">{</span><span class="n">message</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">temporary_lockout</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user_id</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;&#34;&#34;Temporarily lock user account&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">lockout_key</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&#34;lockout:</span><span class="si">{</span><span class="n">user_id</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">redis_client</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="n">lockout_key</span><span class="p">,</span> <span class="s2">&#34;locked&#34;</span><span class="p">,</span> <span class="n">ex</span><span class="o">=</span><span class="mi">1800</span><span class="p">)</span>  <span class="c1"># 30 minute lockout</span>
</span></span></code></pre></div><hr>
<h2 id="common-mistakes-and-how-to-avoid-them">Common Mistakes and How to Avoid Them</h2>
<h3 id="frontend-security-theater"><strong>Frontend Security Theater</strong></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="c1">// WRONG: Security only in frontend
</span></span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">AdminComponent</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="p">[</span><span class="nx">user</span><span class="p">,</span> <span class="nx">setUser</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="kc">null</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1">// This check is meaningless for security
</span></span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nx">user</span><span class="p">.</span><span class="nx">role</span> <span class="o">!==</span> <span class="s1">&#39;admin&#39;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="o">&lt;</span><span class="nx">div</span><span class="o">&gt;</span><span class="nx">Access</span> <span class="nx">Denied</span><span class="o">&lt;</span><span class="err">/div&gt;;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="o">&lt;</span><span class="nx">div</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="o">&lt;</span><span class="nx">button</span> <span class="nx">onClick</span><span class="o">=</span><span class="p">{()</span> <span class="p">=&gt;</span> <span class="nx">deleteAllUsers</span><span class="p">()}</span><span class="o">&gt;</span><span class="nx">Delete</span> <span class="nx">All</span> <span class="nx">Users</span><span class="o">&lt;</span><span class="err">/button&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="o">&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// CORRECT: Security enforced on backend
</span></span></span><span class="line"><span class="cl"><span class="nx">app</span><span class="p">.</span><span class="k">delete</span><span class="p">(</span><span class="s1">&#39;/api/users&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// Real security check on server
</span></span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">user</span><span class="p">.</span><span class="nx">role</span> <span class="o">!==</span> <span class="s1">&#39;admin&#39;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="nx">res</span><span class="p">.</span><span class="nx">status</span><span class="p">(</span><span class="mi">403</span><span class="p">).</span><span class="nx">json</span><span class="p">({</span><span class="nx">error</span><span class="o">:</span> <span class="s1">&#39;Admin access required&#39;</span><span class="p">});</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1">// Proceed with operation
</span></span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><h3 id="inconsistent-authorization-across-methods"><strong>Inconsistent Authorization Across Methods</strong></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># WRONG: Only protecting some HTTP methods</span>
</span></span><span class="line"><span class="cl"><span class="nd">@app.route</span><span class="p">(</span><span class="s1">&#39;/api/documents/&lt;int:id&gt;&#39;</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;GET&#39;</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">get_document</span><span class="p">(</span><span class="nb">id</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># Authorization check</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="ow">not</span> <span class="n">user_can_access_document</span><span class="p">(</span><span class="n">current_user</span><span class="p">,</span> <span class="nb">id</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">abort</span><span class="p">(</span><span class="mi">403</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">jsonify</span><span class="p">(</span><span class="n">get_document_data</span><span class="p">(</span><span class="nb">id</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">@app.route</span><span class="p">(</span><span class="s1">&#39;/api/documents/&lt;int:id&gt;&#39;</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;DELETE&#39;</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">delete_document</span><span class="p">(</span><span class="nb">id</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># No authorization check - VULNERABILITY</span>
</span></span><span class="line"><span class="cl">    <span class="n">delete_document_data</span><span class="p">(</span><span class="nb">id</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="mi">204</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># CORRECT: Consistent authorization</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">require_document_access</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="nd">@wraps</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">decorated</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">doc_id</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="ow">not</span> <span class="n">user_can_access_document</span><span class="p">(</span><span class="n">current_user</span><span class="p">,</span> <span class="n">doc_id</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="n">abort</span><span class="p">(</span><span class="mi">403</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">f</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">decorated</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">@app.route</span><span class="p">(</span><span class="s1">&#39;/api/documents/&lt;int:id&gt;&#39;</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;GET&#39;</span><span class="p">,</span> <span class="s1">&#39;PUT&#39;</span><span class="p">,</span> <span class="s1">&#39;DELETE&#39;</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="nd">@require_document_access</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">handle_document</span><span class="p">(</span><span class="nb">id</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s1">&#39;GET&#39;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">jsonify</span><span class="p">(</span><span class="n">get_document_data</span><span class="p">(</span><span class="nb">id</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="k">elif</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s1">&#39;DELETE&#39;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">delete_document_data</span><span class="p">(</span><span class="nb">id</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="mi">204</span>
</span></span></code></pre></div><h3 id="trusting-client-side-data-for-authorization"><strong>Trusting Client-Side Data for Authorization</strong></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="c1">// WRONG: Trusting role from client request</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nd">@PostMapping</span><span class="p">(</span><span class="s">&#34;/api/users&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="n">User</span><span class="w"> </span><span class="nf">createUser</span><span class="p">(</span><span class="nd">@RequestBody</span><span class="w"> </span><span class="n">CreateUserRequest</span><span class="w"> </span><span class="n">request</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">User</span><span class="w"> </span><span class="n">newUser</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">User</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">newUser</span><span class="p">.</span><span class="na">setUsername</span><span class="p">(</span><span class="n">request</span><span class="p">.</span><span class="na">getUsername</span><span class="p">());</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">newUser</span><span class="p">.</span><span class="na">setRole</span><span class="p">(</span><span class="n">request</span><span class="p">.</span><span class="na">getRole</span><span class="p">());</span><span class="w"> </span><span class="c1">// Client controls role!</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="n">userRepository</span><span class="p">.</span><span class="na">save</span><span class="p">(</span><span class="n">newUser</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// CORRECT: Server determines role</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nd">@PostMapping</span><span class="p">(</span><span class="s">&#34;/api/users&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="n">User</span><span class="w"> </span><span class="nf">createUser</span><span class="p">(</span><span class="nd">@RequestBody</span><span class="w"> </span><span class="n">CreateUserRequest</span><span class="w"> </span><span class="n">request</span><span class="p">,</span><span class="w"> 
</span></span></span><span class="line"><span class="cl"><span class="w">                      </span><span class="n">Authentication</span><span class="w"> </span><span class="n">auth</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Only admins can create users</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">auth</span><span class="p">.</span><span class="na">getAuthorities</span><span class="p">().</span><span class="na">contains</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">SimpleGrantedAuthority</span><span class="p">(</span><span class="s">&#34;ROLE_ADMIN&#34;</span><span class="p">)))</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">throw</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">AccessDeniedException</span><span class="p">(</span><span class="s">&#34;Admin access required&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">User</span><span class="w"> </span><span class="n">newUser</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">User</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">newUser</span><span class="p">.</span><span class="na">setUsername</span><span class="p">(</span><span class="n">request</span><span class="p">.</span><span class="na">getUsername</span><span class="p">());</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Server determines role based on creator&#39;s permissions</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">String</span><span class="w"> </span><span class="n">newUserRole</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">determineAllowedRole</span><span class="p">(</span><span class="n">auth</span><span class="p">,</span><span class="w"> </span><span class="n">request</span><span class="p">.</span><span class="na">getRole</span><span class="p">());</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">newUser</span><span class="p">.</span><span class="na">setRole</span><span class="p">(</span><span class="n">newUserRole</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="n">userRepository</span><span class="p">.</span><span class="na">save</span><span class="p">(</span><span class="n">newUser</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><hr>
<h2 id="the-psychology-of-access-control-bugs">The Psychology of Access Control Bugs</h2>
<h3 id="why-developers-get-this-wrong"><strong>Why Developers Get This Wrong</strong></h3>
<p>After reviewing hundreds of applications, I&rsquo;ve noticed patterns in how access control bugs get introduced:</p>
<p><strong>1. The Frontend Fallacy</strong><br>
Developers think the UI controls access. &ldquo;Users can&rsquo;t see the admin button, so they can&rsquo;t access admin functions.&rdquo; This is like leaving your house unlocked because you didn&rsquo;t put a welcome mat outside.</p>
<p><strong>2. The Complexity Trap</strong><br>
Modern applications have dozens of microservices, each implementing their own authorization logic. Consistency becomes impossible.</p>
<p><strong>3. The Performance Excuse</strong><br>
&ldquo;Authorization checks are slow&rdquo; - so they get skipped or cached incorrectly. I&rsquo;ve seen apps where admin privileges get cached for hours.</p>
<p><strong>4. The Integration Problem</strong><br>
Third-party APIs, legacy systems, and quick integrations often bypass the main application&rsquo;s authorization entirely.</p>
<h3 id="building-a-security-first-culture"><strong>Building a Security-First Culture</strong></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Make security violations impossible to ignore</span>
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">AuthorizationError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Loud, obvious error that can&#39;t be ignored&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">resource</span><span class="p">,</span> <span class="n">action</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">user</span> <span class="o">=</span> <span class="n">user</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">resource</span> <span class="o">=</span> <span class="n">resource</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">action</span> <span class="o">=</span> <span class="n">action</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># Log immediately</span>
</span></span><span class="line"><span class="cl">        <span class="n">security_logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;AUTHORIZATION_VIOLATION: User </span><span class="si">{</span><span class="n">user</span><span class="o">.</span><span class="n">id</span><span class="si">}</span><span class="s2"> attempted </span><span class="si">{</span><span class="n">action</span><span class="si">}</span><span class="s2"> on </span><span class="si">{</span><span class="n">resource</span><span class="o">.</span><span class="n">id</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># Alert security team</span>
</span></span><span class="line"><span class="cl">        <span class="n">send_security_alert</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;type&#39;</span><span class="p">:</span> <span class="s1">&#39;authorization_violation&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;user_id&#39;</span><span class="p">:</span> <span class="n">user</span><span class="o">.</span><span class="n">id</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;resource&#39;</span><span class="p">:</span> <span class="n">resource</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;action&#39;</span><span class="p">:</span> <span class="n">action</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;timestamp&#39;</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">utcnow</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="p">})</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Access denied: </span><span class="si">{</span><span class="n">user</span><span class="si">}</span><span class="s2"> cannot </span><span class="si">{</span><span class="n">action</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">resource</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Make authorization checks mandatory</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">require_authorization</span><span class="p">(</span><span class="n">resource_class</span><span class="p">,</span> <span class="n">action</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Decorator that makes authorization checks mandatory&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">decorator</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="nd">@wraps</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">def</span> <span class="nf">wrapper</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="c1"># Extract user and resource from function arguments</span>
</span></span><span class="line"><span class="cl">            <span class="n">user</span> <span class="o">=</span> <span class="n">extract_user_from_args</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="n">resource_id</span> <span class="o">=</span> <span class="n">extract_resource_id_from_args</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="ow">not</span> <span class="n">user</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="k">raise</span> <span class="n">AuthenticationError</span><span class="p">(</span><span class="s2">&#34;No authenticated user&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">            <span class="c1"># Load resource</span>
</span></span><span class="line"><span class="cl">            <span class="n">resource</span> <span class="o">=</span> <span class="n">resource_class</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="n">resource_id</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">            <span class="c1"># Check authorization</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="ow">not</span> <span class="n">resource</span><span class="o">.</span><span class="n">user_can_perform</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">action</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">                <span class="k">raise</span> <span class="n">AuthorizationError</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">resource</span><span class="p">,</span> <span class="n">action</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="n">f</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">wrapper</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">decorator</span>
</span></span></code></pre></div><hr>
<h2 id="testing-your-authorization-implementation">Testing Your Authorization Implementation</h2>
<h3 id="unit-tests-for-access-control"><strong>Unit Tests for Access Control</strong></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">pytest</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">django.test</span> <span class="kn">import</span> <span class="n">TestCase</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">django.contrib.auth.models</span> <span class="kn">import</span> <span class="n">User</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">myapp.models</span> <span class="kn">import</span> <span class="n">Document</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">AccessControlTest</span><span class="p">(</span><span class="n">TestCase</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">setUp</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">owner</span> <span class="o">=</span> <span class="n">User</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create_user</span><span class="p">(</span><span class="s1">&#39;owner&#39;</span><span class="p">,</span> <span class="s1">&#39;owner@test.com&#39;</span><span class="p">,</span> <span class="s1">&#39;pass&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">other_user</span> <span class="o">=</span> <span class="n">User</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create_user</span><span class="p">(</span><span class="s1">&#39;other&#39;</span><span class="p">,</span> <span class="s1">&#39;other@test.com&#39;</span><span class="p">,</span> <span class="s1">&#39;pass&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">admin</span> <span class="o">=</span> <span class="n">User</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create_user</span><span class="p">(</span><span class="s1">&#39;admin&#39;</span><span class="p">,</span> <span class="s1">&#39;admin@test.com&#39;</span><span class="p">,</span> <span class="s1">&#39;pass&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">admin</span><span class="o">.</span><span class="n">is_staff</span> <span class="o">=</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">admin</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">document</span> <span class="o">=</span> <span class="n">Document</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="n">title</span><span class="o">=</span><span class="s1">&#39;Test Doc&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="n">content</span><span class="o">=</span><span class="s1">&#39;Secret content&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="n">owner</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">owner</span>
</span></span><span class="line"><span class="cl">        <span class="p">)</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">test_owner_can_read_own_document</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;&#34;&#34;Test that owners can read their own documents&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">document</span><span class="o">.</span><span class="n">user_can_read</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">owner</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">test_other_user_cannot_read_private_document</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;&#34;&#34;Test that other users cannot read private documents&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">document</span><span class="o">.</span><span class="n">user_can_read</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">other_user</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">test_admin_can_read_all_documents</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;&#34;&#34;Test that admins can read all documents&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">document</span><span class="o">.</span><span class="n">user_can_read</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">admin</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">test_unauthorized_access_raises_exception</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;&#34;&#34;Test that unauthorized access attempts raise proper exceptions&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="k">with</span> <span class="n">pytest</span><span class="o">.</span><span class="n">raises</span><span class="p">(</span><span class="n">PermissionDenied</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">document</span><span class="o">.</span><span class="n">get_content_for_user</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">other_user</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">test_idor_protection</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;&#34;&#34;Test IDOR protection by trying to access other user&#39;s document&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">client</span> <span class="o">=</span> <span class="n">Client</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="n">client</span><span class="o">.</span><span class="n">login</span><span class="p">(</span><span class="n">username</span><span class="o">=</span><span class="s1">&#39;other&#39;</span><span class="p">,</span> <span class="n">password</span><span class="o">=</span><span class="s1">&#39;pass&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># Try to access owner&#39;s document</span>
</span></span><span class="line"><span class="cl">        <span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;/documents/</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">document</span><span class="o">.</span><span class="n">id</span><span class="si">}</span><span class="s1">/&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="p">,</span> <span class="mi">403</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">test_privilege_escalation_prevention</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;&#34;&#34;Test that users cannot escalate their privileges&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">client</span> <span class="o">=</span> <span class="n">Client</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="n">client</span><span class="o">.</span><span class="n">login</span><span class="p">(</span><span class="n">username</span><span class="o">=</span><span class="s1">&#39;other&#39;</span><span class="p">,</span> <span class="n">password</span><span class="o">=</span><span class="s1">&#39;pass&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># Try to access admin endpoint</span>
</span></span><span class="line"><span class="cl">        <span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;/admin/users/&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="p">,</span> <span class="mi">403</span><span class="p">)</span>
</span></span></code></pre></div><h3 id="integration-tests"><strong>Integration Tests</strong></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">test_complete_access_control_flow</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Test complete access control flow across multiple services&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1"># Create test users</span>
</span></span><span class="line"><span class="cl">    <span class="n">regular_user</span> <span class="o">=</span> <span class="n">create_test_user</span><span class="p">(</span><span class="n">role</span><span class="o">=</span><span class="s1">&#39;user&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">admin_user</span> <span class="o">=</span> <span class="n">create_test_user</span><span class="p">(</span><span class="n">role</span><span class="o">=</span><span class="s1">&#39;admin&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1"># Test document creation (should work for any authenticated user)</span>
</span></span><span class="line"><span class="cl">    <span class="n">doc</span> <span class="o">=</span> <span class="n">create_document</span><span class="p">(</span><span class="n">user</span><span class="o">=</span><span class="n">regular_user</span><span class="p">,</span> <span class="n">title</span><span class="o">=</span><span class="s1">&#39;Test Doc&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">assert</span> <span class="n">doc</span><span class="o">.</span><span class="n">owner</span> <span class="o">==</span> <span class="n">regular_user</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1"># Test document access (owner should have access)</span>
</span></span><span class="line"><span class="cl">    <span class="k">assert</span> <span class="n">can_access_document</span><span class="p">(</span><span class="n">regular_user</span><span class="p">,</span> <span class="n">doc</span><span class="p">)</span> <span class="o">==</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1"># Test IDOR protection (other user should not have access)</span>
</span></span><span class="line"><span class="cl">    <span class="n">other_user</span> <span class="o">=</span> <span class="n">create_test_user</span><span class="p">(</span><span class="n">role</span><span class="o">=</span><span class="s1">&#39;user&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">assert</span> <span class="n">can_access_document</span><span class="p">(</span><span class="n">other_user</span><span class="p">,</span> <span class="n">doc</span><span class="p">)</span> <span class="o">==</span> <span class="kc">False</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1"># Test admin override (admin should have access)</span>
</span></span><span class="line"><span class="cl">    <span class="k">assert</span> <span class="n">can_access_document</span><span class="p">(</span><span class="n">admin_user</span><span class="p">,</span> <span class="n">doc</span><span class="p">)</span> <span class="o">==</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1"># Test deletion (only owner or admin)</span>
</span></span><span class="line"><span class="cl">    <span class="k">assert</span> <span class="n">can_delete_document</span><span class="p">(</span><span class="n">regular_user</span><span class="p">,</span> <span class="n">doc</span><span class="p">)</span> <span class="o">==</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl">    <span class="k">assert</span> <span class="n">can_delete_document</span><span class="p">(</span><span class="n">other_user</span><span class="p">,</span> <span class="n">doc</span><span class="p">)</span> <span class="o">==</span> <span class="kc">False</span>
</span></span><span class="line"><span class="cl">    <span class="k">assert</span> <span class="n">can_delete_document</span><span class="p">(</span><span class="n">admin_user</span><span class="p">,</span> <span class="n">doc</span><span class="p">)</span> <span class="o">==</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1"># Test API access patterns</span>
</span></span><span class="line"><span class="cl">    <span class="n">response</span> <span class="o">=</span> <span class="n">api_client</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;/api/documents/</span><span class="si">{</span><span class="n">doc</span><span class="o">.</span><span class="n">id</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">,</span> 
</span></span><span class="line"><span class="cl">                             <span class="n">headers</span><span class="o">=</span><span class="n">auth_headers</span><span class="p">(</span><span class="n">other_user</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="k">assert</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="o">==</span> <span class="mi">403</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="n">response</span> <span class="o">=</span> <span class="n">api_client</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;/api/documents/</span><span class="si">{</span><span class="n">doc</span><span class="o">.</span><span class="n">id</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">,</span> 
</span></span><span class="line"><span class="cl">                             <span class="n">headers</span><span class="o">=</span><span class="n">auth_headers</span><span class="p">(</span><span class="n">regular_user</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="k">assert</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="o">==</span> <span class="mi">200</span>
</span></span></code></pre></div><hr>
<h2 id="conclusion">Conclusion</h2>
<p>Broken access control isn&rsquo;t just a technical vulnerability - it&rsquo;s a systematic failure that affects 94% of applications. The consolidation of SSRF into this category in OWASP 2025 reflects the reality that attackers don&rsquo;t think in isolated vulnerability categories - they chain techniques to bypass authorization.</p>
<p><strong>Key Takeaways from 15+ Years of Access Control Bugs:</strong></p>
<ol>
<li><strong>Authorization happens on the server, period</strong> - Never trust client-side security</li>
<li><strong>Default deny everything</strong> - Require explicit permission for every action</li>
<li><strong>Test with different user contexts</strong> - Your tests should include cross-user scenarios</li>
<li><strong>Monitor and log access patterns</strong> - Unusual activity often indicates exploitation</li>
<li><strong>Defense in depth</strong> - Multiple layers of authorization checks</li>
</ol>
<p>The patterns are predictable, the solutions are well-understood, and the tools exist. The only reason broken access control remains #1 is because teams don&rsquo;t prioritize implementing authorization correctly from the start.</p>
<p>Don&rsquo;t be part of that 94%. Build authorization into your application architecture from day one, test it thoroughly, and monitor it continuously.</p>
<p><strong>Next Steps:</strong></p>
<ul>
<li>Implement the authorization patterns shown for your framework</li>
<li>Set up monitoring for access control violations</li>
<li>Create tests that verify authorization from an attacker&rsquo;s perspective</li>
<li>Review your existing applications with these attack patterns in mind</li>
</ul>
<p>Remember: attackers don&rsquo;t care about your user interface - they go straight to your API. Make sure your API cares about authorization.</p>
<hr>
<p><strong>Ready to tackle the next OWASP category?</strong> Continue with our <a href="/2026/05/owasp-a02-security-misconfiguration-prevention/">A02: Security Misconfiguration Guide</a> - the vulnerability that jumped from #5 to #2 in 2025.</p>
]]></content:encoded></item><item><title>OWASP Top 10 2025 Developer Guide</title><link>https://chs.us/2026/05/owasp-top-10-2025-complete-developer-security-guide/</link><pubDate>Tue, 05 May 2026 20:00:00 +0000</pubDate><author>carl.sampson@gmail.com (Carl Sampson)</author><guid>https://chs.us/2026/05/owasp-top-10-2025-complete-developer-security-guide/</guid><description>Master the OWASP Top 10 2025 web application vulnerabilities. Complete developer guide with supply chain failures, exceptional conditions, and modern security risks.</description><category>Security</category><category>Owasp</category><category>Web-Security</category><category>Application-Security</category><category>Security-Guide</category><category>Vulnerability-Prevention</category><content:encoded><![CDATA[<p>I&rsquo;ve been working with the OWASP Top 10 for years, and the 2025 update just dropped some major changes that every developer needs to understand. Supply chain attacks finally made it into the top 10 (as A03), and honestly, it&rsquo;s about time. I&rsquo;ve been seeing these attacks destroy companies for the past few years.</p>
<p>Here&rsquo;s the thing about OWASP Top 10 2025: it&rsquo;s not just updating the old list - it&rsquo;s completely rethinking modern threats. Security misconfiguration jumped from #5 to #2, and they merged <a href="/guides/ssrf/">SSRF</a> into broken access control because that&rsquo;s how attackers actually chain these vulnerabilities together.</p>
<p><img src="/images/owasp-top-10-2025-infographic.png" alt="OWASP Top 10 2025 infographic showing new supply chain failures and exceptional conditions categories by Carl Sampson"
  loading="lazy"
  decoding="async"
/></p>
<h2 id="quick-answer-what-is-owasp-top-10-2025">Quick Answer: What is OWASP Top 10 2025?</h2>
<p><strong>The OWASP Top 10 2025 is a standardized list of the 10 most critical web application security risks that:</strong></p>
<ul>
<li><strong>Identifies</strong> the most dangerous vulnerabilities based on real attack data</li>
<li><strong>Provides</strong> actionable guidance for developers and security teams</li>
<li><strong>Updates</strong> every 3-4 years based on evolving threat landscape</li>
<li><strong>Covers</strong> 94% of applications tested by security firms worldwide</li>
<li><strong>Influences</strong> compliance standards like PCI DSS and security frameworks</li>
<li><strong>Serves</strong> as the foundation for secure development practices globally</li>
</ul>
<hr>
<h2 id="whats-new-in-owasp-top-10-2025">What&rsquo;s New in OWASP Top 10 2025</h2>
<p>The 2025 update is honestly the biggest shake-up since I started following OWASP. They didn&rsquo;t just move things around - they completely rethought how modern attacks actually work. Security misconfiguration jumping to #2 perfectly reflects what I&rsquo;m seeing in the wild.</p>
<h3 id="what-actually-changed-and-why-i-care"><strong>What Actually Changed (And Why I Care):</strong></h3>
<ul>
<li>
<p><strong>🆕 A03: Software Supply Chain Failures</strong> - finally! I&rsquo;ve been waiting for this category for years</p>
</li>
<li>
<p><strong>🆕 A10: Mishandling of Exceptional Conditions</strong> - error handling is where so many apps break</p>
</li>
<li>
<p><strong>🔄 SSRF consolidated into A01</strong> - makes sense since it&rsquo;s really an access control bypass</p>
</li>
<li>
<p><strong>📈 Security Misconfiguration</strong> jumped from #5 to <strong>#2</strong> - this reflects reality</p>
</li>
<li>
<p><strong>📉 Cryptographic Failures</strong> dropped to #4 - still critical but not the #2 problem anymore</p>
</li>
<li>
<p><strong>📉 Injection</strong> fell to #5 - modern frameworks are finally helping here</p>
</li>
</ul>
<h3 id="why-this-matters"><strong>Why This Matters:</strong></h3>
<p>After analyzing over 175,000 CVE records, OWASP finally caught up to what we&rsquo;ve been seeing in real attacks. Supply chain compromises are destroying companies, and misconfigurations are the low-hanging fruit that attackers love. This isn&rsquo;t just academic anymore - it&rsquo;s battle-tested priority ordering.</p>
<hr>
<h2 id="the-owasp-top-10-2025-vulnerabilities">The OWASP Top 10 2025 Vulnerabilities</h2>
<h3 id="a012021---broken-access-control-"><strong>A01:2021 - Broken Access Control</strong> 🚨</h3>
<blockquote>
<p><strong>Risk Level:</strong> Critical | <strong>Prevalence:</strong> 94% of applications</p>
</blockquote>
<p>This one keeps me up at night. I&rsquo;ve seen too many breaches that started with someone just changing a URL parameter from <code>/user/123</code> to <code>/user/124</code> and suddenly they&rsquo;re looking at someone else&rsquo;s data.</p>
<p>Access control is supposed to make sure users can only do what they&rsquo;re supposed to do. When it breaks (which is apparently 94% of the time), attackers get access to everything.</p>
<hr>
<p><strong>What I See All The Time:</strong></p>
<ul>
<li>
<p>Developers assuming the frontend &ldquo;hides&rdquo; admin functions (it doesn&rsquo;t)</p>
</li>
<li>
<p>APIs that check authentication but forget about authorization</p>
</li>
<li>
<p>Direct object references where changing an ID gives you someone else&rsquo;s stuff</p>
</li>
<li>
<p>Force browsing to pages that should be protected</p>
</li>
</ul>
<p><strong>Prevention Summary:</strong></p>
<ul>
<li>
<p>Implement proper authorization checks at the server side</p>
</li>
<li>
<p>Default deny access control policies</p>
</li>
<li>
<p>Log access control failures and alert admins appropriately</p>
</li>
<li>
<p>Rate limit API calls to minimize damage from automated attacks</p>
</li>
</ul>
<p><a href="/2026/06/owasp-a01-broken-access-control-prevention/"><strong>→ Complete Broken Access Control Guide</strong></a></p>
<hr>
<h3 id="a022025---security-misconfiguration-"><strong>A02:2025 - Security Misconfiguration</strong> ⚙️</h3>
<blockquote>
<p><strong>Risk Level:</strong> Critical | <strong>Prevalence:</strong> 90% of applications (jumped from #5)</p>
</blockquote>
<p>This one shot up to #2 for a reason - I see misconfiguration disasters weekly. Default passwords, unnecessary features enabled, error messages leaking sensitive info. It&rsquo;s the stuff that makes me want to scream &ldquo;did anyone even read the deployment guide?&rdquo;</p>
<hr>
<p><strong>What Keeps Breaking:</strong></p>
<ul>
<li>
<p>Default accounts with passwords like &ldquo;admin/admin&rdquo; still live in production</p>
</li>
<li>
<p>Debug modes enabled in production applications</p>
</li>
<li>
<p>Cloud storage buckets wide open to the internet</p>
</li>
<li>
<p>Security headers completely missing or misconfigured</p>
</li>
</ul>
<p><strong>Prevention Summary:</strong></p>
<ul>
<li>
<p>Implement repeatable hardening processes (Infrastructure as Code)</p>
</li>
<li>
<p>Remove unnecessary features, frameworks, and documentation</p>
</li>
<li>
<p>Review cloud configurations with automated tools</p>
</li>
<li>
<p>Set up proper error handling that doesn&rsquo;t leak system info</p>
</li>
</ul>
<p><a href="/2026/05/owasp-a02-security-misconfiguration-prevention/"><strong>→ Complete Security Misconfiguration Guide</strong></a></p>
<hr>
<h3 id="a032025---software-supply-chain-failures-"><strong>A03:2025 - Software Supply Chain Failures</strong> 📦</h3>
<blockquote>
<p><strong>Risk Level:</strong> Critical | <strong>New Category - Finally!</strong></p>
</blockquote>
<p>About damn time this made the top 10. I&rsquo;ve been tracking supply chain attacks for years, and they&rsquo;re absolutely devastating when they hit. One compromised dependency can destroy an entire organization&rsquo;s security posture.</p>
<hr>
<p><strong>What I&rsquo;m Seeing:</strong></p>
<ul>
<li>
<p>Malicious packages in npm, PyPI, and other repositories</p>
</li>
<li>
<p>Compromised build systems injecting backdoors</p>
</li>
<li>
<p>Dependencies with known vulnerabilities ignored for months</p>
</li>
<li>
<p>CI/CD pipelines with zero security controls</p>
</li>
</ul>
<p><strong>Prevention Summary:</strong></p>
<ul>
<li>
<p>Verify integrity of all software components and updates</p>
</li>
<li>
<p>Use software bill of materials (SBOM) tracking</p>
</li>
<li>
<p>Implement secure CI/CD pipelines with proper access controls</p>
</li>
<li>
<p>Monitor dependencies for known vulnerabilities continuously</p>
</li>
</ul>
<p><strong>→ Complete Supply Chain Security Guide</strong> <em>(Coming Next)</em></p>
<hr>
<h3 id="a042025---cryptographic-failures-"><strong>A04:2025 - Cryptographic Failures</strong> 🔐</h3>
<p><strong>Risk Level:</strong> High | <strong>Dropped from #2 to #4</strong></p>
<p>Previously known as &ldquo;Sensitive Data Exposure,&rdquo; crypto failures are still critical but modern frameworks are actually helping here. That said, I still see plenty of apps transmitting passwords in plain text or using MD5 for &ldquo;security.&rdquo;</p>
<p><strong>What&rsquo;s Still Breaking:</strong></p>
<ul>
<li>
<p>Transmitting sensitive data over HTTP instead of HTTPS</p>
</li>
<li>
<p>Using deprecated algorithms like SHA1 or MD5 for passwords</p>
</li>
<li>
<p>Hardcoded encryption keys and weak key management</p>
</li>
<li>
<p>Missing security headers (HSTS, CSP, etc.)</p>
</li>
</ul>
<p><strong>Prevention Summary:</strong></p>
<ul>
<li>Encrypt all data in transit with TLS 1.3+</li>
<li>Use bcrypt, Argon2, or scrypt for password hashing</li>
<li>Implement proper key rotation and management</li>
<li>Add security headers automatically in your deployment pipeline</li>
</ul>
<p><strong>→ Complete Cryptographic Failures Guide</strong> <em>(Coming Soon)</em></p>
<hr>
<h3 id="a052025---injection-"><strong>A05:2025 - Injection</strong> 💉</h3>
<p><strong>Risk Level:</strong> High | <strong>Dropped from #3 to #5</strong></p>
<p>Injection is finally dropping in the rankings, and honestly, it&rsquo;s about time. Modern frameworks like Django ORM and Prisma are making <a href="/guides/sqli/">SQL injection</a> much harder to accidentally introduce. But legacy apps and custom queries? Still a nightmare.</p>
<p><strong>What&rsquo;s Still Breaking:</strong></p>
<ul>
<li>SQL injection in legacy applications and custom queries</li>
<li>NoSQL injection as teams move to MongoDB and similar</li>
<li>Command injection through file uploads and system integrations</li>
<li>LDAP injection in authentication systems</li>
</ul>
<p><strong>Prevention Summary:</strong></p>
<ul>
<li>Use your framework&rsquo;s ORM instead of raw SQL queries</li>
<li>Validate and sanitize all inputs at the boundary</li>
<li>Never concatenate user input into commands or queries</li>
<li>Use allowlists for input validation, not denylists</li>
</ul>
<p><strong>→ Complete Injection Prevention Guide</strong> <em>(Coming Soon)</em></p>
<hr>
<h3 id="a042021---insecure-design-"><strong>A04:2021 - Insecure Design</strong> 🏗️</h3>
<p><strong>Risk Level:</strong> High | <strong>New Category in 2021</strong></p>
<p>Insecure design represents missing or ineffective control design. It focuses on risks related to design and architectural flaws, calling for secure design patterns and threat modeling.</p>
<p><strong>Common Examples:</strong></p>
<ul>
<li>Missing rate limiting allowing credential stuffing</li>
<li>Trust boundaries not properly defined</li>
<li>Business logic flaws in workflows</li>
<li>Insufficient threat modeling during design</li>
</ul>
<p><strong>Prevention Summary:</strong></p>
<ul>
<li>Establish secure development lifecycle with security considerations</li>
<li>Implement threat modeling for critical authentication flows</li>
<li>Write unit and integration tests to validate security controls</li>
<li>Use established secure design patterns and libraries</li>
</ul>
<p><strong>→ Complete Insecure Design Prevention Guide</strong> <em>(Coming Soon)</em></p>
<hr>
<h3 id="a052021---security-misconfiguration-"><strong>A05:2021 - Security Misconfiguration</strong> ⚙️</h3>
<p><strong>Risk Level:</strong> High | <strong>Prevalence:</strong> 90% of applications tested</p>
<p>Security misconfiguration can happen at any level of an application stack, including network services, platform, web server, application server, database, frameworks, custom code, and pre-installed virtual machines.</p>
<p><strong>Common Examples:</strong></p>
<ul>
<li>Default accounts with unchanged passwords</li>
<li>Unnecessary features enabled (ports, services, pages)</li>
<li>Stack traces displayed to users containing sensitive information</li>
<li>Security settings in frameworks set to non-secure values</li>
</ul>
<p><strong>Prevention Summary:</strong></p>
<ul>
<li>Implement repeatable hardening processes for deployments</li>
<li>Remove unnecessary features, frameworks, and documentation</li>
<li>Review and update security configurations regularly</li>
<li>Implement automated configuration verification</li>
</ul>
<p><strong>→ Complete Security Misconfiguration Guide</strong> <em>(Live!)</em></p>
<hr>
<h3 id="a062021---vulnerable-and-outdated-components-"><strong>A06:2021 - Vulnerable and Outdated Components</strong> 📦</h3>
<p><strong>Risk Level:</strong> High | <strong>Supply Chain Focus</strong></p>
<p>Components run with the same privileges as the application itself, so flaws in any component can result in serious impact. This risk has grown significantly with modern development practices.</p>
<p><strong>Common Examples:</strong></p>
<ul>
<li>Using components with known vulnerabilities</li>
<li>Unsupported or out-of-date software versions</li>
<li>Not scanning for vulnerabilities regularly</li>
<li>Not securing component configurations appropriately</li>
</ul>
<p><strong>Prevention Summary:</strong></p>
<ul>
<li>Remove unused dependencies, features, and files</li>
<li>Continuously inventory versions of all components</li>
<li>Monitor sources for security vulnerabilities in components</li>
<li>Obtain components from official sources over secure links</li>
</ul>
<p><strong>→ Complete Vulnerable Components Guide</strong> <em>(Coming Soon)</em></p>
<hr>
<h3 id="a072021---identification-and-authentication-failures-"><strong>A07:2021 - Identification and Authentication Failures</strong> 🔑</h3>
<p><strong>Risk Level:</strong> High | <strong>Previously Broken Authentication</strong></p>
<p>Confirmation of user identity, authentication, and session management is critical to protect against authentication-related attacks.</p>
<p><strong>Common Examples:</strong></p>
<ul>
<li>Credential stuffing attacks using leaked password databases</li>
<li>Brute force attacks on user accounts</li>
<li>Weak session management allowing session hijacking</li>
<li>Missing or weak multi-factor authentication</li>
</ul>
<p><strong>Prevention Summary:</strong></p>
<ul>
<li>Implement multi-factor authentication where possible</li>
<li>Do not deploy with default credentials</li>
<li>Implement weak password checks and policies</li>
<li>Implement account lockout and rate limiting</li>
</ul>
<p><strong>→ Complete Authentication Failures Guide</strong> <em>(Coming Soon)</em></p>
<hr>
<h3 id="a082021---software-and-data-integrity-failures-"><strong>A08:2021 - Software and Data Integrity Failures</strong> 🔗</h3>
<p><strong>Risk Level:</strong> High | <strong>New Category in 2021</strong></p>
<p>This new category focuses on making assumptions related to software updates, critical data, and CI/CD pipelines without verifying integrity, which can lead to supply chain attacks.</p>
<p><strong>Common Examples:</strong></p>
<ul>
<li>Auto-update functionality downloading updates over unencrypted connections</li>
<li>Insecure <a href="/guides/deserialization/">deserialization</a> leading to remote code execution</li>
<li>CI/CD pipeline security weaknesses</li>
<li>Unsigned or unverified software artifacts</li>
</ul>
<p><strong>Prevention Summary:</strong></p>
<ul>
<li>Use digital signatures to verify software integrity</li>
<li>Ensure CI/CD pipelines have proper segregation and access controls</li>
<li>Review and audit third-party components and dependencies</li>
<li>Implement integrity verification for critical data</li>
</ul>
<p><strong>→ Complete Integrity Failures Guide</strong> <em>(Coming Soon)</em></p>
<hr>
<h3 id="a092021---security-logging-and-monitoring-failures-"><strong>A09:2021 - Security Logging and Monitoring Failures</strong> 📊</h3>
<p><strong>Risk Level:</strong> Medium | <strong>New Category in 2021</strong></p>
<p>Insufficient logging and monitoring, coupled with missing or ineffective integration with incident response, allows attackers to further attack systems and maintain persistence.</p>
<p><strong>Common Examples:</strong></p>
<ul>
<li>Auditable events not logged (logins, failed logins, high-value transactions)</li>
<li>Warnings and errors generate inadequate or unclear log messages</li>
<li>Application and API logs not monitored for suspicious activity</li>
<li>Penetration testing and DAST scans not triggering alerts</li>
</ul>
<p><strong>Prevention Summary:</strong></p>
<ul>
<li>Ensure all login, access control, and input validation failures are logged</li>
<li>Log all events in a format that log management solutions can consume</li>
<li>Establish effective monitoring and alerting for suspicious activities</li>
<li>Establish incident response and recovery plans</li>
</ul>
<p><strong>→ Complete Logging and Monitoring Guide</strong> <em>(Coming Soon)</em></p>
<hr>
<h3 id="a102025---mishandling-of-exceptional-conditions-"><strong>A10:2025 - Mishandling of Exceptional Conditions</strong> ⚠️</h3>
<p><strong>Risk Level:</strong> Medium | <strong>New Category in 2025</strong></p>
<p>Finally, a category that addresses what I see constantly - applications that completely fall apart when something unexpected happens. Error handling is where so many security bugs hide, and now OWASP is finally paying attention.</p>
<p><strong>What Breaks Down:</strong></p>
<ul>
<li>Stack traces revealing sensitive system information</li>
<li>Applications crashing instead of gracefully handling errors</li>
<li>Race conditions in error handling code</li>
<li>Timeouts and resource exhaustion not properly managed</li>
</ul>
<p><strong>Prevention Summary:</strong></p>
<ul>
<li>Implement consistent error handling across your application</li>
<li>Never expose internal system details in error messages</li>
<li>Handle timeouts and resource limits gracefully</li>
<li>Test error conditions as thoroughly as happy paths</li>
</ul>
<p><strong>→ Complete Exception Handling Guide</strong> <em>(Coming Soon)</em></p>
<hr>
<h2 id="implementation-strategy">Implementation Strategy</h2>
<h3 id="phase-1-assessment-week-1-2"><strong>Phase 1: Assessment (Week 1-2)</strong></h3>
<ol>
<li>
<p><strong>Inventory Current Security Posture</strong></p>
<ul>
<li>Audit existing applications against Top 10</li>
<li>Identify immediate high-risk vulnerabilities</li>
<li>Document current security controls</li>
</ul>
</li>
<li>
<p><strong>Prioritize by Risk</strong></p>
<ul>
<li>Focus on A01 (Broken Access Control) first</li>
<li>Address injection vulnerabilities immediately</li>
<li>Review cryptographic implementations</li>
</ul>
</li>
</ol>
<h3 id="phase-2-quick-wins-week-3-4"><strong>Phase 2: Quick Wins (Week 3-4)</strong></h3>
<ol>
<li>
<p><strong>Security Configuration Review</strong></p>
<ul>
<li>Audit default settings and credentials</li>
<li>Implement security headers</li>
<li>Review error handling and information disclosure</li>
</ul>
</li>
<li>
<p><strong>Access Control Hardening</strong></p>
<ul>
<li>Implement consistent authorization checks</li>
<li>Review privilege escalation paths</li>
<li>Add monitoring for access violations</li>
</ul>
</li>
</ol>
<h3 id="phase-3-comprehensive-security-month-2-3"><strong>Phase 3: Comprehensive Security (Month 2-3)</strong></h3>
<ol>
<li>
<p><strong>Design Review Process</strong></p>
<ul>
<li>Implement threat modeling</li>
<li>Review business logic security</li>
<li>Establish secure coding standards</li>
</ul>
</li>
<li>
<p><strong>Supply Chain Security</strong></p>
<ul>
<li>Audit third-party components</li>
<li>Implement dependency scanning</li>
<li>Secure CI/CD pipelines</li>
</ul>
</li>
</ol>
<hr>
<h2 id="security-testing-approach">Security Testing Approach</h2>
<h3 id="automated-testing-tools"><strong>Automated Testing Tools</strong></h3>
<p><strong>Static Application Security Testing (SAST):</strong></p>
<ul>
<li><strong>SonarQube</strong> - Code quality and security analysis</li>
<li><strong>Semgrep</strong> - Custom security rule creation</li>
<li><strong>CodeQL</strong> - Deep semantic code analysis</li>
</ul>
<p><strong>Dynamic Application Security Testing (DAST):</strong></p>
<ul>
<li><strong>OWASP ZAP</strong> - Free comprehensive web app scanner</li>
<li><strong>Burp Suite</strong> - Professional security testing platform</li>
<li><strong>Nuclei</strong> - Fast vulnerability scanner with community templates</li>
</ul>
<p><strong>Software Composition Analysis (SCA):</strong></p>
<ul>
<li><strong>Snyk</strong> - Dependency vulnerability management</li>
<li><strong>OWASP Dependency-Check</strong> - Free dependency analysis</li>
<li><strong>GitHub Dependabot</strong> - Automated dependency updates</li>
</ul>
<h3 id="manual-testing-techniques"><strong>Manual Testing Techniques</strong></h3>
<p><strong>Access Control Testing:</strong></p>
<ul>
<li>Test horizontal and vertical privilege escalation</li>
<li>Validate authorization at every protected resource</li>
<li>Test for insecure direct object references</li>
</ul>
<p><strong>Injection Testing:</strong></p>
<ul>
<li>Test all input fields with various injection payloads</li>
<li>Validate proper encoding and sanitization</li>
<li>Test stored and reflected injection vectors</li>
</ul>
<p><strong>Authentication Testing:</strong></p>
<ul>
<li>Test password policies and account lockout</li>
<li>Validate session management controls</li>
<li>Test multi-factor authentication bypass</li>
</ul>
<hr>
<h2 id="framework-specific-guidance">Framework-Specific Guidance</h2>
<h3 id="django-security"><strong>Django Security</strong></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Secure Django settings</span>
</span></span><span class="line"><span class="cl"><span class="n">SECURE_BROWSER_XSS_FILTER</span> <span class="o">=</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl"><span class="n">SECURE_CONTENT_TYPE_NOSNIFF</span> <span class="o">=</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl"><span class="n">SECURE_HSTS_SECONDS</span> <span class="o">=</span> <span class="mi">31536000</span>
</span></span><span class="line"><span class="cl"><span class="n">SECURE_SSL_REDIRECT</span> <span class="o">=</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl"><span class="n">SESSION_COOKIE_SECURE</span> <span class="o">=</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl"><span class="n">CSRF_COOKIE_SECURE</span> <span class="o">=</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Use Django&#39;s built-in protections</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">django.contrib.auth.decorators</span> <span class="kn">import</span> <span class="n">login_required</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">django.core.exceptions</span> <span class="kn">import</span> <span class="n">PermissionDenied</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">@login_required</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">sensitive_view</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="ow">not</span> <span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">has_perm</span><span class="p">(</span><span class="s1">&#39;app.view_sensitive&#39;</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">raise</span> <span class="n">PermissionDenied</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># Safe implementation</span>
</span></span></code></pre></div><h3 id="flask-security"><strong>Flask Security</strong></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Flask-Security configuration</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">flask_security</span> <span class="kn">import</span> <span class="n">Security</span><span class="p">,</span> <span class="n">login_required</span><span class="p">,</span> <span class="n">roles_required</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">app</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;SECURITY_PASSWORD_SALT&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;secure-salt-here&#39;</span>
</span></span><span class="line"><span class="cl"><span class="n">app</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;SECURITY_HASHING_SCHEMES&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;bcrypt&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">app</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;SECURITY_DEPRECATED_HASHING_SCHEMES&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">@app.route</span><span class="p">(</span><span class="s1">&#39;/admin&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nd">@login_required</span>
</span></span><span class="line"><span class="cl"><span class="nd">@roles_required</span><span class="p">(</span><span class="s1">&#39;admin&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">admin_panel</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># Secure admin functionality</span>
</span></span><span class="line"><span class="cl">    <span class="k">pass</span>
</span></span></code></pre></div><h3 id="spring-boot-security"><strong>Spring Boot Security</strong></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="nd">@Configuration</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nd">@EnableWebSecurity</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">SecurityConfig</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nd">@Bean</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">public</span><span class="w"> </span><span class="n">SecurityFilterChain</span><span class="w"> </span><span class="nf">filterChain</span><span class="p">(</span><span class="n">HttpSecurity</span><span class="w"> </span><span class="n">http</span><span class="p">)</span><span class="w"> </span><span class="kd">throws</span><span class="w"> </span><span class="n">Exception</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">http</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">authorizeHttpRequests</span><span class="p">(</span><span class="n">authz</span><span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="n">authz</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">.</span><span class="na">requestMatchers</span><span class="p">(</span><span class="s">&#34;/admin/**&#34;</span><span class="p">).</span><span class="na">hasRole</span><span class="p">(</span><span class="s">&#34;ADMIN&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">.</span><span class="na">requestMatchers</span><span class="p">(</span><span class="s">&#34;/user/**&#34;</span><span class="p">).</span><span class="na">hasRole</span><span class="p">(</span><span class="s">&#34;USER&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">.</span><span class="na">anyRequest</span><span class="p">().</span><span class="na">authenticated</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">formLogin</span><span class="p">(</span><span class="n">form</span><span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="n">form</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">.</span><span class="na">loginPage</span><span class="p">(</span><span class="s">&#34;/login&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">.</span><span class="na">permitAll</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">.</span><span class="na">sessionManagement</span><span class="p">(</span><span class="n">session</span><span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="n">session</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">.</span><span class="na">maximumSessions</span><span class="p">(</span><span class="n">1</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">.</span><span class="na">maxSessionsPreventsLogin</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="n">http</span><span class="p">.</span><span class="na">build</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><hr>
<h2 id="compliance-and-standards-integration">Compliance and Standards Integration</h2>
<h3 id="industry-standards-alignment"><strong>Industry Standards Alignment</strong></h3>
<p><strong>PCI DSS Requirements:</strong></p>
<ul>
<li>A01-A03: Directly impact PCI DSS requirements 6, 7, 8</li>
<li>Proper access controls required for cardholder data</li>
<li>Input validation essential for payment processing</li>
</ul>
<p><strong>ISO 27001 Controls:</strong></p>
<ul>
<li>A.14.2.5: Secure system engineering principles</li>
<li>A.13.1.1: Network controls</li>
<li>A.9.4.2: Secure log-on procedures</li>
</ul>
<p><strong>NIST Cybersecurity Framework:</strong></p>
<ul>
<li><strong>Protect (PR):</strong> Access control, data security, protective technology</li>
<li><strong>Detect (DE):</strong> Anomalies and events, continuous monitoring</li>
<li><strong>Respond (RS):</strong> Response planning, communications</li>
</ul>
<h3 id="regulatory-considerations"><strong>Regulatory Considerations</strong></h3>
<p><strong>GDPR Implications:</strong></p>
<ul>
<li>Data protection by design and by default</li>
<li>Technical measures for processing security</li>
<li>Breach notification requirements</li>
</ul>
<p><strong>HIPAA Security Rule:</strong></p>
<ul>
<li>Access controls for protected health information</li>
<li>Audit controls and monitoring</li>
<li>Transmission security requirements</li>
</ul>
<hr>
<h2 id="continuous-security-integration">Continuous Security Integration</h2>
<h3 id="devsecops-implementation"><strong>DevSecOps Implementation</strong></h3>
<p><strong>Pre-commit Hooks:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Git pre-commit security scanning</span>
</span></span><span class="line"><span class="cl">pip install pre-commit
</span></span><span class="line"><span class="cl">cat &gt; .pre-commit-config.yaml <span class="s">&lt;&lt; EOF
</span></span></span><span class="line"><span class="cl"><span class="s">repos:
</span></span></span><span class="line"><span class="cl"><span class="s">  - repo: https://github.com/pre-commit/pre-commit-hooks
</span></span></span><span class="line"><span class="cl"><span class="s">    hooks:
</span></span></span><span class="line"><span class="cl"><span class="s">      - id: check-yaml
</span></span></span><span class="line"><span class="cl"><span class="s">      - id: check-json
</span></span></span><span class="line"><span class="cl"><span class="s">  - repo: https://github.com/Yelp/detect-secrets
</span></span></span><span class="line"><span class="cl"><span class="s">    hooks:
</span></span></span><span class="line"><span class="cl"><span class="s">      - id: detect-secrets
</span></span></span><span class="line"><span class="cl"><span class="s">  - repo: https://github.com/PyCQA/bandit
</span></span></span><span class="line"><span class="cl"><span class="s">    hooks:
</span></span></span><span class="line"><span class="cl"><span class="s">      - id: bandit
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span></code></pre></div><p><strong>CI/CD Pipeline Security:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># GitHub Actions security workflow</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Security Scan</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">on</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">push, pull_request]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">jobs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">security</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l">ubuntu-latest</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/checkout@v3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Run security scan</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">securecodewarrior/github-action-add-sarif@v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">sarif-file</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;security-results.sarif&#39;</span><span class="w">
</span></span></span></code></pre></div><h3 id="monitoring-and-alerting"><strong>Monitoring and Alerting</strong></h3>
<p><strong>Security Event Detection:</strong></p>
<ul>
<li>Failed authentication attempts</li>
<li>Privilege escalation activities</li>
<li>Unusual data access patterns</li>
<li>Injection attempt indicators</li>
</ul>
<p><strong>SIEM Integration:</strong></p>
<ul>
<li>Structured logging for security events</li>
<li>Real-time alerting on critical security violations</li>
<li>Automated response to common attack patterns</li>
<li>Threat intelligence integration</li>
</ul>
<hr>
<h2 id="training-and-awareness">Training and Awareness</h2>
<h3 id="developer-security-training"><strong>Developer Security Training</strong></h3>
<p><strong>Essential Topics:</strong></p>
<ol>
<li><strong>Secure Coding Principles</strong> - Input validation, output encoding, error handling</li>
<li><strong>Threat Modeling</strong> - Understanding attacker perspectives and motivations</li>
<li><strong>Security Testing</strong> - Integrating security testing into development workflows</li>
<li><strong>Incident Response</strong> - Developer responsibilities during security incidents</li>
</ol>
<p><strong>Hands-on Labs:</strong></p>
<ul>
<li><strong>DVWA (Damn Vulnerable Web Application)</strong> - Practice identifying vulnerabilities</li>
<li><strong>WebGoat</strong> - OWASP&rsquo;s interactive security learning platform</li>
<li><strong>Security Shepherd</strong> - Capture-the-flag style security challenges</li>
<li><strong>Juice Shop</strong> - Modern vulnerable application for security training</li>
</ul>
<h3 id="security-champion-program"><strong>Security Champion Program</strong></h3>
<p><strong>Champion Responsibilities:</strong></p>
<ul>
<li>Security code review participation</li>
<li>Security training delivery to team members</li>
<li>Threat modeling facilitation</li>
<li>Security tool evaluation and adoption</li>
</ul>
<p><strong>Ongoing Development:</strong></p>
<ul>
<li>Monthly security briefings on new threats</li>
<li>Access to advanced security training resources</li>
<li>Participation in security community events</li>
<li>Recognition and advancement opportunities</li>
</ul>
<hr>
<h2 id="frequently-asked-questions">Frequently Asked Questions</h2>
<h3 id="what-is-the-most-critical-owasp-top-10-vulnerability"><strong>What is the most critical OWASP Top 10 vulnerability?</strong></h3>
<p>Broken Access Control (A01) is the most critical, found in 94% of applications tested. It directly leads to unauthorized access to sensitive data and functionality, making it the top priority for remediation.</p>
<h3 id="how-often-should-we-assess-applications-against-owasp-top-10"><strong>How often should we assess applications against OWASP Top 10?</strong></h3>
<p>Assess applications at minimum annually, or whenever significant changes are made. For high-risk applications, quarterly assessments are recommended. Continuous security testing should be integrated into CI/CD pipelines.</p>
<h3 id="do-owasp-top-10-vulnerabilities-apply-to-apis"><strong>Do OWASP Top 10 vulnerabilities apply to APIs?</strong></h3>
<p>Yes, the OWASP Top 10 applies to APIs, but OWASP also publishes a separate &ldquo;API Security Top 10&rdquo; that addresses API-specific risks like improper assets management and insufficient rate limiting.</p>
<h3 id="what"><strong>What&rsquo;s the difference between OWASP Top 10 2017 and 2021?</strong></h3>
<p>The 2021 version reflects modern threat landscapes with new categories (Insecure Design, Integrity Failures, Logging Failures), reordering based on fresh data, and broader coverage of cloud and supply chain risks.</p>
<h3 id="how-do-i-prioritize-owasp-top-10-remediation"><strong>How do I prioritize OWASP Top 10 remediation?</strong></h3>
<p>Prioritize based on: 1) Business impact of exploitation, 2) Ease of exploitation, 3) Current security controls, 4) Regulatory requirements. Typically start with A01 (Access Control), A02 (Crypto), and A03 (Injection).</p>
<h3 id="are-there-automated-tools-to-check-owasp-top-10-compliance"><strong>Are there automated tools to check OWASP Top 10 compliance?</strong></h3>
<p>Yes, tools like OWASP ZAP, SonarQube, and Snyk can automatically detect many Top 10 vulnerabilities. However, manual testing and code review remain essential for complete coverage.</p>
<hr>
<div class="owasp-series-navigation">
  <div class="series-header">
    <h3>🛡️ OWASP Top 10 2025 Series</h3>
    <p>Complete guides to modern web application security vulnerabilities</p>
  </div>

  <div class="series-content">
    <div class="pillar-page">
      <h4>📚 Complete Guide</h4>
      <a href="/2026/05/owasp-top-10-2025-complete-developer-security-guide/" class="current">
        <strong>OWASP Top 10 2025: Complete Developer Guide</strong><br>
        <span class="description">Comprehensive overview of all vulnerabilities, rankings, and modern threat landscape</span>
      </a>
    </div>

    <div class="vulnerability-guides">
      <h4>🎯 Individual Vulnerability Guides</h4>
      <div class="guide-grid">
        <a href="/2026/06/owasp-a01-broken-access-control-prevention/">
          <strong>A01:</strong> Broken Access Control
          <span class="status">Includes SSRF</span>
        </a>
        <a href="/2026/05/owasp-a02-security-misconfiguration-prevention/">
          <strong>A02:</strong> Security Misconfiguration
          <span class="status">Jumped to #2</span>
        </a>
        <a href="/2026/06/owasp-a03-software-supply-chain-failures-prevention/">
          <strong>A03:</strong> Software Supply Chain Failures
          <span class="status">New in 2025</span>
        </a>
        <a href="/2026/06/owasp-a04-cryptographic-failures-prevention/">
          <strong>A04:</strong> Cryptographic Failures
        </a>
        <a href="/2026/06/owasp-a05-injection-prevention/">
          <strong>A05:</strong> Injection
        </a>
        <div class="coming-soon">
          <strong>A06:</strong> Vulnerable Components <span class="status-coming">Coming Next</span>
        </div>
        <div class="coming-soon">
          <strong>A07:</strong> Authentication Failures <span class="status-coming">Coming Soon</span>
        </div>
        <div class="coming-soon">
          <strong>A08:</strong> Integrity Failures <span class="status-coming">Coming Soon</span>
        </div>
        <div class="coming-soon">
          <strong>A09:</strong> Logging & Monitoring <span class="status-coming">Coming Soon</span>
        </div>
        <div class="coming-soon">
          <strong>A10:</strong> Exception Handling <span class="status-coming">Coming Soon</span>
        </div>
      </div>
    </div>
  </div>

  <div class="series-footer">
    <p><strong>👨‍💻 Written by Carl Sampson</strong> • Security researcher with 15+ years experience • OWASP Indianapolis Chapter founder</p>
  </div>
</div>

<style>
.owasp-series-navigation {
  background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
  border: 1px solid #cbd5e0;
  border-radius: 8px;
  padding: 24px;
  margin: 32px 0;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}

.series-header h3 {
  color: #1a202c;
  margin: 0 0 8px 0;
  font-size: 1.25rem;
  font-weight: 700;
}

.series-header p {
  color: #4a5568;
  margin: 0 0 24px 0;
  font-style: italic;
}

.pillar-page {
  margin-bottom: 24px;
  padding-bottom: 20px;
  border-bottom: 2px solid #e2e8f0;
}

.pillar-page h4, .vulnerability-guides h4 {
  color: #2d3748;
  margin: 0 0 12px 0;
  font-size: 1.1rem;
  font-weight: 600;
}

.pillar-page a {
  display: block;
  padding: 16px;
  background: #ffffff;
  border: 1px solid #e2e8f0;
  border-radius: 6px;
  text-decoration: none;
  color: #2d3748;
  transition: all 0.2s ease;
}

.pillar-page a:hover, .pillar-page a.current {
  border-color: #3182ce;
  box-shadow: 0 2px 4px rgba(49, 130, 206, 0.1);
}

.pillar-page a.current {
  background: #ebf8ff;
  border-color: #3182ce;
}

.pillar-page .description {
  color: #718096;
  font-size: 0.9rem;
  margin-top: 4px;
}

.guide-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 12px;
}

.guide-grid a {
  display: block;
  padding: 12px 16px;
  background: #ffffff;
  border: 1px solid #e2e8f0;
  border-radius: 6px;
  text-decoration: none;
  color: #2d3748;
  transition: all 0.2s ease;
  position: relative;
}

.guide-grid a:hover, .guide-grid a.current {
  border-color: #3182ce;
  transform: translateY(-1px);
  box-shadow: 0 2px 4px rgba(49, 130, 206, 0.1);
}

.guide-grid a.current {
  background: #ebf8ff;
  border-color: #3182ce;
}

.guide-grid strong {
  color: #1a202c;
  font-weight: 600;
}

.coming-soon {
  display: block;
  padding: 12px 16px;
  background: #f7fafc;
  border: 1px solid #e2e8f0;
  border-radius: 6px;
  color: #718096;
  position: relative;
  opacity: 0.7;
}

.coming-soon strong {
  color: #4a5568;
  font-weight: 600;
}

.status {
  display: inline-block;
  background: #fed7d7;
  color: #9b2c2c;
  font-size: 0.75rem;
  padding: 2px 6px;
  border-radius: 4px;
  margin-left: 8px;
  font-weight: 500;
}

.status-coming {
  display: inline-block;
  background: #edf2f7;
  color: #4a5568;
  font-size: 0.75rem;
  padding: 2px 6px;
  border-radius: 4px;
  margin-left: 8px;
  font-weight: 500;
}

.status:contains("New") {
  background: #c6f6d5;
  color: #276749;
}

.status:contains("Jumped") {
  background: #fef5e7;
  color: #975a16;
}

.series-footer {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid #e2e8f0;
}

.series-footer p {
  color: #718096;
  font-size: 0.9rem;
  margin: 0;
  text-align: center;
}

 
@media (prefers-color-scheme: dark) {
  .owasp-series-navigation {
    background: linear-gradient(135deg, #1a202c 0%, #2d3748 100%);
    border-color: #4a5568;
  }

  .series-header h3, .pillar-page h4, .vulnerability-guides h4 {
    color: #f7fafc;
  }

  .series-header p, .pillar-page .description, .series-footer p {
    color: #a0aec0;
  }

  .pillar-page a, .guide-grid a {
    background: #2d3748;
    border-color: #4a5568;
    color: #f7fafc;
  }

  .pillar-page a:hover, .guide-grid a:hover,
  .pillar-page a.current, .guide-grid a.current {
    background: #2c5282;
    border-color: #3182ce;
  }

  .guide-grid strong {
    color: #f7fafc;
  }

  .coming-soon {
    background: #2d3748;
    border-color: #4a5568;
    color: #a0aec0;
  }

  .coming-soon strong {
    color: #cbd5e0;
  }

  .status-coming {
    background: #4a5568;
    color: #a0aec0;
  }
}
</style>
<h2 id="next-steps-deep-dive-guides">Next Steps: Deep Dive Guides</h2>
<p>This guide provides a comprehensive overview of OWASP Top 10 2025. For detailed implementation guidance, practical examples, and hands-on labs, explore our complete series:</p>
<h3 id="-start-with-priority-vulnerabilities"><strong>🚀 Start with Priority Vulnerabilities:</strong></h3>
<ol>
<li><strong><a href="/2026/06/owasp-a01-broken-access-control-prevention/">Broken Access Control Prevention →</a></strong> - Still #1, includes SSRF now</li>
<li><strong><a href="/2026/05/owasp-a02-security-misconfiguration-prevention/">Security Misconfiguration →</a></strong> - Jumped to #2, critical priority</li>
<li><strong>Supply Chain Failures</strong> <em>(Coming Next)</em> - New category, modern threat</li>
</ol>
<h3 id="-complete-series-navigation"><strong>📚 Complete Series Navigation:</strong></h3>
<ul>
<li><strong>A04: Cryptographic Failures</strong> <em>(Coming Soon)</em></li>
<li><strong>A05: Injection</strong> <em>(Coming Soon)</em></li>
<li><strong>A06: Vulnerable Components</strong> <em>(Coming Soon)</em></li>
<li><strong>A07: Authentication Failures</strong> <em>(Coming Soon)</em></li>
<li><strong>A08: Integrity Failures</strong> <em>(Coming Soon)</em></li>
<li><strong>A09: Logging/Monitoring</strong> <em>(Coming Soon)</em></li>
<li><strong>A10: Exception Handling</strong> <em>(Coming Soon)</em></li>
</ul>
<h3 id="-practical-resources"><strong>🛠️ Practical Resources:</strong></h3>
<ul>
<li><strong>Security Testing Toolkit</strong> <em>(Coming Soon)</em> - Tools and methodologies</li>
<li><strong>Secure Development Lifecycle</strong> <em>(Coming Soon)</em> - Process integration</li>
<li><strong><a href="/security-playground/">Security Playground →</a></strong> - Interactive vulnerability demos</li>
</ul>
<hr>
<h2 id="conclusion">Conclusion</h2>
<p>The OWASP Top 10 2021 represents the current state of web application security threats based on real-world data and expert analysis. While this guide provides comprehensive coverage of each vulnerability, remember that security is not a checkbox exercise—it&rsquo;s an ongoing process of assessment, improvement, and vigilance.</p>
<p>The shift to Broken Access Control as #1 and the addition of design-focused categories reflects the maturing threat landscape. Modern attackers are sophisticated, and our defenses must evolve accordingly.</p>
<p><strong>Key Takeaways:</strong></p>
<ul>
<li><strong>Start with access control</strong> - it&rsquo;s the #1 vulnerability for a reason</li>
<li><strong>Security by design</strong> matters more than ever (A04)</li>
<li><strong>Supply chain security</strong> is now a top-tier concern (A06, A08)</li>
<li><strong>Detection and response</strong> are critical capabilities (A09)</li>
</ul>
<p>Use this guide as your roadmap, but remember: effective security comes from understanding not just the &ldquo;what&rdquo; but the &ldquo;why&rdquo; behind each vulnerability. Each detailed guide in this series will give you that deeper understanding needed to build truly secure applications.</p>
<hr>
<p><strong>Ready to secure your applications?</strong> Start with our <a href="/2026/06/owasp-a01-broken-access-control-prevention/">Broken Access Control Prevention Guide</a> - the #1 vulnerability affecting 94% of applications tested.</p>
]]></content:encoded></item></channel></rss>