code wiki / _hdl_build / nx_adnet_selfserve_gate.nx

nx_adnet_selfserve_gate.nx source

↩ module page · 155 lines · 7498 B

1// nx_adnet_selfserve_gate.nx -- GATE for self-serve advertiser intake (nx_adnet_selfserve). Proves: 2// valid submission accepted + persisted (read-back) to the STAGED journal; malicious rows (third-party 3// img, javascript: click, bad id, directive smuggling) REFUSED and NOT persisted; STAGED IS NOT LIVE 4// (the live inventory stays untouched by submit -- the load-bearing negative control); operator approve 5// re-validates and appends to live; the anti-snoop detector FIRES on a planted visitor token. 6// expect_exit: 0 license_tier: ORIGINAL 7import "nx_syscalls.nx" 8import "_hdl_build/nx_adnet_selfserve.nx" 9import "nx_gate_verdict.nx" 10 11func sg_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 12func sg_putn(v: i64) -> i64 { var m: i64 = v; if m < 0 { sg_puts("-" as *u8); m = 0 - m } let t: *u8 = sys_mmap(24); var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 } while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } let o: *u8 = sys_mmap(24); var i: i64 = 0; while i < k { o[i] = t[k - 1 - i]; i = i + 1 } sys_write(1, o, k); return 0 } 13func sg_cat(dst: *u8, off: i64, s: *u8) -> i64 { var o: i64 = off; var i: i64 = 0; while s[i] != (0 as u8) { dst[o] = s[i]; o = o + 1; i = i + 1 } return o } 14func sg_tab(dst: *u8, off: i64) -> i64 { dst[off] = 9 as u8; return off + 1 } 15 16func sg_has(hay: *u8, n: i64, needle: *u8) -> i64 { 17 var nl: i64 = 0 18 while needle[nl] != (0 as u8) { nl = nl + 1 } 19 if nl == 0 { return 0 } 20 var i: i64 = 0 21 while i + nl <= n { 22 var j: i64 = 0 23 var eq: i64 = 1 24 while j < nl { if hay[i + j] != needle[j] { eq = 0; break } j = j + 1 } 25 if eq == 1 { return 1 } 26 i = i + 1 27 } 28 return 0 29} 30 31func sg_row6(dst: *u8, f0: *u8, f1: *u8, f2: *u8, f3: *u8, f4: *u8, f5: *u8) -> i64 { 32 var o: i64 = 0 33 o = sg_cat(dst, o, f0) 34 o = sg_tab(dst, o) 35 o = sg_cat(dst, o, f1) 36 o = sg_tab(dst, o) 37 o = sg_cat(dst, o, f2) 38 o = sg_tab(dst, o) 39 o = sg_cat(dst, o, f3) 40 o = sg_tab(dst, o) 41 o = sg_cat(dst, o, f4) 42 o = sg_tab(dst, o) 43 o = sg_cat(dst, o, f5) 44 return o 45} 46 47func sg_readn(path: *u8, box: *i64) -> *u8 { 48 box[0] = 0 49 let p: *u8 = sys_read_file(path, box) 50 return p 51} 52 53func main() -> i64 { 54 sg_puts("=== nx_adnet_selfserve_gate ===\n" as *u8) 55 var pass: i64 = 0 56 var fail: i64 = 0 57 58 let subs: *u8 = "/tmp/adnet_subs_test.log" as *u8 59 let inv: *u8 = "/tmp/adnet_inv_test.conf" as *u8 60 let f1: i64 = sys_openat_wr(subs, 0x1A4) 61 if f1 >= 0 { sys_close(f1) } 62 let f2: i64 = sys_openat_wr(inv, 0x1A4) 63 if f2 >= 0 { sys_close(f2) } 64 65 let good: *u8 = sys_mmap(1024) 66 let gn: i64 = sg_row6(good, "n1" as *u8, "NewCo" as *u8, "/adnet/n1.png" as *u8, "https://example.com/n1" as *u8, "home" as *u8, "1" as *u8) 67 let badimg: *u8 = sys_mmap(1024) 68 let bin: i64 = sg_row6(badimg, "b1" as *u8, "EvilImgCo" as *u8, "https://evil.example/x.png" as *u8, "https://example.com/b" as *u8, "home" as *u8, "1" as *u8) 69 let badclk: *u8 = sys_mmap(1024) 70 let bcn: i64 = sg_row6(badclk, "b2" as *u8, "EvilClkCo" as *u8, "/adnet/b2.png" as *u8, "javascript:alert(1)" as *u8, "home" as *u8, "1" as *u8) 71 let badid: *u8 = sys_mmap(1024) 72 let bdn: i64 = sg_row6(badid, "a b" as *u8, "BadIdCo" as *u8, "/adnet/b3.png" as *u8, "/x" as *u8, "home" as *u8, "1" as *u8) 73 let baddir: *u8 = sys_mmap(1024) 74 let bxn: i64 = sg_row6(baddir, "@host" as *u8, "smuggled.example" as *u8, "/x.png" as *u8, "/x" as *u8, "home" as *u8, "1" as *u8) 75 76 // T1 valid submit accepted + persisted 77 let r1: i64 = ass_submit(subs, good, gn) 78 let box: *i64 = (sys_mmap(8)) as *i64 79 let back1: *u8 = sg_readn(subs, box) 80 var t1: i64 = 1 81 if r1 != 1 { t1 = 0 } 82 if (back1 as i64) == 0 { t1 = 0 } else { if sg_has(back1, box[0], "n1" as *u8) == 0 { t1 = 0 } } 83 if t1 == 1 { pass = pass + 1 } else { fail = fail + 1; sg_puts("T1 FAIL valid submit\n" as *u8) } 84 85 // T2 malicious rows REFUSED + NOT persisted 86 var t2: i64 = 1 87 if ass_submit(subs, badimg, bin) != 0 { t2 = 0 } 88 if ass_submit(subs, badclk, bcn) != 0 { t2 = 0 } 89 if ass_submit(subs, badid, bdn) != 0 { t2 = 0 } 90 if ass_submit(subs, baddir, bxn) != 0 { t2 = 0 } 91 let back2: *u8 = sg_readn(subs, box) 92 if (back2 as i64) != 0 { 93 if sg_has(back2, box[0], "EvilImgCo" as *u8) == 1 { t2 = 0 } 94 if sg_has(back2, box[0], "EvilClkCo" as *u8) == 1 { t2 = 0 } 95 if sg_has(back2, box[0], "BadIdCo" as *u8) == 1 { t2 = 0 } 96 if sg_has(back2, box[0], "smuggled.example" as *u8) == 1 { t2 = 0 } 97 } 98 if t2 == 1 { pass = pass + 1 } else { fail = fail + 1; sg_puts("T2 FAIL refusals\n" as *u8) } 99 100 // T3 STAGED IS NOT LIVE: the live inventory stays empty after submits (negative control) 101 let back3: *u8 = sg_readn(inv, box) 102 var t3: i64 = 1 103 if (back3 as i64) != 0 { if box[0] > 0 { if sg_has(back3, box[0], "n1" as *u8) == 1 { t3 = 0 } } } 104 if t3 == 1 { pass = pass + 1 } else { fail = fail + 1; sg_puts("T3 FAIL staged leaked live\n" as *u8) } 105 106 // T4 operator approve -> live; invalid approve refused 107 var t4: i64 = 1 108 if ass_approve(inv, good, gn) != 1 { t4 = 0 } 109 let back4: *u8 = sg_readn(inv, box) 110 if (back4 as i64) == 0 { t4 = 0 } else { if sg_has(back4, box[0], "n1" as *u8) == 0 { t4 = 0 } } 111 if ass_approve(inv, badclk, bcn) != 0 { t4 = 0 } 112 let back5: *u8 = sg_readn(inv, box) 113 if (back5 as i64) != 0 { if sg_has(back5, box[0], "EvilClkCo" as *u8) == 1 { t4 = 0 } } 114 if t4 == 1 { pass = pass + 1 } else { fail = fail + 1; sg_puts("T4 FAIL approve\n" as *u8) } 115 116 // T5 anti-snoop detector: clean journal scans 0, then FIRES on a planted visitor token 117 var t5: i64 = 1 118 let back6: *u8 = sg_readn(subs, box) 119 if (back6 as i64) == 0 { t5 = 0 } else { if ass_snoop_scan(back6, box[0]) != 0 { t5 = 0 } } 120 let pfd: i64 = sys_openat_append(subs, 420) 121 if pfd >= 0 { 122 let planted: *u8 = "VISITOR-TOKEN-XYZ" as *u8 123 var pl: i64 = 0 124 while planted[pl] != (0 as u8) { pl = pl + 1 } 125 sys_write(pfd, planted, pl) 126 sys_close(pfd) 127 } 128 let back7: *u8 = sg_readn(subs, box) 129 if (back7 as i64) == 0 { t5 = 0 } else { if ass_snoop_scan(back7, box[0]) != 1 { t5 = 0 } } 130 if t5 == 1 { pass = pass + 1 } else { fail = fail + 1; sg_puts("T5 FAIL anti-snoop detector\n" as *u8) } 131 132 sg_puts("pass=" as *u8) 133 sg_putn(pass) 134 sg_puts(" fail=" as *u8) 135 sg_putn(fail) 136 sg_puts("\n" as *u8) 137 138 let log2: *u8 = sys_mmap(256) 139 var lo: i64 = 0 140 if fail == 0 { lo = sg_cat(log2, lo, "ADNETSELFSERVE authored=organ verdict=GREEN" as *u8) } else { lo = sg_cat(log2, lo, "ADNETSELFSERVE authored=organ verdict=RED" as *u8) } 141 log2[lo] = 10 as u8 142 lo = lo + 1 143 let fd: i64 = sys_openat_wr("knowledge/status/adnet_selfserve.log" as *u8, 0x1A4) 144 if fd >= 0 { sys_write(fd, log2, lo); sys_close(fd) } 145 146 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 147 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 148 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 149 let ctr__dry: *i64 = gv_ctr() 150 ctr__dry[0] = pass 151 ctr__dry[1] = pass + fail 152 let rc__dry: i64 = gv_verdict("ADNET-SELFSERVE-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8) 153 sys_exit(rc__dry) 154 return rc__dry 155}