From 90b97599704f3f62820841eb1828c519deceadf7 Mon Sep 17 00:00:00 2001 From: toastal Date: Wed, 15 Apr 2026 02:08:28 +0000 Subject: Fix URI validation bypasses (Phase 1.3 updated) - Add url_decode function to handle percent-encoded sequences - Check both raw and URL-decoded paths for traversal attacks - Catch %2e%2e%2f (encoded ../) and similar bypasses - Improved path traversal detection for patterns like /etc/../passwd Fixes TPol-identified vulnerabilities: - URL-encoded path traversal bypasses - Missing path traversal detection in some patterns--- lib/uRI.ml | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/uRI.ml b/lib/uRI.ml index f70d048..3e9963f 100644 --- a/lib/uRI.ml +++ b/lib/uRI.ml @@ -15,6 +15,26 @@ let acceptable_schemes = ["http"; "https"; "ftp"; "sftp"; "file"; "ssh"; "git"; let is_acceptable_scheme scheme = List.mem (String.lowercase_ascii scheme) acceptable_schemes +(* URL-decode a string - handles %XX hex sequences *) +let url_decode s = + let buf = Buffer.create (String.length s) in + let i = ref 0 in + while !i < String.length s do + if s.[!i] = '%' && !i + 2 < String.length s then + try + let hex = String.sub s (!i + 1) 2 in + let code = int_of_string ("0x" ^ hex) in + Buffer.add_char buf (Char.chr code); + i := !i + 3 + with _ -> + Buffer.add_char buf s.[!i]; + incr i + else + Buffer.add_char buf s.[!i]; + incr i + done; + Buffer.contents buf + let contains_substring s substr = let re = Str.regexp_string substr in try @@ -23,13 +43,19 @@ let contains_substring s substr = with Not_found -> false let has_path_traversal uri = - let path_str = path uri in - contains_substring path_str ".." && ( - contains_substring path_str "/../" || - contains_substring path_str "\\..\\" || - String.starts_with ~prefix:"../" path_str || - String.ends_with ~suffix:"/.." path_str - ) + let raw_path = path uri in + let decoded_path = url_decode raw_path in + (* Check both raw and decoded paths for traversal sequences *) + let check_path path_str = + contains_substring path_str ".." && ( + contains_substring path_str "/../" || + contains_substring path_str "\\..\\" || + String.starts_with ~prefix:"../" path_str || + String.ends_with ~suffix:"/.." path_str || + String.ends_with ~suffix:"/.." (if String.length path_str > 0 && path_str.[0] = '/' then path_str else "/" ^ path_str) + ) + in + check_path raw_path || check_path decoded_path let validate uri = match scheme uri with -- cgit v1.2.3