code wiki / _hdl_build / nx_cms_draft_exceed_gate.nx

nx_cms_draft_exceed_gate.nx source

↩ module page · 124 lines · 7000 B

1// nx_cms_draft_exceed_gate.nx -- W-RE-004 head-to-head EXCEED (draft-preview, XSS-SANITIZATION axis). 2// Runs BOTH renderers on the SAME corpus of draft content (benign + stored-XSS payloads): 3// OURS = hs_sanitize (KSES-style allowlist: strips <script> content, drops all attrs except safe 4// a@href, kills javascript: schemes) 5// INCUMBENT = raw passthrough (render untrusted draft content without sanitization) -- the CWE-79 6// stored-XSS failure mode of CMS preview/render paths. 7// A render is SAFE iff the output contains no executable vector (<script / onerror / javascript:). 8// Ground truth: a correct renderer is ALWAYS safe. Verdict COMPUTED by nx_cms_exceed. license_tier: ORIGINAL 9import "nx_cms_exceed.nx" 10import "nx_html_sanitize.nx" 11import "nx_syscalls.nx" 12 13func dx_w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 14func dx_num(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m}; let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48;k=1}; while m>0{t[k]=48+(m%10);m=m/10;k=k+1}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(1,bb,k); return 0 } 15func dx_cat(dst: *u8, off: i64, s: *u8) -> i64 { var o: i64=off; var k: i64=0; while s[k]!=(0 as u8){dst[o]=s[k];o=o+1;k=k+1} return o } 16func dx_catnum(dst: *u8, off: i64, v: i64) -> i64 { 17 var o: i64=off; let t: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m}; var k: i64=0 18 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} 19 var i: i64=0; while i<k {dst[o]=t[k-1-i]; o=o+1; i=i+1} return o 20} 21func dx_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 22func dx_lc(c: i64) -> i64 { if c >= 65 { if c <= 90 { return c + 32 } } return c } 23// case-insensitive substring search; needle must be lowercase 24func dx_find_lc(hay: *u8, n: i64, needle: *u8) -> i64 { 25 var nl: i64=0; while needle[nl]!=(0 as u8){nl=nl+1} 26 var i: i64=0 27 while i + nl <= n { 28 var q: i64=0; var ok: i64=1 29 while q<nl { if dx_lc(hay[i+q] as i64) != (needle[q] as i64) { ok=0; q=nl } q=q+1 } 30 if ok==1 { return i } 31 i=i+1 32 } 33 return 0 - 1 34} 35// does buf contain an executable XSS vector? 36func dx_has_marker(buf: *u8, n: i64) -> i64 { 37 if dx_find_lc(buf, n, "<script" as *u8) >= 0 { return 1 } 38 if dx_find_lc(buf, n, "onerror" as *u8) >= 0 { return 1 } 39 if dx_find_lc(buf, n, "javascript:" as *u8) >= 0 { return 1 } 40 return 0 41} 42func dx_row(id: i64, ok: i64, what: *u8) -> i64 { 43 dx_w("DXROW " as *u8); dx_num(id); dx_w(" " as *u8) 44 if ok==1 { dx_w("PASS " as *u8) } else { dx_w("FAIL " as *u8) } 45 dx_w(what); dx_w("\n" as *u8) 46 return ok 47} 48 49func main() -> i64 { 50 var pass: i64 = 0 51 var rows: i64 = 0 52 53 let inp: *i64 = sys_mmap(8 * 16) as *i64 54 var nc: i64 = 0 55 let b0: *u8 = "<b>bold</b> and <i>italic</i>" as *u8; inp[nc]=b0 as i64; nc=nc+1 56 let b1: *u8 = "just plain legal text." as *u8; inp[nc]=b1 as i64; nc=nc+1 57 let x0: *u8 = "<script>alert(1)</script>" as *u8; inp[nc]=x0 as i64; nc=nc+1 58 let x1: *u8 = "<img src=x onerror=alert(1)>" as *u8; inp[nc]=x1 as i64; nc=nc+1 59 let x2: *u8 = "<a href=\"javascript:alert(1)\">click</a>" as *u8; inp[nc]=x2 as i64; nc=nc+1 60 61 let out: *u8 = sys_mmap(4096) 62 var our_correct: i64 = 0 63 var inc_correct: i64 = 0 64 var n_xss: i64 = 0 65 var xss_our: i64 = 0 66 var xss_inc: i64 = 0 67 var i: i64 = 0 68 while i < nc { 69 let s: *u8 = (inp[i]) as *u8 70 let ln: i64 = dx_slen(s) 71 let on: i64 = hs_sanitize(s, ln, out, 4096) 72 var our_safe: i64 = 0; if dx_has_marker(out, on) == 0 { our_safe = 1 } 73 var inc_safe: i64 = 0; if dx_has_marker(s, ln) == 0 { inc_safe = 1 } // incumbent = raw passthrough 74 if our_safe == 1 { our_correct = our_correct + 1 } 75 if inc_safe == 1 { inc_correct = inc_correct + 1 } 76 if dx_has_marker(s, ln) == 1 { // this input is a stored-XSS payload 77 n_xss = n_xss + 1 78 if our_safe == 1 { xss_our = xss_our + 1 } 79 if inc_safe == 1 { xss_inc = xss_inc + 1 } 80 } 81 i = i + 1 82 } 83 84 let verdict: i64 = xcd_verdict(our_correct, inc_correct) 85 dx_w("HEAD-TO-HEAD draft-preview xss-sanitization: ours=" as *u8); dx_num(our_correct); dx_w("/" as *u8); dx_num(nc) 86 dx_w(" incumbent=" as *u8); dx_num(inc_correct); dx_w("/" as *u8); dx_num(nc) 87 dx_w(" xss-neutralized ours=" as *u8); dx_num(xss_our); dx_w("/" as *u8); dx_num(n_xss) 88 dx_w(" incumbent=" as *u8); dx_num(xss_inc); dx_w("/" as *u8); dx_num(n_xss) 89 dx_w(" verdict=" as *u8); dx_w(xcd_vname(verdict)); dx_w("\n" as *u8) 90 91 var ok: i64 = 0; if our_correct == nc { ok = 1 } 92 rows=rows+1; pass=pass+dx_row(0, ok, "ours fully safe (every payload neutralized, benign kept)" as *u8) 93 ok = 0; if inc_correct < nc { ok = 1 } 94 rows=rows+1; pass=pass+dx_row(1, ok, "incumbent raw render unsafe (executes stored XSS = CWE-79)" as *u8) 95 ok = 0; if verdict == XCD_AHEAD { ok = 1 } 96 rows=rows+1; pass=pass+dx_row(2, ok, "measured verdict = AHEAD" as *u8) 97 ok = 0; if xss_our == n_xss { if xss_inc == 0 { if n_xss > 0 { ok = 1 } } } 98 rows=rows+1; pass=pass+dx_row(3, ok, "xss axis: ours neutralizes all payloads, incumbent neutralizes 0" as *u8) 99 ok = 0; if xcd_referee_ok(XCD_AHEAD, our_correct, nc) == 1 { ok = 1 } 100 rows=rows+1; pass=pass+dx_row(4, ok, "referee accepts honest AHEAD claim" as *u8) 101 ok = 0; if xcd_referee_ok(XCD_AHEAD, nc - 1, nc) == 0 { ok = 1 } 102 rows=rows+1; pass=pass+dx_row(5, ok, "referee rejects overclaim (anti-false-green)" as *u8) 103 104 dx_w("CMS-DRAFT-EXCEED-GATE rows=" as *u8); dx_num(rows); dx_w(" pass=" as *u8); dx_num(pass); dx_w("\n" as *u8) 105 106 if pass == rows { 107 if verdict == XCD_AHEAD { 108 if xcd_referee_ok(XCD_AHEAD, our_correct, nc) == 1 { 109 let line: *u8 = sys_mmap(256) 110 var lo: i64 = dx_cat(line, 0, "CMSEXCEED feature=draft-preview axis=xss-sanitization cwe=CWE-79 ours=" as *u8) 111 lo = dx_catnum(line, lo, our_correct); lo = dx_cat(line, lo, "/" as *u8); lo = dx_catnum(line, lo, nc) 112 lo = dx_cat(line, lo, " incumbent=" as *u8); lo = dx_catnum(line, lo, inc_correct); lo = dx_cat(line, lo, "/" as *u8); lo = dx_catnum(line, lo, nc) 113 lo = dx_cat(line, lo, " xss-neutralized=" as *u8); lo = dx_catnum(line, lo, xss_our); lo = dx_cat(line, lo, "/" as *u8); lo = dx_catnum(line, lo, n_xss) 114 lo = dx_cat(line, lo, " verdict=AHEAD\n" as *u8) 115 let gf: i64 = sys_openat_append("knowledge/status/cms_exceed.log" as *u8, 0x1a4) 116 if gf >= 0 { sys_write(gf, line, lo); sys_close(gf) } 117 dx_w("CMS-DRAFT-EXCEED-GATE verdict=AHEAD -- measured EXCEED recorded\n" as *u8) 118 sys_exit(0); return 0 119 } 120 } 121 } 122 dx_w("CMS-DRAFT-EXCEED-GATE verdict=NOT-RECORDED (no fake-green)\n" as *u8) 123 sys_exit(1); return 1 124}