1
0
Fork 0
mirror of https://github.com/gocsaf/csaf.git synced 2025-12-22 18:15:42 +01:00

Load location of provider-metadata.json from security.txt

This commit is contained in:
Sascha L. Teichmann 2022-02-07 20:12:32 +01:00
parent 27f1aa5461
commit b894950b63

View file

@ -20,6 +20,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"log"
"net/http" "net/http"
"net/url" "net/url"
"regexp" "regexp"
@ -723,36 +724,88 @@ func (p *processor) locateProviderMetadata(
client := p.httpClient() client := p.httpClient()
for _, loc := range providerMetadataLocations { tryURL := func(url string) (bool, error) {
url := "https://" + domain + "/" + loc
res, err := client.Get(url) res, err := client.Get(url)
if err != nil { if err != nil || res.StatusCode != http.StatusOK ||
continue res.Header.Get("Content-Type") != "application/json" {
} // ignore this as it is expected.
if res.StatusCode != http.StatusOK { return false, nil
continue
}
if res.Header.Get("Content-Type") != "application/json" {
continue
} }
if err := func() error { if err := func() error {
defer res.Body.Close() defer res.Body.Close()
return found(url, res.Body) return found(url, res.Body)
}(); err != nil { }(); err != nil {
return false, err
}
return true, nil
}
for _, loc := range providerMetadataLocations {
url := "https://" + domain + "/" + loc
ok, err := tryURL(url)
if err != nil {
if err == errContinue { if err == errContinue {
continue continue
} }
return err return err
} }
break if ok {
return nil
}
} }
// TODO: Read from security.txt // Read from security.txt
path := "https://" + domain + "/.well-known/security.txt"
res, err := client.Get(path)
if err != nil {
return err
}
if res.StatusCode != http.StatusOK {
return err
}
loc, err := func() (string, error) {
defer res.Body.Close()
return extractProviderURL(res.Body)
}()
if err != nil {
log.Printf("error: %v\n", err)
return nil return nil
} }
if loc != "" {
if _, err = tryURL(loc); err == errContinue {
err = nil
}
}
return err
}
func extractProviderURL(r io.Reader) (string, error) {
sc := bufio.NewScanner(r)
const csaf = "CSAF:"
for sc.Scan() {
line := sc.Text()
if strings.HasPrefix(line, csaf) {
line = strings.TrimSpace(line[len(csaf):])
if !strings.HasPrefix(line, "https://") {
return "", errors.New("CASF: found in security.txt, but does not start with https://")
}
return line, nil
}
}
if err := sc.Err(); err != nil {
return "", err
}
return "", nil
}
func (p *processor) checkProviderMetadata(domain string) error { func (p *processor) checkProviderMetadata(domain string) error {
use(&p.badProviderMetadatas) use(&p.badProviderMetadatas)