Question
I have the following code running on localhost:3000 and my api running at localhost:8020. If I visit localhost:3000 the request is made to localhost:8020/user/refresh to get a new access-token with the refresh-token in the cookie and it responds with the new access-token. I am now able to make another request with the acquired access-token to localhost:8020/user/delete.
But why am I able to read the response from the first request as an attacker. Should same-origin policy not prohibit from reading the response, because I have different ports? Is it because I am allowing Origin localhost:3000 to make cross-site requests with "Access-Control-Allow-Origin: localhost:3000"?
If Access-Control-Allow-Origin is the problem, do I have to protect my api requests with csrf-tokens or is there another way? Implementing csrf tokens is not the problem but I am wondering, if there is an different, probably smaller solution.
<script>
function post() {
var x = new XMLHttpRequest();
x.open("GET", "http://localhost:8020/user/refresh", true);
x.withCredentials = true;
x.setRequestHeader("Content-Type", "application/json");
x.onreadystatechange = function () {
if (x.readyState == XMLHttpRequest.DONE) {
var data = JSON.parse(x.responseText);
var x2 = new XMLHttpRequest();
x2.open("POST", "http://localhost:8020/user/delete", true);
x2.setRequestHeader("Content-Type", "application/json");
x2.setRequestHeader("Authorization", `Bearer ${data["data"]["accessToken"]}`);
x2.onreadystatechange = function () {
if (x2.readyState == XMLHttpRequest.DONE) {
console.log(x2.responseText);
}
}
x2.send(JSON.stringify({user : { "id": "2" }}));
}
}
x.send(null);
}
</script>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body onload="post()">
</body>
</html>
Solution
But why am I able to read the response from the first request as an attacker. Should same-origin policy not prohibit from reading the response, because I have different ports? Is it because I am allowing Origin localhost:3000 to make cross-site requests with "Access-Control-Allow-Origin: localhost:3000"?
Yes, "Access-Control-Allow-Origin: localhost:3000" allows localhost:3000 to read response.
If Access-Control-Allow-Origin is the problem, do I have to protect my api requests with csrf-tokens or is there another way? Implementing csrf tokens is not the problem but I am wondering, if there is an different, probably smaller solution.
OWASP recommendation is to always use csrf-tokens. So I implemented csrf-tokens.