repochecker: New option to restrict domain where remote file can come from

This commit is contained in:
nemunaire 2023-10-13 23:05:08 +02:00
parent 3e1c01031f
commit 6163d51e5b
3 changed files with 43 additions and 0 deletions

View File

@ -126,6 +126,7 @@ func main() {
flag.BoolVar(&fic.StrongDigest, "strongdigest", fic.StrongDigest, "Are BLAKE2b digests required or is SHA-1 good enough?")
flag.BoolVar(&api.IsProductionEnv, "4real", api.IsProductionEnv, "Set this flag when running for a real challenge (it disallows or avoid most of mass user progression deletion)")
flag.Var(&checkplugins, "rules-plugins", "List of libraries containing others rules to checks")
flag.Var(&sync.RemoteFileDomainWhitelist, "remote-file-domain-whitelist", "List of domains which are allowed to store remote files")
flag.Parse()
log.SetPrefix("[admin] ")

View File

@ -7,6 +7,7 @@ import (
"io"
"log"
"net/http"
"net/url"
"os"
"path"
"strings"
@ -17,6 +18,38 @@ import (
"srs.epita.fr/fic-server/libfic"
)
type remoteFileDomainWhitelist []string
func (l *remoteFileDomainWhitelist) String() string {
return fmt.Sprintf("%v", *l)
}
func (l *remoteFileDomainWhitelist) Set(value string) error {
*l = append(*l, value)
return nil
}
var RemoteFileDomainWhitelist remoteFileDomainWhitelist
func isURLAllowed(in string) bool {
if len(RemoteFileDomainWhitelist) == 0 {
return true
}
u, err := url.Parse(in)
if err != nil {
return false
}
for _, t := range RemoteFileDomainWhitelist {
if t == u.Host {
return true
}
}
return false
}
func BuildFilesListInto(i Importer, exercice *fic.Exercice, into string) (files []string, digests map[string][]byte, errs []error) {
// If no files directory, don't display error
if !i.Exists(path.Join(exercice.Path, into)) {
@ -107,6 +140,9 @@ func CheckExerciceFilesPresence(i Importer, exercice *fic.Exercice) (files []str
if pf, exists := paramsFiles[fname]; !exists || pf.URL == "" {
errs = append(errs, NewFileError(exercice, fname, fmt.Errorf("No such file or directory")))
continue
} else if !isURLAllowed(pf.URL) {
errs = append(errs, NewFileError(exercice, fname, fmt.Errorf("URL hostname is not whitelisted")))
continue
} else {
resp, err := http.Head(pf.URL)
if err != nil {
@ -278,6 +314,11 @@ func SyncExerciceFiles(i Importer, exercice *fic.Exercice, exceptions *CheckExce
}
}
if !isURLAllowed(pf.URL) {
errs = append(errs, NewFileError(exercice, fname, fmt.Errorf("URL hostname is not whitelisted")))
continue
}
if f == nil {
var resp *http.Response
resp, err = http.Get(pf.URL)

View File

@ -175,6 +175,7 @@ func main() {
flag.BoolVar(&skipBinaryFileCheck, "skip-binary-file", skipBinaryFileCheck, "In Git-LFS check, don't warn files")
flag.IntVar(&ignoreBinaryFileUnder, "skip-binary-files-under", ignoreBinaryFileUnder, "In Git-LFS check, don't warn files under this size")
flag.Var(&checkplugins, "rules-plugins", "List of libraries containing others rules to checks")
flag.Var(&sync.RemoteFileDomainWhitelist, "remote-file-domain-whitelist", "List of domains which are allowed to store remote files")
flag.Parse()
// Do not display timestamp