CWE-601: URL Redirection to Untrusted Site ('Open Redirect')
Opis Open Redirect
:
parametru HTTP może zawierać wartość URL i może spowodować aplikację internetową, aby przekierować żądanie do określonego adresu URL. Modyfikując wartość adresu URL do złośliwej witryny, osoba atakująca może z powodzeniem uruchomić wyłudzanie informacji i wykraść dane uwierzytelniające użytkownika. Ponieważ nazwa serwera w zmodyfikowanym łączu jest identyczna z oryginalną witryną, próby wyłudzania informacji są bardziej wiarygodne.
Sugestia input validation
strategii zapobiegania otwarty atak przekierowania:
siebie wszelkie wejście jest złośliwy. Użyj strategii sprawdzania danych wejściowych "zaakceptuj dobrze znane", tj. Użyj białej listy dopuszczalnych danych wejściowych ściśle zgodnych ze specyfikacjami. Odrzuć wszelkie dane wejściowe, które nie są ściśle zgodne ze specyfikacjami lub przekształć je w coś, co robi. Nie należy polegać wyłącznie na poszukiwaniu złośliwych lub zniekształconych danych wejściowych (tzn. Nie należy polegać na czarnej liście). Czarna lista prawdopodobnie ominie co najmniej jeden niepożądany sygnał wejściowy, zwłaszcza jeśli zmieni się środowisko kodu. To może dać napastnikowi wystarczająco dużo miejsca, aby ominąć zamierzoną walidację. Jednak czarne listy mogą być przydatne do wykrywania potencjalnych ataków lub określania, które dane wejściowe są tak źle sformułowane, że powinny zostać odrzucone całkowicie. Użyj białej listy zatwierdzonych adresów URL lub domen do przekierowania.
Zastosowanie req.headers.host
, req.host
lub req.hostname
jest niepewny, ponieważ req.headers
mogą być sfałszowane (np. Żądanie HTTP mają zwyczaj Host
nagłówek dostępu do wyraźnej aplikacja napisana w kodzie poniżej)
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);
});
Korzystając curl
aby złożyć zamówienie:
$ 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]
proponuję użyć białej listy, aby sprawdzić poprawność danych wejściowych, kod przykład poniżej:
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);
});
Mogłoby być łatwiejsze w użyciu 'redirect = dashboard' a następnie w użyciu serwera' res.redirect ('http://example.com/' + req.query.redirect) 'W ten sposób będzie przekierowanie nigdy nie oddalaj się od swojego serwera. – Molda
Dzięki. Jak nie kodować hasłem 'http: // example.com /' w 'res.redirect' ale używać' req.host' lub czegoś podobnego? – Erik
'res.redirect ('http: //' + req.host + '/' + req.query.redirect);' – Molda