How can you do a CRSF attack on express if it only accepts JSON?
Sample Node app:
const express = require('express');
const app = express();
app.use(express.json());
app.post('/item', (req, res, next) => {
console.log('posting item');
res.send(`posted item name: ${req.body.itemName}`);
});
app.listen(4000)
.on('listening', console.log("HTTP server listening on port 4000"));
What I tried:
If you do an attack from an html form it sends form data:
<!DOCTYPE html>
<html lang="en">
<body>
<form action=http://localhost:4000/item method=post >
<input name ="itemName" value="Shirt" type="text">
<input type=submit>
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
With this attack, req.body
will be empty. express.json()
only parses json, not form data. So in this instance, a POST
where the end point requires user data, the attack doesn't do anything.
My actual app uses fetch
to send requests. fetch
does populate req.body
but my understanding is that CSRF can't be done with fetch- Browsers send preflight requests when using fetch. If the preflight request shows that the origin isn't allowed, it will not send the full request. So it will always fail with a CSRF request. But I'm not so certain of this.
So is there another way to send a CSRF attack with user inputs? Or in this case, is there no way to do a successful csrf attack?