CWE-601: URL Redirection to Untrusted Site ('Open Redirect')
descrizione Open Redirect
:
Un parametro http può contenere un valore URL e potrebbe causare l'applicazione Web per reindirizzare la richiesta all'URL specificato. Modificando il valore dell'URL su un sito dannoso, un utente malintenzionato può avviare correttamente una truffa di phishing e rubare le credenziali dell'utente. Poiché il nome del server nel collegamento modificato è identico al sito originale, i tentativi di phishing hanno un aspetto più affidabile.
Il suggerimento di input validation
strategia per prevenire aperta attacco di reindirizzamento:
assumere tutte ingresso è dannoso. Utilizzare una strategia di convalida dell'input "accetta noto", ovvero utilizzare una whitelist di input accettabili che siano strettamente conformi alle specifiche. Rifiuta qualsiasi input che non è strettamente conforme alle specifiche o trasformalo in qualcosa che lo fa. Non affidarsi esclusivamente alla ricerca di input malevoli o malformati (ad esempio, non fare affidamento su una lista nera). Una lista nera rischia di perdere almeno un input indesiderato, specialmente se l'ambiente del codice cambia. Questo può dare agli attaccanti spazio sufficiente per aggirare la convalida prevista. Tuttavia, le liste nere possono essere utili per individuare potenziali attacchi o determinare quali input sono così malformati da dover essere respinti in modo definitivo. Utilizzare una whitelist di URL o domini approvati da utilizzare per il reindirizzamento.
Usa req.headers.host
, req.host
o req.hostname
è insicuro, perché req.headers
possono essere contraffatti (ad es. Una richiesta HTTP avete l'usanza Host
intestazione per accedere a un'applicazione esplicito scritto nel codice qui sotto)
var url = require('url');
app.get('/login', function (req, res, next) {
var redirect = req.query.redirect,
targetUrl = url.parse(redirect);
console.log('req.headers.host: [%s]', req.headers.host);
console.log('req.host: [%s]', req.host);
console.log('req.hostname: [%s]', req.hostname);
if (targetUrl.host != req.headers.host) {
return next(new Error('Open redirect attack detected'));
}
return res.redirect(redirect);
});
Usa curl
per fare una richiesta:
$ curl -H 'Host: malicious.example.com' 'http://localhost:3012/login?redirect=http://malicious.example.com' -i
HTTP/1.1 302 Found
X-Powered-By: Express
Location: http://malicious.example.com
Vary: Accept
Content-Type: text/plain; charset=utf-8
Content-Length: 54
Date: Mon, 13 Jun 2016 06:30:55 GMT
Connection: keep-alive
$ #server output
req.headers.host: [malicious.example.com]
req.host: [malicious.example.com]
req.hostname: [malicious.example.com]
vi suggerisco di utilizzare whitelist per convalidare l'input, un codice di esempio sotto:
const WHITELIST_TO_REDIRECT = new Set(["localhost:3012", "www.realdomain.com"]);
app.get('/login', function (req, res, next) {
var redirect = req.query.redirect,
targetUrl = url.parse(redirect);
console.log("req.hostname: [%s]", req.hostname);
console.log("url.host: [%s]", targetUrl.host);
if (!WHITELIST_TO_REDIRECT.has(targetUrl.host)) {
return next(new Error('Open redirect attack detected'));
}
return res.redirect(redirect);
});
potrebbe essere più facile da usare 'reindirizzare = dashboard' e poi l'utilizzo di server' res.redirect ('http://example.com/' + req.query.redirect); 'questo modo il reindirizzamento sarà mai andare via dal tuo server. – Molda
Grazie. Come non inserire hardcode 'http: // example.com /' in 'res.redirect' ma usare' req.host' o qualcosa di simile? – Erik
'res.redirect ('http: //' + req.host + '/' + req.query.redirect)' – Molda