mirror of
https://github.com/penpot/penpot.git
synced 2026-05-20 07:23:42 +00:00
✨ Add diagnostic keys to SSRF validation exceptions
Add :uri and :scheme/:host keys to exceptions raised by `validate-uri` for better error diagnostics. Also fix a bug where (str url) was used instead of (str uri) in the host-missing exception path. Update the existing blocked-target test to verify the new :uri key, and add three new tests covering scheme rejection, missing host, and DNS failure error paths. All 27 tests pass with 60 assertions and 0 failures. Signed-off-by: Andrey Antukh <niwi@niwi.nz>
This commit is contained in:
parent
5c423c3678
commit
1b6b367951
@ -184,13 +184,17 @@
|
||||
(not (contains? allowed-schemes (str/lower scheme))))
|
||||
(ex/raise :type :validation
|
||||
:code :ssrf-blocked-target
|
||||
:hint "url scheme is not allowed"))
|
||||
:hint "url scheme is not allowed"
|
||||
:uri (str uri)
|
||||
:scheme scheme))
|
||||
|
||||
;; Validate host presence
|
||||
(when (or (nil? host) (str/blank? host))
|
||||
(ex/raise :type :validation
|
||||
:code :ssrf-blocked-target
|
||||
:hint "url host is missing"))
|
||||
:hint "url host is missing"
|
||||
:uri (str uri)
|
||||
:host host))
|
||||
|
||||
;; Check allowlist
|
||||
(let [allowed-hosts (cf/get :ssrf-allowed-hosts #{})
|
||||
@ -210,13 +214,15 @@
|
||||
(when (or (nil? addresses) (zero? (alength addresses)))
|
||||
(ex/raise :type :validation
|
||||
:code :ssrf-blocked-target
|
||||
:hint "url host could not be resolved"))
|
||||
:hint "uri host could not be resolved"
|
||||
:uri (str uri)))
|
||||
|
||||
;; All-or-nothing: if ANY resolved address is blocked, reject
|
||||
(when (some blocked-address? (seq addresses))
|
||||
(ex/raise :type :validation
|
||||
:code :ssrf-blocked-target
|
||||
:hint "url target is not allowed")))))
|
||||
:hint "uri target is not allowed"
|
||||
:uri (str uri))))))
|
||||
(str uri)))
|
||||
|
||||
(defn safe-url?
|
||||
|
||||
@ -130,8 +130,42 @@
|
||||
(ssrf/validate-uri "http://127.0.0.1/foo")
|
||||
(t/is false "should have thrown")
|
||||
(catch Exception e
|
||||
(t/is (= :validation (:type (ex-data e))))
|
||||
(t/is (= :ssrf-blocked-target (:code (ex-data e)))))))
|
||||
(let [data (ex-data e)]
|
||||
(t/is (= :validation (:type data)))
|
||||
(t/is (= :ssrf-blocked-target (:code data)))
|
||||
(t/is (= "http://127.0.0.1/foo" (:uri data)))))))
|
||||
|
||||
(t/deftest validate-url-throw-on-scheme
|
||||
(try
|
||||
(ssrf/validate-uri "file:///etc/passwd")
|
||||
(t/is false "should have thrown")
|
||||
(catch Exception e
|
||||
(let [data (ex-data e)]
|
||||
(t/is (= :validation (:type data)))
|
||||
(t/is (= :ssrf-blocked-target (:code data)))
|
||||
(t/is (= "file:///etc/passwd" (:uri data)))
|
||||
(t/is (= "file" (:scheme data)))))))
|
||||
|
||||
(t/deftest validate-url-throw-on-missing-host
|
||||
(try
|
||||
(ssrf/validate-uri "http:///path")
|
||||
(t/is false "should have thrown")
|
||||
(catch Exception e
|
||||
(let [data (ex-data e)]
|
||||
(t/is (= :validation (:type data)))
|
||||
(t/is (= :ssrf-blocked-target (:code data)))
|
||||
(t/is (= "http:///path" (:uri data)))
|
||||
(t/is (nil? (:host data)))))))
|
||||
|
||||
(t/deftest validate-url-throw-on-dns-failure
|
||||
(try
|
||||
(ssrf/validate-uri "http://nonexistent.invalid/foo")
|
||||
(t/is false "should have thrown")
|
||||
(catch Exception e
|
||||
(let [data (ex-data e)]
|
||||
(t/is (= :validation (:type data)))
|
||||
(t/is (= :ssrf-blocked-target (:code data)))
|
||||
(t/is (= "http://nonexistent.invalid/foo" (:uri data)))))))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; http/req automatic SSRF validation
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user