Node.js · Report #2913312
Usage of unsafe random function in undici for choosing boundary
How it was found
Summary:
Undici uses Math.random() to choose the boundary for a multipart/form-data request. It is known that the output of Math.random() can be predicted if several of its generated values are known.
Description:
If an attacker can access a few generated values of Math.random() and has control over one of the fields of a multipart request, they can add or overwrite fields that are not meant to be controllable.
If there is a mechanism in an app that sends multipart requests to an attacker-controlled website, they can use this to leak the necessary values.
Here is an example app that is vulnerable to this bug.
#!/usr/bin/env node
const express = require('express')
const BACKEND_API = 'http://localhost:2000/order.php'
const app = express()
app.use(express.urlencoded({ extended: false }))
app.get('/trigger-webhook',(req,res)=>{
let url = req.query.url
let data = new FormData()
data.append('event','example-event')
fetch(url,{
body: data,
method: 'POST'
})
res.send('OK')
})
app.post('/order',(req,res)=>{
let description = req.body.description || 'Please wrap it in Christmas-themed wrapping paper.'
let data = new FormData()
data.append('price','4000')
data.append('customer_id','1')
data.append('item_id','1')
data.append('description',description)
fetch(BACKEND_API,{
body: data,
method: `POST`
}).then(r=>r.text()).then(r=>res.send(r)).catch(r=>res.send('Err'))
})
app.listen(8000)
BACKEND_API points to this php app (order.php):
$<?= $_POST['price'] ?> has been subtracted from the account of customer #<?= $_POST['customer_id'] ?> for item <?= $_POST['item_id'] ?>.
description of order: ("<?= $_POST['description'] ?>")
Steps To Reproduce:
- Extract F3883352.
- In the
serverdirectory:npm install; node ./server.js. - In the
serverdirectory:php -S 127.0.0.1:2000. - In the
expdirectory:pip3 install z3-solver; node ./exp.js.
A successful exploit looks like this:
$ node --version
v22.12.0
$ node ./server.js
$ node ./exp.js
Need 9 more values
Need 8 more values
Need 7 more values
Need 6 more values
Need 5 more values
Need 4 more values
Need 3 more values
Need 2 more values
Need 1 more values
$4000 has been subtracted from the account of customer #1337 for item 1.
description of order: ("zzz")
The customer_id parameter could be successfully tampered with.
Impact:
An attacker can tamper with the requests going to the backend APIs if certain conditions are met.
Supporting Material/References:
predict.pyis the modified version of https://github.com/PwnFunction/v8-randomness-predictor/tree/main- https://blog.securityevaluators.com/hacking-the-javascript-lottery-80cc437e3b7f
Impact
An attacker can tamper with the requests going to the backend APIs if certain conditions are met.