@@ -752,7 +752,8 @@ func (hs *WebServer) marketDataUploadHandler(w http.ResponseWriter, r *http.Requ
752752 // Limit request body to 10 MB to prevent memory exhaustion.
753753 r .Body = http .MaxBytesReader (w , r .Body , 10 << 20 )
754754
755- // Parse multipart form – limit body to 10 MB.
755+ // Parse multipart form – the body size is already capped by MaxBytesReader above.
756+ //nolint:gosec // G120: request body is bounded by http.MaxBytesReader (10 MB)
756757 if err := r .ParseMultipartForm (10 << 20 ); err != nil {
757758 w .WriteHeader (http .StatusBadRequest )
758759 _ = json .NewEncoder (w ).Encode (map [string ]string {"error" : "failed to parse form: " + err .Error ()})
@@ -863,6 +864,16 @@ func (hs *WebServer) marketDataDownloadHandler(w http.ResponseWriter, r *http.Re
863864 date = time .Now ().In (location ).Format ("2006-01-02" )
864865 }
865866
867+ // Validate the date so it is safe to embed in response headers.
868+ parsedDate , err := time .Parse ("2006-01-02" , date )
869+ if err != nil {
870+ w .Header ().Set ("Content-Type" , "application/json" )
871+ w .WriteHeader (http .StatusBadRequest )
872+ _ = json .NewEncoder (w ).Encode (map [string ]string {"error" : "invalid date format, expected YYYY-MM-DD" })
873+ return
874+ }
875+ date = parsedDate .Format ("2006-01-02" )
876+
866877 rawXML , ok := hs .scheduler .xmlCache .GetRaw (date )
867878 if ! ok {
868879 w .Header ().Set ("Content-Type" , "application/json" )
@@ -872,8 +883,10 @@ func (hs *WebServer) marketDataDownloadHandler(w http.ResponseWriter, r *http.Re
872883 }
873884
874885 w .Header ().Set ("Content-Type" , "application/xml" )
886+ w .Header ().Set ("X-Content-Type-Options" , "nosniff" )
875887 w .Header ().Set ("Content-Disposition" , fmt .Sprintf ("attachment; filename=\" Energy_Prices_%s.xml\" " , date ))
876888 w .WriteHeader (http .StatusOK )
889+ //nolint:gosec // G705: served as a non-sniffable XML attachment, never rendered inline
877890 _ , _ = w .Write (rawXML )
878891}
879892
0 commit comments