code wiki / (root) / nx_http_security_headers_test.nx

nx_http_security_headers_test.nx source

↩ module page · 167 lines · 7088 B

1// nx_http_security_headers_test.nx -- smoke for production header set. 2// 3// expect_exit: 0 4// 5// license_tier: ORIGINAL 6 7import "nx_syscalls_x86_64.nx" 8import "nx_http_security_headers.nx" 9 10func bytes_eq(a: *u8, b: *u8, n: i64) -> i64 { 11 var i: i64 = 0 12 while i < n { 13 if a[i] != b[i] { return 0 } 14 i = i + 1 15 } 16 return 1 17} 18 19func bytes_contains(haystack: *u8, h_n: i64, needle: *u8, n_n: i64) -> i64 { 20 if n_n > h_n { return 0 } 21 var i: i64 = 0 22 while i <= h_n - n_n { 23 if bytes_eq(((haystack as i64) + i) as *u8, needle, n_n) == 1 { return 1 } 24 i = i + 1 25 } 26 return 0 27} 28 29func main() -> i64 { 30 // ---- Verdict + level enum gates ---- 31 if nxsh_verdict_is_valid(NXSH_OK) != 1 { return 1 } 32 if nxsh_verdict_is_valid(NXSH_VERDICT_N) != 0 { return 2 } 33 if nxsh_level_is_valid(NXSH_STRICT) != 1 { return 3 } 34 if nxsh_level_is_valid(NXSH_LEVEL_N) != 0 { return 4 } 35 36 if bytes_eq(nxsh_level_name(NXSH_STRICT), "STRICT" as *u8, 6) != 1 { return 5 } 37 if bytes_eq(nxsh_level_name(NXSH_MODERATE), "MODERATE" as *u8, 8) != 1 { return 6 } 38 if bytes_eq(nxsh_level_name(NXSH_PERMISSIVE), "PERMISSIVE" as *u8, 10) != 1 { return 7 } 39 40 let buf: *u8 = sys_mmap(2048) 41 let off: *i64 = sys_mmap(8) as *i64 42 43 // ---- CSP STRICT ---- 44 off[0] = 0 45 if nx_http_emit_csp(buf, off, 2048, NXSH_STRICT) != NXSH_OK { return 10 } 46 if bytes_contains(buf, off[0], 47 "Content-Security-Policy: default-src 'none'" as *u8, 43) != 1 { return 11 } 48 if bytes_contains(buf, off[0], 49 "frame-ancestors 'none'" as *u8, 22) != 1 { return 12 } 50 51 // ---- CSP MODERATE ---- 52 off[0] = 0 53 if nx_http_emit_csp(buf, off, 2048, NXSH_MODERATE) != NXSH_OK { return 13 } 54 if bytes_contains(buf, off[0], 55 "default-src 'self'" as *u8, 18) != 1 { return 14 } 56 if bytes_contains(buf, off[0], 57 "'unsafe-inline'" as *u8, 15) != 1 { return 15 } 58 59 // ---- CSP PERMISSIVE ---- 60 off[0] = 0 61 if nx_http_emit_csp(buf, off, 2048, NXSH_PERMISSIVE) != NXSH_OK { return 16 } 62 if bytes_contains(buf, off[0], 63 "Content-Security-Policy: default-src 'self'" as *u8, 43) != 1 { return 17 } 64 65 // ---- BAD_LEVEL ---- 66 off[0] = 0 67 if nx_http_emit_csp(buf, off, 2048, 99) != NXSH_BAD_LEVEL { return 18 } 68 69 // ---- X-Frame-Options STRICT -> DENY ---- 70 off[0] = 0 71 if nx_http_emit_x_frame_options(buf, off, 2048, NXSH_STRICT) != NXSH_OK { return 20 } 72 if bytes_contains(buf, off[0], 73 "X-Frame-Options: DENY\r\n" as *u8, 23) != 1 { return 21 } 74 75 // ---- X-Frame-Options MODERATE -> SAMEORIGIN ---- 76 off[0] = 0 77 if nx_http_emit_x_frame_options(buf, off, 2048, NXSH_MODERATE) != NXSH_OK { return 22 } 78 if bytes_contains(buf, off[0], 79 "X-Frame-Options: SAMEORIGIN\r\n" as *u8, 29) != 1 { return 23 } 80 81 // ---- X-Frame-Options PERMISSIVE -> header omitted ---- 82 off[0] = 0 83 if nx_http_emit_x_frame_options(buf, off, 2048, NXSH_PERMISSIVE) != NXSH_OK { return 24 } 84 if off[0] != 0 { return 25 } 85 86 // ---- X-Content-Type-Options ---- 87 off[0] = 0 88 if nx_http_emit_x_content_type_options(buf, off, 2048) != NXSH_OK { return 30 } 89 if bytes_contains(buf, off[0], 90 "X-Content-Type-Options: nosniff\r\n" as *u8, 33) != 1 { return 31 } 91 92 // ---- Referrer-Policy STRICT -> no-referrer ---- 93 off[0] = 0 94 if nx_http_emit_referrer_policy(buf, off, 2048, NXSH_STRICT) != NXSH_OK { return 40 } 95 if bytes_contains(buf, off[0], 96 "Referrer-Policy: no-referrer\r\n" as *u8, 30) != 1 { return 41 } 97 98 // ---- Referrer-Policy MODERATE -> strict-origin-when-cross-origin ---- 99 off[0] = 0 100 if nx_http_emit_referrer_policy(buf, off, 2048, NXSH_MODERATE) != NXSH_OK { return 42 } 101 if bytes_contains(buf, off[0], 102 "strict-origin-when-cross-origin" as *u8, 31) != 1 { return 43 } 103 104 // ---- Permissions-Policy STRICT -> deny all ---- 105 off[0] = 0 106 if nx_http_emit_permissions_policy(buf, off, 2048, NXSH_STRICT) != NXSH_OK { return 50 } 107 if bytes_contains(buf, off[0], 108 "Permissions-Policy: camera=()" as *u8, 29) != 1 { return 51 } 109 if bytes_contains(buf, off[0], 110 "microphone=()" as *u8, 13) != 1 { return 52 } 111 if bytes_contains(buf, off[0], 112 "geolocation=()" as *u8, 14) != 1 { return 53 } 113 114 // ---- Permissions-Policy PERMISSIVE -> header omitted ---- 115 off[0] = 0 116 if nx_http_emit_permissions_policy(buf, off, 2048, NXSH_PERMISSIVE) != NXSH_OK { return 54 } 117 if off[0] != 0 { return 55 } 118 119 // ---- HSTS ---- 120 off[0] = 0 121 if nx_http_emit_hsts(buf, off, 2048, 31536000, 1) != NXSH_OK { return 60 } 122 if bytes_contains(buf, off[0], 123 "Strict-Transport-Security: max-age=31536000; includeSubDomains\r\n" as *u8, 64) != 1 { return 61 } 124 125 // HSTS without subdomains 126 off[0] = 0 127 if nx_http_emit_hsts(buf, off, 2048, 60, 0) != NXSH_OK { return 62 } 128 if bytes_contains(buf, off[0], 129 "max-age=60\r\n" as *u8, 12) != 1 { return 63 } 130 // Verify NO "includeSubDomains" present 131 if bytes_contains(buf, off[0], 132 "includeSubDomains" as *u8, 17) != 0 { return 64 } 133 134 // ---- DNS-prefetch off ---- 135 off[0] = 0 136 if nx_http_emit_dns_prefetch_off(buf, off, 2048) != NXSH_OK { return 70 } 137 if bytes_contains(buf, off[0], 138 "X-DNS-Prefetch-Control: off\r\n" as *u8, 29) != 1 { return 71 } 139 140 // ---- Bundle (all-secure-defaults) ---- 141 off[0] = 0 142 if nx_http_emit_security_headers_bundle(buf, off, 2048, NXSH_STRICT) != NXSH_OK { return 80 } 143 // All 7 headers should be present: 144 if bytes_contains(buf, off[0], 145 "Content-Security-Policy:" as *u8, 24) != 1 { return 81 } 146 if bytes_contains(buf, off[0], 147 "X-Frame-Options: DENY" as *u8, 21) != 1 { return 82 } 148 if bytes_contains(buf, off[0], 149 "X-Content-Type-Options: nosniff" as *u8, 31) != 1 { return 83 } 150 if bytes_contains(buf, off[0], 151 "Referrer-Policy: no-referrer" as *u8, 28) != 1 { return 84 } 152 if bytes_contains(buf, off[0], 153 "Permissions-Policy:" as *u8, 19) != 1 { return 85 } 154 if bytes_contains(buf, off[0], 155 "X-DNS-Prefetch-Control: off" as *u8, 27) != 1 { return 86 } 156 if bytes_contains(buf, off[0], 157 "Strict-Transport-Security: max-age=31536000" as *u8, 43) != 1 { return 87 } 158 159 // ---- BAD_ARG ---- 160 off[0] = 0 161 if nx_http_emit_security_headers_bundle(0 as *u8, off, 2048, NXSH_STRICT) != NXSH_BAD_ARG { return 90 } 162 if nx_http_emit_security_headers_bundle(buf, 0 as *i64, 2048, NXSH_STRICT) != NXSH_BAD_ARG { return 91 } 163 if nx_http_emit_security_headers_bundle(buf, off, 0, NXSH_STRICT) != NXSH_BAD_ARG { return 92 } 164 if nx_http_emit_security_headers_bundle(buf, off, 2048, 99) != NXSH_BAD_LEVEL { return 93 } 165 166 return 0 167}