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}