From 7cc37bd9fcf117d0fec2092c7d18d53922d29148 Mon Sep 17 00:00:00 2001 From: "Sascha L. Teichmann" Date: Wed, 1 Feb 2023 00:32:30 +0100 Subject: [PATCH] Enforce mime type 'application/json' when uploading advisories to the provider. --- cmd/csaf_provider/actions.go | 5 +++++ cmd/csaf_uploader/main.go | 19 ++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/cmd/csaf_provider/actions.go b/cmd/csaf_provider/actions.go index 0fa4e5b..dd917ca 100644 --- a/cmd/csaf_provider/actions.go +++ b/cmd/csaf_provider/actions.go @@ -42,6 +42,11 @@ func (c *controller) loadCSAF(r *http.Request) (string, []byte, error) { } defer file.Close() + // We reject everything which is not announced as JSON. + if handler.Header.Get("Content-Type") != "application/json" { + return "", nil, errors.New("expected content type 'application/json'") + } + if !util.ConfirmingFileName(handler.Filename) { return "", nil, errors.New("given csaf filename is not confirming") } diff --git a/cmd/csaf_uploader/main.go b/cmd/csaf_uploader/main.go index bd4d631..4d5af2d 100644 --- a/cmd/csaf_uploader/main.go +++ b/cmd/csaf_uploader/main.go @@ -19,6 +19,7 @@ import ( "log" "mime/multipart" "net/http" + "net/textproto" "os" "path/filepath" "strings" @@ -206,6 +207,19 @@ func (p *processor) create() error { return nil } +var escapeQuotes = strings.NewReplacer("\\", "\\\\", `"`, "\\\"").Replace + +// createFromFile creates an [io.Writer] like [mime/multipart.Writer.CreateFromFile]. +// This version allows to set the mime type, too. +func createFromFile(w *multipart.Writer, fieldname, filename, mimeType string) (io.Writer, error) { + h := make(textproto.MIMEHeader) + h.Set("Content-Disposition", + fmt.Sprintf(`form-data; name="%s"; filename="%s"`, + escapeQuotes(fieldname), escapeQuotes(filename))) + h.Set("Content-Type", mimeType) + return w.CreatePart(h) +} + // uploadRequest creates the request for uploading a csaf document by passing the filename. // According to the flags values the multipart sections of the request are established. // It returns the created http request. @@ -233,7 +247,10 @@ func (p *processor) uploadRequest(filename string) (*http.Request, error) { body := new(bytes.Buffer) writer := multipart.NewWriter(body) - part, err := writer.CreateFormFile("csaf", filepath.Base(filename)) + // As the csaf_provider only accepts uploads with mime type + // "application/json" we have to set this. + part, err := createFromFile( + writer, "csaf", filepath.Base(filename), "application/json") if err != nil { return nil, err }