X-Forwarded-For parsing and trusted proxy detection for OCaml
at main 81 lines 2.6 kB view raw
1(*--------------------------------------------------------------------------- 2 Copyright (c) 2025 Thomas Gazagnaire. All rights reserved. 3 SPDX-License-Identifier: MIT 4 ---------------------------------------------------------------------------*) 5 6(* Crowbar-based fuzz testing for X-Forwarded-For parsing *) 7 8open Crowbar 9 10(* Test that parse_xff never crashes on arbitrary input *) 11let test_parse_xff_no_crash input = 12 ignore (Xff.parse_xff input); 13 check true 14 15(* Test that first_xff_ip never crashes *) 16let test_first_xff_no_crash input = 17 ignore (Xff.first_xff_ip input); 18 check true 19 20(* Test that parse_cidr never crashes *) 21let test_parse_cidr_no_crash input = 22 ignore (Xff.parse_cidr input); 23 check true 24 25(* Test client_ip with various combinations *) 26let test_get_ip_no_crash socket_ip xff_header = 27 let socket = Result.to_option (Ipaddr.of_string socket_ip) in 28 let xff = if xff_header = "" then None else Some xff_header in 29 ignore (Xff.client_ip ~socket_ip:socket ~xff_header:xff ~trusted_proxies:None); 30 check true 31 32(* Test with comma-separated IP addresses *) 33let test_comma_separated ip1 ip2 ip3 = 34 let xff = ip1 ^ ", " ^ ip2 ^ ", " ^ ip3 in 35 ignore (Xff.parse_xff xff); 36 check true 37 38(* Test IPv4-like addresses *) 39let test_ipv4_xff a b c d = 40 let ipv4 = 41 Fmt.str "%d.%d.%d.%d" 42 (abs a mod 256) 43 (abs b mod 256) 44 (abs c mod 256) 45 (abs d mod 256) 46 in 47 ignore (Xff.parse_xff ipv4); 48 check true 49 50(* Test CIDR notation *) 51let test_cidr_notation a b c d prefix = 52 let cidr = 53 Fmt.str "%d.%d.%d.%d/%d" 54 (abs a mod 256) 55 (abs b mod 256) 56 (abs c mod 256) 57 (abs d mod 256) 58 (abs prefix mod 33) 59 in 60 ignore (Xff.parse_cidr cidr); 61 check true 62 63(* Test is_trusted_proxy never crashes *) 64let test_is_trusted_proxy ip_str cidr_str = 65 (match (Ipaddr.of_string ip_str, Xff.parse_cidr cidr_str) with 66 | Ok ip, Ok prefix -> ignore (Xff.is_trusted_proxy ip [ prefix ]) 67 | _ -> ()); 68 check true 69 70let suite = 71 ( "xff", 72 [ 73 test_case "parse_xff no crash" [ bytes ] test_parse_xff_no_crash; 74 test_case "first_xff_ip no crash" [ bytes ] test_first_xff_no_crash; 75 test_case "parse_cidr no crash" [ bytes ] test_parse_cidr_no_crash; 76 test_case "client_ip no crash" [ bytes; bytes ] test_get_ip_no_crash; 77 test_case "comma separated" [ bytes; bytes; bytes ] test_comma_separated; 78 test_case "ipv4" [ int; int; int; int ] test_ipv4_xff; 79 test_case "cidr notation" [ int; int; int; int; int ] test_cidr_notation; 80 test_case "is_trusted_proxy" [ bytes; bytes ] test_is_trusted_proxy; 81 ] )