code wiki / (root) / nx_url_safety_lib.nx

nx_url_safety_lib.nx

buildroot/runtime/nx_url_safety_lib.nx

7494 B152 linesdepth 2pulls 2 transitivereach 4 importersview sourcekind librarytopic url
docsdependenciesstructsconstsfunctions

about

nx_url_safety_lib.nx -- THE ONE SSRF URL-SAFETY RULER (/compare/mediaingest R11 ge_edge_push). WHY THIS EXISTS. Measured 2026-09-01, corpus_complete=1 over 23,424 sources: the estate has TWO copies of this decision -- csd_url_safe (nx_clean_serve_daemon.nx:101) and ncv_url_safe (nx_cleanview.nx:44). They are byte-for-byte identical logic today, differing only in their function-name prefix, which is exactly the duplicate-ruler defect: they agree by the luck of having been copied, and the next edit to one will not reach the other. For a SECURITY decision that is not a style problem -- it is how one surface quietly keeps admitting a host the other learned to refuse. ⇒ ONE ruler, composed by every caller. WHEN TWO ORGANS MUST AGREE, MAKE DISAGREEMENT IMPOSSIBLE BY CONSTRUCTION RATHER THAN BY REVIEW DISCIPLINE. WHY IT RETURNS A REASON AND NOT A BOOLEAN. This estate has already paid for a boolean here. Its own law: "Four SSRF deny-tests went green while the guard was wholly broken (a url-decoder missing its SPACE terminator swallowed the request line so EVERY url refused as control bytes)." A guard that refuses everything passes every negative test. So: - us_reason() names WHICH RULE FIRED, so a refusal test can assert the rule and not merely the refusal; - us_url_safe() is the 0/1 shim, defined AS us_reason()==US_OK, so the boolean can never disagree with the reason it is derived from; - and any gate over this MUST carry POSITIVE CONTROLS -- inputs that must be ALLOWED -- or a refuse-everything regression scores full marks. SCOPE, STATED SO NOBODY OVER-TRUSTS IT. This is a SYNTACTIC guard on the URL as written. It does NOT resolve DNS, so a public hostname whose A record points at 10.x (DNS rebinding, and the classic time-of-check/time-of-use hole) is ALLOWED here and must be caught at connect time by the fetcher. It blocks all of 172.x rather than only 172.16-31 -- deliberately conservative, and wrong in the direction of refusing a legitimate public host rather than admitting a private one. module: nishi-core.net.url_safety license_tier: ORIGINAL

dependencies 1 imports · 4 importers

nx_syscalls.nx nx_url_safety_lib.nx nx_clean_serve_daemon.nx nx_cleanview.nx nx_url_safety_gate.nx nx_vault_capture.nx

imports: nx_syscalls.nx

imported by: nx_clean_serve_daemon.nxnx_cleanview.nxnx_url_safety_gate.nxnx_vault_capture.nx

structs

none

consts

33const US_OK: i64 = 0
34const US_BAD_SCHEME: i64 = 1 // neither http:// nor https://
35const US_NO_HOST: i64 = 2 // empty host after the scheme
36const US_LOOPBACK: i64 = 3 // localhost or 127.x
37const US_PRIVATE_10: i64 = 4
38const US_PRIVATE_192: i64 = 5
39const US_LINK_LOCAL: i64 = 6 // 169.254.x -- cloud metadata lives here
40const US_PRIVATE_172: i64 = 7
41const US_ZERO_NET: i64 = 8 // 0.x -- 0.0.0.0 routes to local on many stacks
42const US_IPV6_LITERAL: i64 = 9 // any [..] literal: loopback/ULA/link-local all hide in here
43const US_INTERNAL_TLD: i64 = 10 // .local / .internal / .lan
44const US_REASON_N: i64 = 11
46const US_HOST_CAP: i64 = 512
47const US_CH_SLASH: i64 = 47
48const US_CH_COLON: i64 = 58
49const US_CH_QUERY: i64 = 63
50const US_CH_AT: i64 = 64
51const US_CH_UPPER_A: i64 = 65
52const US_CH_UPPER_Z: i64 = 90
53const US_CH_CASE_DELTA: i64 = 32

functions

55func us_reason_name(r: i64) -> *u8
called by 1: main
70func us_reason_is_valid(r: i64) -> i64
76func us_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
called by 1: us_pfx_ci
77func us_lc(c: i64) -> i64
called by 1: us_pfx_ci
83func us_pfx_ci(s: *u8, n: i64, pfx: *u8) -> i64
called by 2: us_host_ofus_reason calls 2: us_slenus_lc
96func us_host_of(url: *u8, ulen: i64, host: *u8, cap: i64) -> i64
called by 2: mainus_reason calls 1: us_pfx_ci
128func us_reason(url: *u8, ulen: i64) -> i64
149func us_url_safe(url: *u8, ulen: i64) -> i64