From 563a7a7fe2e667520bce28c79d916a3939a3d816 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Markovi=C4=87?= Date: Thu, 25 Jun 2026 21:42:58 +0200 Subject: [PATCH] =?UTF-8?q?Bezbednost:=20SSRF=20=E2=80=94=20port=20iz=20UR?= =?UTF-8?q?L-a=20se=20izvla=C4=8Di=20kao=20integer=20da=20prese=C4=8De=20C?= =?UTF-8?q?odeQL=20taint=20Pre:=20parsedURL.Host=20je=20i=20dalje=20nosio?= =?UTF-8?q?=20korisni=C4=8Dki=20unos=20u=20mre=C5=BEni=20poziv=20Posle:=20?= =?UTF-8?q?port=20=E2=86=92=20strconv.Atoi=20=E2=86=92=20validiran=20int?= =?UTF-8?q?=20=E2=86=92=20fmt.Sprintf("%d")=20=E2=80=94=20=C4=8Dist=20URL?= =?UTF-8?q?=20bez=20taint-a?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/handler/podesavanja.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/internal/handler/podesavanja.go b/internal/handler/podesavanja.go index f47e928..a63afe4 100644 --- a/internal/handler/podesavanja.go +++ b/internal/handler/podesavanja.go @@ -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") } - // Samo localhost/loopback — SSRF zaštita. Pošto SAST alati (CodeQL) ne - // priznaju validaciju kroz url.Parse kao dovoljnu sanitizaciju, URL - // rekonstruišemo eksplicitno iz validiranih delova, a ne iz korisničkog unosa. + // SSRF zaštita: URL validiramo, izvlačimo SAMO port, a host hardkodiramo. + // Port konvertujemo u integer da presečemo CodeQL taint lanac — broj ne može + // da sadrži URL manipulaciju, pa rekonstruisani URL nije korisnički unos. parsedURL, err := url.Parse(pfrURL) 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) 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} - resp, err := klijent.Get(statusURL.String()) + resp, err := klijent.Get(statusURL) if err != nil { w.Header().Set("Content-Type", "text/html; charset=utf-8") fmt.Fprintf(w, `
✗ Nije dostupan — %s
`, html.EscapeString(err.Error()))