Bezbednost: SSRF — port iz URL-a se izvlači kao integer da preseče CodeQL taint
Pre: parsedURL.Host je i dalje nosio korisnički unos u mrežni poziv
Posle: port → strconv.Atoi → validiran int → fmt.Sprintf("%d") — čist URL bez taint-a
This commit is contained in:
@@ -924,18 +924,24 @@ func (h *Handler) TestFiskalizacije(w http.ResponseWriter, r *http.Request) {
|
|||||||
pfrURL = vrednostIliDefault(podesavanja, "pfr_url", "http://127.0.0.1:4566")
|
pfrURL = vrednostIliDefault(podesavanja, "pfr_url", "http://127.0.0.1:4566")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Samo localhost/loopback — SSRF zaštita. Pošto SAST alati (CodeQL) ne
|
// SSRF zaštita: URL validiramo, izvlačimo SAMO port, a host hardkodiramo.
|
||||||
// priznaju validaciju kroz url.Parse kao dovoljnu sanitizaciju, URL
|
// Port konvertujemo u integer da presečemo CodeQL taint lanac — broj ne može
|
||||||
// rekonstruišemo eksplicitno iz validiranih delova, a ne iz korisničkog unosa.
|
// da sadrži URL manipulaciju, pa rekonstruisani URL nije korisnički unos.
|
||||||
parsedURL, err := url.Parse(pfrURL)
|
parsedURL, err := url.Parse(pfrURL)
|
||||||
if err != nil || (parsedURL.Hostname() != "127.0.0.1" && parsedURL.Hostname() != "localhost") {
|
if err != nil || (parsedURL.Hostname() != "127.0.0.1" && parsedURL.Hostname() != "localhost") {
|
||||||
http.Error(w, "Nevažeći PFR URL — dozvoljen samo localhost", http.StatusBadRequest)
|
http.Error(w, "Nevažeći PFR URL — dozvoljen samo localhost", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
statusURL := url.URL{Scheme: "http", Host: parsedURL.Host, Path: "/api/status"}
|
port := 4566
|
||||||
|
if p := parsedURL.Port(); p != "" {
|
||||||
|
if n, e := strconv.Atoi(p); e == nil && n > 0 && n <= 65535 {
|
||||||
|
port = n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
statusURL := fmt.Sprintf("http://127.0.0.1:%d/api/status", port)
|
||||||
|
|
||||||
klijent := &http.Client{Timeout: 5 * time.Second}
|
klijent := &http.Client{Timeout: 5 * time.Second}
|
||||||
resp, err := klijent.Get(statusURL.String())
|
resp, err := klijent.Get(statusURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||||
fmt.Fprintf(w, `<div class="fisk-status greska">✗ Nije dostupan — %s</div>`, html.EscapeString(err.Error()))
|
fmt.Fprintf(w, `<div class="fisk-status greska">✗ Nije dostupan — %s</div>`, html.EscapeString(err.Error()))
|
||||||
|
|||||||
Reference in New Issue
Block a user