freemoney4you.comfreemoney4you.com serves you this JavaScript which runs in your browser:const response = await fetch("https://bank.com/account", {credentials: "include"});
const accountDetails = await response.text();<form id="attack" action="https://bank.com/transfer" method="post">
<input type="hidden" name="to" value="attacker">
<input type="hidden" name="amount" value="10000">
</form>
<script>document.getElementById("attack").submit();</script><img src="https://bank.com/transfer?to=attacker&amount=10000">fetch, like the potential attackfreemoney4you.com's JavaScript cannot read the response from bank.comhttp, https, ws, ftpcse312.com443https://api.cse312.com and https://cse312.com are the same sitehttps://autograder.cse.buffalo.edu and https://buffalo.edu are the same sitehttp://localhost:8080 and http://localhost:5000 are the same sitehttp://localhost:8080 and http://127.0.0.1:8080 which are different sites, but both reach your serverSameSite cookie directive| Cross-origin... | Examples | SOP |
|---|---|---|
| Writes | Links, redirects, form submissions | Allowed |
| Embeds | Multimedia, JS Scripts, links, CSS | Allowed |
| Reads | Reading a fetch response |
Blocked |
SameSite directive rules (A lax cookie would not be sent on this request)fetch a URL on another origin
Access to fetch at '...' from origin '...' blocked by CORSfreemoney4you.com send bank.com:
DELETE request?A cross-origin request is simple if all of these are true:
GET, HEAD, or POSTAccept, Accept-Language, Content-Language, Content-TypeContent-Type, if set, is one of:
application/x-www-form-urlencodedmultipart/form-datatext/plainEvery other request is "to be preflighted"
AJAX existedfetch wouldn't make anything safer. An attacker would simply use a formPUT, DELETE, a JSON body, a custom header) were impossible to send cross-origin before AJAX
AJAX so it was able to block these without breaking existing appsOPTIONS, same pathOPTIONS, so every preflight failsPOST, a PUT, or a DELETESameSite cookie directive. It controls whether a cookie is sent on cross-site requests
Strict - Never sent on a cross-site requestLax - Only sent on a cross-site request if it navigates to your site with a GET requestNone; Secure - Always sentRequests sent from a page on a different site:
| Cross-site request | Strict |
Lax |
None |
|---|---|---|---|
| Clicking a link (GET navigation) | Not sent | Sent | Sent |
| Form submission with GET | Not sent | Sent | Sent |
| Form submission with POST | Not sent | Not sent | Sent |
<img>, <script> |
Not sent | Not sent | Sent |
fetch, <iframe> |
Not sent | Not sent | Sent |
GET requests must never change the state of your server
Lax cookies are sent when the user follows a link from another site
GET /transfer?to=attacker&amount=10000 is exploitable even with modern browser defaultsSameSite are enforced by the user's browser. We have limited control
SameSite valueSameSite=None (Embedded widgets, cross-site sign-in)SameSite checks the site, not the origin. Any subdomain of your site can attack you<form action="/image-upload" id="image-form" method="post" enctype="multipart/form-data">
<input type="hidden" name="xsrf_token" value="AQAAAjppCA8mhugn2UvwOTaKnVY">
<label for="form-file">Image: </label>
<input id="form-file" type="file" name="upload">
<br/>
<label for="image-form-name">Caption: </label>
<input id="image-form-name" type="text" name="name">
<input type="submit" value="Submit">
</form>403 Forbiddenfreemoney4you.com from reading your pagesSameSite settingSameSite controls whether cookies are attached to cross-site requestsGET requests never change state