code wiki / _hdl_build / nx_site_intake_gate.nx

nx_site_intake_gate.nx source

↩ module page · 160 lines · 8571 B

1// nx_site_intake_gate.nx -- proves the PUBLIC intake route core END-TO-END IN-PROCESS (the 2// nx_fin_route_gate discipline: crafted raw requests -> si_route -> assert response bytes AND plane 3// side-effects), on the nx_gate_verdict base class (L009/D001: new gates inherit, never hand-roll). 4// Fixture paths are per-run epoch-suffixed /tmp files so the gate can never measure its own history 5// (the office-intake T1 state-poisoning lesson). license_tier: ORIGINAL No hw writes (Rule 26). 6import "nx_syscalls.nx" 7import "nx_site_intake.nx" 8import "nx_gate_verdict.nx" 9 10const SIG_BUF: i64 = 16384 11const SIG_BIG: i64 = 5000 12const SIG_B_A: i64 = 97 13 14func sg_has(buf: *u8, n: i64, lit: *u8) -> i64 { 15 let ll: i64 = si_len(lit) 16 if ll == 0 { return 0 } 17 var i: i64 = 0 18 while i + ll <= n { var j: i64 = 0; var ok: i64 = 1; while j < ll { if buf[i+j] != lit[j] { ok = 0; j = ll } else { j = j + 1 } } if ok == 1 { return 1 } i = i + 1 } 19 return 0 20} 21func sg_cnt(buf: *u8, n: i64, b: i64) -> i64 { 22 var c: i64 = 0 23 var i: i64 = 0 24 while i < n { if buf[i] == (b as u8) { c = c + 1 } i = i + 1 } 25 return c 26} 27func sg_read(path: *u8, box: *i64) -> *u8 { 28 box[0] = 0 29 let d: *u8 = sys_read_file(path, box) 30 return d 31} 32 33func main(argc: i64, argv: *i64) -> i64 { 34 let ctr: *i64 = gv_ctr() 35 gv_head("nx_site_intake -- the public contact route: record, refuse, redirect, all proven against per-run fixtures" as *u8) 36 37 let ep: i64 = sys_now_realtime_sec() 38 let plane: *u8 = sys_mmap(SI_SCRATCH) 39 var po: i64 = si_cat(plane, 0, "/tmp/si_gate_plane_" as *u8) 40 po = si_putn(plane, po, ep) 41 plane[po] = 0 as u8 42 let logf: *u8 = sys_mmap(SI_SCRATCH) 43 var lo: i64 = si_cat(logf, 0, "/tmp/si_gate_log_" as *u8) 44 lo = si_putn(logf, lo, ep) 45 logf[lo] = 0 as u8 46 let req: *u8 = sys_mmap(SIG_BUF) 47 let resp: *u8 = sys_mmap(SIG_BUF) 48 let box: *i64 = sys_mmap(16) as *i64 49 50 // ---- T1 real submission -> 303 + safe back + ONE grammar-clean row ---- 51 var t1: i64 = 1 52 var rn: i64 = si_cat(req, 0, "POST /intake/gen-law HTTP/1.1\r\nHost: nishifamily.com\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\nname=Jane+Doe&email=jane%40example.com&message=Please+call+about+an+estate&back=%2Ffactory%2Fgen-law%2Fcontact%23sent&website=" as *u8) 53 var rl: i64 = si_route(req, rn, resp, plane, logf) 54 if sg_has(resp, rl, "303 See Other" as *u8) == 0 { t1 = 0 } 55 if sg_has(resp, rl, "Location: /factory/gen-law/contact#sent\r\n" as *u8) == 0 { t1 = 0 } 56 var pd: *u8 = sg_read(plane, box) 57 if sg_has(pd, box[0], "Jane Doe" as *u8) == 0 { t1 = 0 } 58 if sg_has(pd, box[0], "jane@example.com" as *u8) == 0 { t1 = 0 } 59 if sg_has(pd, box[0], "Please call about an estate" as *u8) == 0 { t1 = 0 } 60 if sg_has(pd, box[0], "gen-law" as *u8) == 0 { t1 = 0 } 61 if sg_cnt(pd, box[0], SI_B_LF) != 1 { t1 = 0 } 62 if sg_cnt(pd, box[0], SI_B_TAB) != 4 { t1 = 0 } 63 gv_check("T1 RECORD a real submission 303s to the caller's safe back and appends one grammar-clean row" as *u8, t1, ctr) 64 65 // ---- T2 honeypot -> SAME 303 shape, NOTHING recorded ---- 66 var t2: i64 = 1 67 rn = si_cat(req, 0, "POST /intake/gen-law HTTP/1.1\r\n\r\nname=Bot&email=bot%40spam.io&message=buy+now&back=%2Ffactory%2Fgen-law%2Fcontact%23sent&website=spamlink" as *u8) 68 rl = si_route(req, rn, resp, plane, logf) 69 if sg_has(resp, rl, "303 See Other" as *u8) == 0 { t2 = 0 } 70 if sg_has(resp, rl, "Location: /factory/gen-law/contact#sent\r\n" as *u8) == 0 { t2 = 0 } 71 pd = sg_read(plane, box) 72 if sg_cnt(pd, box[0], SI_B_LF) != 1 { t2 = 0 } 73 gv_check("T2 HONEYPOT a filled trap gets a 303 indistinguishable from success and records NOTHING" as *u8, t2, ctr) 74 75 // ---- T3 oversized body -> 413 at the door, nothing recorded ---- 76 var t3: i64 = 1 77 rn = si_cat(req, 0, "POST /intake/gen-law HTTP/1.1\r\n\r\n" as *u8) 78 var f3: i64 = 0 79 while f3 < SIG_BIG { req[rn] = SIG_B_A as u8; rn = rn + 1; f3 = f3 + 1 } 80 rl = si_route(req, rn, resp, plane, logf) 81 if sg_has(resp, rl, "413" as *u8) == 0 { t3 = 0 } 82 pd = sg_read(plane, box) 83 if sg_cnt(pd, box[0], SI_B_LF) != 1 { t3 = 0 } 84 gv_check("T3 BODYCAP an oversized body is refused 413 at the door (the oversized-proxied-POST class)" as *u8, t3, ctr) 85 86 // ---- T4 GET -> 405 ---- 87 var t4: i64 = 1 88 rn = si_cat(req, 0, "GET /intake/gen-law HTTP/1.1\r\n\r\n" as *u8) 89 rl = si_route(req, rn, resp, plane, logf) 90 if sg_has(resp, rl, "405" as *u8) == 0 { t4 = 0 } 91 gv_check("T4 METHOD a GET on the intake route is 405, never a page" as *u8, t4, ctr) 92 93 // ---- T5 separator injection cannot break the plane grammar ---- 94 var t5: i64 = 1 95 rn = si_cat(req, 0, "POST /intake/gen-coffee HTTP/1.1\r\n\r\nname=evil%09col%0Arow&message=hi&back=%2Ffactory%2Fgen-coffee%2Fcontact" as *u8) 96 rl = si_route(req, rn, resp, plane, logf) 97 if sg_has(resp, rl, "303 See Other" as *u8) == 0 { t5 = 0 } 98 pd = sg_read(plane, box) 99 if sg_cnt(pd, box[0], SI_B_LF) != 2 { t5 = 0 } 100 if sg_cnt(pd, box[0], SI_B_TAB) != 8 { t5 = 0 } 101 if sg_has(pd, box[0], "evil col row" as *u8) == 0 { t5 = 0 } 102 gv_check("T5 GRAMMAR TAB/CR/LF in fields become spaces BEFORE the append; separator counts hold" as *u8, t5, ctr) 103 104 // ---- T6 open-redirect attempts collapse to '/' ---- 105 var t6: i64 = 1 106 rn = si_cat(req, 0, "POST /intake/gen-law HTTP/1.1\r\n\r\nmessage=hello&back=https%3A%2F%2Fevil.example" as *u8) 107 rl = si_route(req, rn, resp, plane, logf) 108 if sg_has(resp, rl, "Location: /\r\n" as *u8) == 0 { t6 = 0 } 109 rn = si_cat(req, 0, "POST /intake/gen-law HTTP/1.1\r\n\r\nmessage=hello2&back=%2F%2Fevil.example%2Fx" as *u8) 110 rl = si_route(req, rn, resp, plane, logf) 111 if sg_has(resp, rl, "Location: /\r\n" as *u8) == 0 { t6 = 0 } 112 pd = sg_read(plane, box) 113 if sg_cnt(pd, box[0], SI_B_LF) != 4 { t6 = 0 } 114 gv_check("T6 REDIRECT absolute and protocol-relative back targets collapse to '/', submissions still record" as *u8, t6, ctr) 115 116 // ---- T7 all-empty submission -> 400, nothing recorded ---- 117 var t7: i64 = 1 118 rn = si_cat(req, 0, "POST /intake/gen-law HTTP/1.1\r\n\r\nname=&email=&message=&back=%2F" as *u8) 119 rl = si_route(req, rn, resp, plane, logf) 120 if sg_has(resp, rl, "400" as *u8) == 0 { t7 = 0 } 121 pd = sg_read(plane, box) 122 if sg_cnt(pd, box[0], SI_B_LF) != 4 { t7 = 0 } 123 gv_check("T7 EMPTY an all-empty submission is 400 and records nothing" as *u8, t7, ctr) 124 125 // ---- T8 malformed slug -> 404; evidence log = exactly the recorded set ---- 126 var t8: i64 = 1 127 rn = si_cat(req, 0, "POST /intake/Bad_Slug%21 HTTP/1.1\r\n\r\nmessage=x" as *u8) 128 rl = si_route(req, rn, resp, plane, logf) 129 if sg_has(resp, rl, "404" as *u8) == 0 { t8 = 0 } 130 rn = si_cat(req, 0, "POST /intake/../secret HTTP/1.1\r\n\r\nmessage=x" as *u8) 131 rl = si_route(req, rn, resp, plane, logf) 132 if sg_has(resp, rl, "404" as *u8) == 0 { t8 = 0 } 133 pd = sg_read(plane, box) 134 if sg_cnt(pd, box[0], SI_B_LF) != 4 { t8 = 0 } 135 var ld: *u8 = sg_read(logf, box) 136 var rec: i64 = 0 137 var li: i64 = 0 138 let rlit: *u8 = "recorded=1" as *u8 139 let rl8: i64 = si_len(rlit) 140 while li + rl8 <= box[0] { var j8: i64 = 0; var ok8: i64 = 1; while j8 < rl8 { if ld[li+j8] != rlit[j8] { ok8 = 0; j8 = rl8 } else { j8 = j8 + 1 } } if ok8 == 1 { rec = rec + 1; li = li + rl8 } else { li = li + 1 } } 141 if rec != 4 { t8 = 0 } 142 gv_check("T8 SLUG malformed and traversal slugs are 404, and the evidence log carries exactly the 4 recorded submissions" as *u8, t8, ctr) 143 144 // ---- T9 health surface: GET answers 200 ok for the deploy probe; the slug is reserved ---- 145 var t9: i64 = 1 146 rn = si_cat(req, 0, "GET /intake/health HTTP/1.1\r\n\r\n" as *u8) 147 rl = si_route(req, rn, resp, plane, logf) 148 if sg_has(resp, rl, "200 OK" as *u8) == 0 { t9 = 0 } 149 if sg_has(resp, rl, "\r\n\r\nok" as *u8) == 0 { t9 = 0 } 150 rn = si_cat(req, 0, "POST /intake/health HTTP/1.1\r\n\r\nmessage=probe" as *u8) 151 rl = si_route(req, rn, resp, plane, logf) 152 if sg_has(resp, rl, "404" as *u8) == 0 { t9 = 0 } 153 pd = sg_read(plane, box) 154 if sg_cnt(pd, box[0], SI_B_LF) != 4 { t9 = 0 } 155 gv_check("T9 HEALTH GET /intake/health answers 200 ok for the deploy probe; POSTing to the reserved slug records nothing" as *u8, t9, ctr) 156 157 let rc: i64 = gv_verdict("SITE-INTAKE" as *u8, ctr, "the public contact data path is real: record, refuse and redirect proven against per-run fixtures, and the plane grammar cannot be broken from a form" as *u8) 158 sys_exit(rc) 159 return rc 160}