54 lines
2.5 KiB
Go
54 lines
2.5 KiB
Go
package scanner
|
||
|
||
import (
|
||
"net/http"
|
||
"strings"
|
||
)
|
||
|
||
// CheckCORS отправляет клон req с произвольным Origin-заголовком
|
||
// (уникальным на каждый вызов) и смотрит, отражает ли сервер этот
|
||
// Origin в Access-Control-Allow-Origin — особенно опасно в сочетании
|
||
// с Access-Control-Allow-Credentials: true, что открывает межсайтовый
|
||
// доступ к аутентифицированным данным с любого сайта.
|
||
//
|
||
// В отличие от Check-проверок, CORS не подставляется в §маркер§ —
|
||
// здесь модифицируется заголовок запроса, а не тело/параметр, поэтому
|
||
// это отдельная функция, а не реализация интерфейса Check.
|
||
func CheckCORS(client *http.Client, req *http.Request) (*Finding, error) {
|
||
evilOrigin := "https://" + randToken(6) + ".burterm-cors-check.invalid"
|
||
|
||
probe := req.Clone(req.Context())
|
||
probe.Header.Set("Origin", evilOrigin)
|
||
|
||
resp, err := client.Do(probe)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
defer resp.Body.Close()
|
||
|
||
acao := resp.Header.Get("Access-Control-Allow-Origin")
|
||
acac := resp.Header.Get("Access-Control-Allow-Credentials")
|
||
|
||
switch {
|
||
case acao == evilOrigin:
|
||
sev := SeverityMedium
|
||
detail := "Сервер отражает произвольный Origin в Access-Control-Allow-Origin"
|
||
if strings.EqualFold(acac, "true") {
|
||
sev = SeverityHigh
|
||
detail += " вместе с Access-Control-Allow-Credentials: true — межсайтовый доступ к аутентифицированным данным с любого сайта"
|
||
}
|
||
return &Finding{Check: "CORS", Severity: sev, Detail: detail, Evidence: acao}, nil
|
||
|
||
case acao == "*" && strings.EqualFold(acac, "true"):
|
||
// Браузер такую комбинацию по спецификации отклонит, но раз
|
||
// сервер её всё же выставляет — это сигнал небрежной настройки,
|
||
// стоит перепроверить остальные CORS-заголовки вручную.
|
||
return &Finding{
|
||
Check: "CORS", Severity: SeverityMedium,
|
||
Detail: "Access-Control-Allow-Origin: * вместе с Allow-Credentials: true (браузеры отклонят эту комбинацию, но она сигнализирует о небрежной настройке)",
|
||
Evidence: acao,
|
||
}, nil
|
||
}
|
||
|
||
return nil, nil
|
||
}
|