code wiki / _hdl_build / nx_adnet_submit_gate.nx

nx_adnet_submit_gate.nx source

↩ module page · 127 lines · 6733 B

1// nx_adnet_submit_gate.nx -- GATE for the self-serve intake surface (nx_adnet_submit). Proves: the GET form 2// renders zero-JS with all fields; a VALID POST stages a row (read-back verified) and shows confirmation; a 3// malicious POST (external img / javascript: click / bad slug) is REJECTED, re-populates the form ESCAPED, 4// and stages NOTHING (load-bearing negative control on the live journal); reflected XSS in a field stays 5// escaped. expect_exit: 0 license_tier: ORIGINAL 6import "nx_syscalls.nx" 7import "_hdl_build/nx_adnet_submit.nx" 8 9func fg_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 10func fg_putn(v: i64) -> i64 { var m: i64 = v; if m < 0 { fg_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 } 11 12func fg_has(hay: *u8, n: i64, needle: *u8) -> i64 { 13 var nl: i64 = 0 14 while needle[nl] != (0 as u8) { nl = nl + 1 } 15 if nl == 0 { return 0 } 16 var i: i64 = 0 17 while i + nl <= n { 18 var j: i64 = 0 19 var eq: i64 = 1 20 while j < nl { if hay[i + j] != needle[j] { eq = 0; break } j = j + 1 } 21 if eq == 1 { return 1 } 22 i = i + 1 23 } 24 return 0 25} 26 27func fg_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 28 29func fg_readn(path: *u8, box: *i64) -> *u8 { 30 box[0] = 0 31 return sys_read_file(path, box) 32} 33 34func main() -> i64 { 35 fg_puts("=== nx_adnet_submit_gate ===\n" as *u8) 36 var pass: i64 = 0 37 var fail: i64 = 0 38 let out: *u8 = sys_mmap(65536) 39 let subs: *u8 = "/tmp/adnet_submit_test.log" as *u8 40 let f0: i64 = sys_openat_wr(subs, 0x1A4) 41 if f0 >= 0 { sys_close(f0) } 42 43 // T1 GET form zero-JS with all fields 44 let w0: i64 = asf_form_page(out, 65536) 45 var t1: i64 = 1 46 if w0 <= 0 { t1 = 0 } 47 if fg_has(out, w0, "name=\"slug\"" as *u8) == 0 { t1 = 0 } 48 if fg_has(out, w0, "name=\"business\"" as *u8) == 0 { t1 = 0 } 49 if fg_has(out, w0, "name=\"img\"" as *u8) == 0 { t1 = 0 } 50 if fg_has(out, w0, "name=\"click\"" as *u8) == 0 { t1 = 0 } 51 if fg_has(out, w0, "name=\"section\"" as *u8) == 0 { t1 = 0 } 52 if fg_has(out, w0, "<script" as *u8) == 1 { t1 = 0 } 53 // empty-form fields must render EMPTY (value="") -- guards the ""-literal alias-pool trap that leaked a 54 // stray pooled vhost string ("andelinwest.com") into every field. slug field value must be immediately "". 55 if fg_has(out, w0, "name=\"slug\" value=\"\"" as *u8) == 0 { t1 = 0 } 56 if fg_has(out, w0, "andelinwest" as *u8) == 1 { t1 = 0 } 57 if t1 == 1 { pass = pass + 1 } else { fail = fail + 1; fg_puts("T1 FAIL form render / empty-field alias leak\n" as *u8) } 58 59 // T2 valid POST stages + confirms 60 let good: *u8 = "slug=acme-spring&business=Acme+Co&img=%2Fsynth%2Facme.png&click=https%3A%2F%2Facme.example&section=home" as *u8 61 let w1: i64 = asf_post(good, fg_slen(good), subs, out, 65536) 62 var t2: i64 = 1 63 if w1 <= 0 { t2 = 0 } 64 if fg_has(out, w1, "Submitted for review" as *u8) == 0 { t2 = 0 } 65 if fg_has(out, w1, "acme-spring" as *u8) == 0 { t2 = 0 } 66 let box: *i64 = sys_mmap(8) as *i64 67 let back1: *u8 = fg_readn(subs, box) 68 if (back1 as i64) == 0 { t2 = 0 } else { 69 if fg_has(back1, box[0], "acme-spring" as *u8) == 0 { t2 = 0 } 70 if fg_has(back1, box[0], "Acme Co" as *u8) == 0 { t2 = 0 } 71 if fg_has(back1, box[0], "/synth/acme.png" as *u8) == 0 { t2 = 0 } 72 } 73 if t2 == 1 { pass = pass + 1 } else { fail = fail + 1; fg_puts("T2 FAIL valid submit\n" as *u8) } 74 75 // T3 external img REJECTED + nothing staged 76 let badimg: *u8 = "slug=evilimg&business=Bad&img=https%3A%2F%2Fevil.example%2Fx.png&click=https%3A%2F%2Fok.example&section=home" as *u8 77 let w2: i64 = asf_post(badimg, fg_slen(badimg), subs, out, 65536) 78 var t3: i64 = 1 79 if fg_has(out, w2, "Rejected" as *u8) == 0 { t3 = 0 } 80 let back2: *u8 = fg_readn(subs, box) 81 if (back2 as i64) != 0 { if fg_has(back2, box[0], "evilimg" as *u8) == 1 { t3 = 0 } } 82 if t3 == 1 { pass = pass + 1 } else { fail = fail + 1; fg_puts("T3 FAIL external img not rejected\n" as *u8) } 83 84 // T4 javascript: click REJECTED + nothing staged 85 let badclick: *u8 = "slug=evilclick&business=Bad&img=%2Fsynth%2Fb.png&click=javascript%3Aalert(1)&section=home" as *u8 86 let w3: i64 = asf_post(badclick, fg_slen(badclick), subs, out, 65536) 87 var t4: i64 = 1 88 if fg_has(out, w3, "Rejected" as *u8) == 0 { t4 = 0 } 89 let back3: *u8 = fg_readn(subs, box) 90 if (back3 as i64) != 0 { if fg_has(back3, box[0], "evilclick" as *u8) == 1 { t4 = 0 } } 91 if t4 == 1 { pass = pass + 1 } else { fail = fail + 1; fg_puts("T4 FAIL javascript click not rejected\n" as *u8) } 92 93 // T5 bad slug (uppercase/space) REJECTED 94 let badslug: *u8 = "slug=Bad+Slug&business=Co&img=%2Fsynth%2Fc.png&click=%2Fx&section=home" as *u8 95 let w4: i64 = asf_post(badslug, fg_slen(badslug), subs, out, 65536) 96 var t5: i64 = 1 97 if fg_has(out, w4, "Rejected" as *u8) == 0 { t5 = 0 } 98 if t5 == 1 { pass = pass + 1 } else { fail = fail + 1; fg_puts("T5 FAIL bad slug not rejected\n" as *u8) } 99 100 // T6 reflected XSS in business field stays escaped in the re-populated form (rejected via external img, 101 // so the form re-renders with the submitted business value -> must be escaped, raw tag absent). 102 let xss: *u8 = "slug=okslug&business=%3Cscript%3Ealert(1)%3C%2Fscript%3E&img=https%3A%2F%2Fevil%2Fx.png&click=%2Fx&section=home" as *u8 103 let w5b: i64 = asf_post(xss, fg_slen(xss), subs, out, 65536) 104 var t6: i64 = 1 105 if fg_has(out, w5b, "&lt;script&gt;" as *u8) == 0 { t6 = 0 } 106 if fg_has(out, w5b, "<script>alert" as *u8) == 1 { t6 = 0 } 107 if t6 == 1 { pass = pass + 1 } else { fail = fail + 1; fg_puts("T6 FAIL reflected xss not escaped\n" as *u8) } 108 109 fg_puts("pass=" as *u8) 110 fg_putn(pass) 111 fg_puts(" fail=" as *u8) 112 fg_putn(fail) 113 fg_puts("\n" as *u8) 114 115 let log: *u8 = sys_mmap(256) 116 var lo: i64 = 0 117 if fail == 0 { lo = ad_cat(log, lo, "ADNETSUBMIT authored=organ verdict=GREEN" as *u8) } else { lo = ad_cat(log, lo, "ADNETSUBMIT authored=organ verdict=RED" as *u8) } 118 log[lo] = 10 as u8 119 lo = lo + 1 120 let fd: i64 = sys_openat_wr("knowledge/status/adnet_submit.log" as *u8, 0x1A4) 121 if fd >= 0 { sys_write(fd, log, lo); sys_close(fd) } 122 123 if fail == 0 { fg_puts("=== ADNET-SUBMIT-GATE verdict=GREEN ===\n" as *u8); sys_exit(0); return 0 } 124 fg_puts("=== ADNET-SUBMIT-GATE verdict=RED ===\n" as *u8) 125 sys_exit(1) 126 return 1 127}