insa-check-core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/LICENSE +24 -0
  2. package/dist/annex-b.d.ts +6 -0
  3. package/dist/annex-b.d.ts.map +1 -0
  4. package/dist/annex-b.js +152 -0
  5. package/dist/annex-b.js.map +1 -0
  6. package/dist/checks/content/page.d.ts +7 -0
  7. package/dist/checks/content/page.d.ts.map +1 -0
  8. package/dist/checks/content/page.js +133 -0
  9. package/dist/checks/content/page.js.map +1 -0
  10. package/dist/checks/cookies/cookie-flags.d.ts +3 -0
  11. package/dist/checks/cookies/cookie-flags.d.ts.map +1 -0
  12. package/dist/checks/cookies/cookie-flags.js +41 -0
  13. package/dist/checks/cookies/cookie-flags.js.map +1 -0
  14. package/dist/checks/cookies/cookie-scope.d.ts +6 -0
  15. package/dist/checks/cookies/cookie-scope.d.ts.map +1 -0
  16. package/dist/checks/cookies/cookie-scope.js +60 -0
  17. package/dist/checks/cookies/cookie-scope.js.map +1 -0
  18. package/dist/checks/deployment/server-banner.d.ts +4 -0
  19. package/dist/checks/deployment/server-banner.d.ts.map +1 -0
  20. package/dist/checks/deployment/server-banner.js +60 -0
  21. package/dist/checks/deployment/server-banner.js.map +1 -0
  22. package/dist/checks/deployment/trace.d.ts +3 -0
  23. package/dist/checks/deployment/trace.d.ts.map +1 -0
  24. package/dist/checks/deployment/trace.js +30 -0
  25. package/dist/checks/deployment/trace.js.map +1 -0
  26. package/dist/checks/headers/clickjacking.d.ts +5 -0
  27. package/dist/checks/headers/clickjacking.d.ts.map +1 -0
  28. package/dist/checks/headers/clickjacking.js +57 -0
  29. package/dist/checks/headers/clickjacking.js.map +1 -0
  30. package/dist/checks/headers/content-type-options.d.ts +3 -0
  31. package/dist/checks/headers/content-type-options.d.ts.map +1 -0
  32. package/dist/checks/headers/content-type-options.js +17 -0
  33. package/dist/checks/headers/content-type-options.js.map +1 -0
  34. package/dist/checks/headers/cors.d.ts +4 -0
  35. package/dist/checks/headers/cors.d.ts.map +1 -0
  36. package/dist/checks/headers/cors.js +38 -0
  37. package/dist/checks/headers/cors.js.map +1 -0
  38. package/dist/checks/html.d.ts +11 -0
  39. package/dist/checks/html.d.ts.map +1 -0
  40. package/dist/checks/html.js +30 -0
  41. package/dist/checks/html.js.map +1 -0
  42. package/dist/checks/index.d.ts +7 -0
  43. package/dist/checks/index.d.ts.map +1 -0
  44. package/dist/checks/index.js +48 -0
  45. package/dist/checks/index.js.map +1 -0
  46. package/dist/checks/info-disclosure/directory-listing.d.ts +6 -0
  47. package/dist/checks/info-disclosure/directory-listing.d.ts.map +1 -0
  48. package/dist/checks/info-disclosure/directory-listing.js +60 -0
  49. package/dist/checks/info-disclosure/directory-listing.js.map +1 -0
  50. package/dist/checks/info-disclosure/exposed-files.d.ts +4 -0
  51. package/dist/checks/info-disclosure/exposed-files.d.ts.map +1 -0
  52. package/dist/checks/info-disclosure/exposed-files.js +56 -0
  53. package/dist/checks/info-disclosure/exposed-files.js.map +1 -0
  54. package/dist/checks/info-disclosure/more.d.ts +8 -0
  55. package/dist/checks/info-disclosure/more.d.ts.map +1 -0
  56. package/dist/checks/info-disclosure/more.js +186 -0
  57. package/dist/checks/info-disclosure/more.js.map +1 -0
  58. package/dist/checks/tls/certificate.d.ts +3 -0
  59. package/dist/checks/tls/certificate.d.ts.map +1 -0
  60. package/dist/checks/tls/certificate.js +49 -0
  61. package/dist/checks/tls/certificate.js.map +1 -0
  62. package/dist/checks/tls/hsts.d.ts +5 -0
  63. package/dist/checks/tls/hsts.d.ts.map +1 -0
  64. package/dist/checks/tls/hsts.js +35 -0
  65. package/dist/checks/tls/hsts.js.map +1 -0
  66. package/dist/checks/tls/https-redirect.d.ts +3 -0
  67. package/dist/checks/tls/https-redirect.d.ts.map +1 -0
  68. package/dist/checks/tls/https-redirect.js +46 -0
  69. package/dist/checks/tls/https-redirect.js.map +1 -0
  70. package/dist/checks/tls/legacy-protocols.d.ts +3 -0
  71. package/dist/checks/tls/legacy-protocols.d.ts.map +1 -0
  72. package/dist/checks/tls/legacy-protocols.js +27 -0
  73. package/dist/checks/tls/legacy-protocols.js.map +1 -0
  74. package/dist/checks/util.d.ts +22 -0
  75. package/dist/checks/util.d.ts.map +1 -0
  76. package/dist/checks/util.js +63 -0
  77. package/dist/checks/util.js.map +1 -0
  78. package/dist/code/checks/crypto.d.ts +5 -0
  79. package/dist/code/checks/crypto.d.ts.map +1 -0
  80. package/dist/code/checks/crypto.js +100 -0
  81. package/dist/code/checks/crypto.js.map +1 -0
  82. package/dist/code/checks/django.d.ts +14 -0
  83. package/dist/code/checks/django.d.ts.map +1 -0
  84. package/dist/code/checks/django.js +313 -0
  85. package/dist/code/checks/django.js.map +1 -0
  86. package/dist/code/checks/flask.d.ts +6 -0
  87. package/dist/code/checks/flask.d.ts.map +1 -0
  88. package/dist/code/checks/flask.js +100 -0
  89. package/dist/code/checks/flask.js.map +1 -0
  90. package/dist/code/checks/index.d.ts +9 -0
  91. package/dist/code/checks/index.d.ts.map +1 -0
  92. package/dist/code/checks/index.js +126 -0
  93. package/dist/code/checks/index.js.map +1 -0
  94. package/dist/code/checks/injection.d.ts +27 -0
  95. package/dist/code/checks/injection.d.ts.map +1 -0
  96. package/dist/code/checks/injection.js +189 -0
  97. package/dist/code/checks/injection.js.map +1 -0
  98. package/dist/code/checks/javascript-config.d.ts +14 -0
  99. package/dist/code/checks/javascript-config.d.ts.map +1 -0
  100. package/dist/code/checks/javascript-config.js +251 -0
  101. package/dist/code/checks/javascript-config.js.map +1 -0
  102. package/dist/code/checks/javascript.d.ts +34 -0
  103. package/dist/code/checks/javascript.d.ts.map +1 -0
  104. package/dist/code/checks/javascript.js +333 -0
  105. package/dist/code/checks/javascript.js.map +1 -0
  106. package/dist/code/checks/php.d.ts +27 -0
  107. package/dist/code/checks/php.d.ts.map +1 -0
  108. package/dist/code/checks/php.js +433 -0
  109. package/dist/code/checks/php.js.map +1 -0
  110. package/dist/code/checks/secrets.d.ts +10 -0
  111. package/dist/code/checks/secrets.d.ts.map +1 -0
  112. package/dist/code/checks/secrets.js +140 -0
  113. package/dist/code/checks/secrets.js.map +1 -0
  114. package/dist/code/checks/shared.d.ts +25 -0
  115. package/dist/code/checks/shared.d.ts.map +1 -0
  116. package/dist/code/checks/shared.js +57 -0
  117. package/dist/code/checks/shared.js.map +1 -0
  118. package/dist/code/checks/treesitter.d.ts +15 -0
  119. package/dist/code/checks/treesitter.d.ts.map +1 -0
  120. package/dist/code/checks/treesitter.js +322 -0
  121. package/dist/code/checks/treesitter.js.map +1 -0
  122. package/dist/code/checks/xml.d.ts +9 -0
  123. package/dist/code/checks/xml.d.ts.map +1 -0
  124. package/dist/code/checks/xml.js +78 -0
  125. package/dist/code/checks/xml.js.map +1 -0
  126. package/dist/code/context.d.ts +6 -0
  127. package/dist/code/context.d.ts.map +1 -0
  128. package/dist/code/context.js +92 -0
  129. package/dist/code/context.js.map +1 -0
  130. package/dist/code/detect.d.ts +3 -0
  131. package/dist/code/detect.d.ts.map +1 -0
  132. package/dist/code/detect.js +118 -0
  133. package/dist/code/detect.js.map +1 -0
  134. package/dist/code/django/settings.d.ts +46 -0
  135. package/dist/code/django/settings.d.ts.map +1 -0
  136. package/dist/code/django/settings.js +154 -0
  137. package/dist/code/django/settings.js.map +1 -0
  138. package/dist/code/findings.d.ts +18 -0
  139. package/dist/code/findings.d.ts.map +1 -0
  140. package/dist/code/findings.js +63 -0
  141. package/dist/code/findings.js.map +1 -0
  142. package/dist/code/javascript/ast.d.ts +46 -0
  143. package/dist/code/javascript/ast.d.ts.map +1 -0
  144. package/dist/code/javascript/ast.js +166 -0
  145. package/dist/code/javascript/ast.js.map +1 -0
  146. package/dist/code/javascript/index.d.ts +3 -0
  147. package/dist/code/javascript/index.d.ts.map +1 -0
  148. package/dist/code/javascript/index.js +3 -0
  149. package/dist/code/javascript/index.js.map +1 -0
  150. package/dist/code/javascript/module.d.ts +59 -0
  151. package/dist/code/javascript/module.d.ts.map +1 -0
  152. package/dist/code/javascript/module.js +250 -0
  153. package/dist/code/javascript/module.js.map +1 -0
  154. package/dist/code/php/index.d.ts +92 -0
  155. package/dist/code/php/index.d.ts.map +1 -0
  156. package/dist/code/php/index.js +316 -0
  157. package/dist/code/php/index.js.map +1 -0
  158. package/dist/code/project.d.ts +13 -0
  159. package/dist/code/project.d.ts.map +1 -0
  160. package/dist/code/project.js +69 -0
  161. package/dist/code/project.js.map +1 -0
  162. package/dist/code/python/ast.d.ts +47 -0
  163. package/dist/code/python/ast.d.ts.map +1 -0
  164. package/dist/code/python/ast.js +193 -0
  165. package/dist/code/python/ast.js.map +1 -0
  166. package/dist/code/python/index.d.ts +3 -0
  167. package/dist/code/python/index.d.ts.map +1 -0
  168. package/dist/code/python/index.js +3 -0
  169. package/dist/code/python/index.js.map +1 -0
  170. package/dist/code/python/module.d.ts +55 -0
  171. package/dist/code/python/module.d.ts.map +1 -0
  172. package/dist/code/python/module.js +215 -0
  173. package/dist/code/python/module.js.map +1 -0
  174. package/dist/code/scan.d.ts +24 -0
  175. package/dist/code/scan.d.ts.map +1 -0
  176. package/dist/code/scan.js +159 -0
  177. package/dist/code/scan.js.map +1 -0
  178. package/dist/code/treesitter/index.d.ts +83 -0
  179. package/dist/code/treesitter/index.d.ts.map +1 -0
  180. package/dist/code/treesitter/index.js +243 -0
  181. package/dist/code/treesitter/index.js.map +1 -0
  182. package/dist/code/types.d.ts +48 -0
  183. package/dist/code/types.d.ts.map +1 -0
  184. package/dist/code/types.js +2 -0
  185. package/dist/code/types.js.map +1 -0
  186. package/dist/content/en.d.ts +3 -0
  187. package/dist/content/en.d.ts.map +1 -0
  188. package/dist/content/en.js +722 -0
  189. package/dist/content/en.js.map +1 -0
  190. package/dist/content/index.d.ts +15 -0
  191. package/dist/content/index.d.ts.map +1 -0
  192. package/dist/content/index.js +21 -0
  193. package/dist/content/index.js.map +1 -0
  194. package/dist/content/types.d.ts +87 -0
  195. package/dist/content/types.d.ts.map +1 -0
  196. package/dist/content/types.js +2 -0
  197. package/dist/content/types.js.map +1 -0
  198. package/dist/engine.d.ts +52 -0
  199. package/dist/engine.d.ts.map +1 -0
  200. package/dist/engine.js +120 -0
  201. package/dist/engine.js.map +1 -0
  202. package/dist/index.d.ts +12 -0
  203. package/dist/index.d.ts.map +1 -0
  204. package/dist/index.js +11 -0
  205. package/dist/index.js.map +1 -0
  206. package/dist/meta.d.ts +4 -0
  207. package/dist/meta.d.ts.map +1 -0
  208. package/dist/meta.js +4 -0
  209. package/dist/meta.js.map +1 -0
  210. package/dist/net/context.d.ts +9 -0
  211. package/dist/net/context.d.ts.map +1 -0
  212. package/dist/net/context.js +62 -0
  213. package/dist/net/context.js.map +1 -0
  214. package/dist/net/guard.d.ts +16 -0
  215. package/dist/net/guard.d.ts.map +1 -0
  216. package/dist/net/guard.js +70 -0
  217. package/dist/net/guard.js.map +1 -0
  218. package/dist/net/http.d.ts +22 -0
  219. package/dist/net/http.d.ts.map +1 -0
  220. package/dist/net/http.js +114 -0
  221. package/dist/net/http.js.map +1 -0
  222. package/dist/net/tls.d.ts +15 -0
  223. package/dist/net/tls.d.ts.map +1 -0
  224. package/dist/net/tls.js +103 -0
  225. package/dist/net/tls.js.map +1 -0
  226. package/dist/report/html.d.ts +14 -0
  227. package/dist/report/html.d.ts.map +1 -0
  228. package/dist/report/html.js +210 -0
  229. package/dist/report/html.js.map +1 -0
  230. package/dist/report/index.d.ts +10 -0
  231. package/dist/report/index.d.ts.map +1 -0
  232. package/dist/report/index.js +10 -0
  233. package/dist/report/index.js.map +1 -0
  234. package/dist/report/manual.d.ts +62 -0
  235. package/dist/report/manual.d.ts.map +1 -0
  236. package/dist/report/manual.js +190 -0
  237. package/dist/report/manual.js.map +1 -0
  238. package/dist/report/merge.d.ts +8 -0
  239. package/dist/report/merge.d.ts.map +1 -0
  240. package/dist/report/merge.js +135 -0
  241. package/dist/report/merge.js.map +1 -0
  242. package/dist/report/summary.d.ts +10 -0
  243. package/dist/report/summary.d.ts.map +1 -0
  244. package/dist/report/summary.js +27 -0
  245. package/dist/report/summary.js.map +1 -0
  246. package/dist/report/validate.d.ts +3 -0
  247. package/dist/report/validate.d.ts.map +1 -0
  248. package/dist/report/validate.js +78 -0
  249. package/dist/report/validate.js.map +1 -0
  250. package/dist/types.d.ts +244 -0
  251. package/dist/types.d.ts.map +1 -0
  252. package/dist/types.js +2 -0
  253. package/dist/types.js.map +1 -0
  254. package/dist/validate.d.ts +4 -0
  255. package/dist/validate.d.ts.map +1 -0
  256. package/dist/validate.js +24 -0
  257. package/dist/validate.js.map +1 -0
  258. package/package.json +40 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-banner.js","sourceRoot":"","sources":["../../../src/checks/deployment/server-banner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Check } from "../../types.js";
2
+ export declare const traceMethod: Check;
3
+ //# sourceMappingURL=trace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../../../src/checks/deployment/trace.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAK5C,eAAO,MAAM,WAAW,EAAE,KA0BzB,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { effectiveOrigin } from "../util.js";
3
+ const MARKER_HEADER = "x-insa-check-trace";
4
+ export const traceMethod = {
5
+ key: "http-trace",
6
+ kind: "url",
7
+ async run(ctx) {
8
+ const origin = await effectiveOrigin(ctx);
9
+ const enabled = [];
10
+ const evidence = [];
11
+ for (const method of ["TRACE", "TRACK"]) {
12
+ const marker = randomBytes(8).toString("hex");
13
+ const res = await ctx.request(`${origin}/`, {
14
+ method,
15
+ followRedirects: false,
16
+ headers: { [MARKER_HEADER]: marker },
17
+ });
18
+ evidence.push(`${method} / → HTTP ${res.status}`);
19
+ // Only an echo of our request proves the method is live (some apps answer 200 to any verb).
20
+ const echoed = res.body.includes(marker) || res.body.startsWith(`${method} /`);
21
+ if (res.status >= 200 && res.status < 300 && echoed)
22
+ enabled.push(method);
23
+ }
24
+ if (enabled.length > 0) {
25
+ return { status: "fail", detail: `${enabled.join(" and ")} enabled: the request is echoed back.`, evidence };
26
+ }
27
+ return { status: "pass", detail: "TRACE and TRACK are not enabled (request not echoed).", evidence };
28
+ },
29
+ };
30
+ //# sourceMappingURL=trace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace.js","sourceRoot":"","sources":["../../../src/checks/deployment/trace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,aAAa,GAAG,oBAAoB,CAAC;AAE3C,MAAM,CAAC,MAAM,WAAW,GAAU;IAChC,GAAG,EAAE,YAAY;IACjB,IAAI,EAAE,KAAK;IACX,KAAK,CAAC,GAAG,CAAC,GAAG;QACX,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,KAAK,MAAM,MAAM,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC9C,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,MAAM,GAAG,EAAE;gBAC1C,MAAM;gBACN,eAAe,EAAE,KAAK;gBACtB,OAAO,EAAE,EAAE,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE;aACrC,CAAC,CAAC;YACH,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;YAClD,4FAA4F;YAC5F,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,MAAM,IAAI,CAAC,CAAC;YAC/E,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,IAAI,MAAM;gBAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5E,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,uCAAuC,EAAE,QAAQ,EAAE,CAAC;QAC/G,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,uDAAuD,EAAE,QAAQ,EAAE,CAAC;IACvG,CAAC;CACF,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { Check } from "../../types.js";
2
+ export declare const clickjacking: Check;
3
+ /** Returns a CSP directive's value ("" if present but empty), or undefined if absent. */
4
+ export declare function cspDirective(policy: string, name: string): string | undefined;
5
+ //# sourceMappingURL=clickjacking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clickjacking.d.ts","sourceRoot":"","sources":["../../../src/checks/headers/clickjacking.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAG5C,eAAO,MAAM,YAAY,EAAE,KA+C1B,CAAC;AAEF,yFAAyF;AACzF,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAM7E"}
@@ -0,0 +1,57 @@
1
+ import { landingPage } from "../util.js";
2
+ export const clickjacking = {
3
+ key: "anti-clickjacking",
4
+ kind: "url",
5
+ async run(ctx) {
6
+ const res = await landingPage(ctx);
7
+ const csp = res.headers["content-security-policy"];
8
+ const xfo = res.headers["x-frame-options"];
9
+ const evidence = [
10
+ csp ? `Content-Security-Policy: ${csp}` : null,
11
+ xfo ? `X-Frame-Options: ${xfo}` : null,
12
+ ].filter((e) => e !== null);
13
+ // CSP frame-ancestors takes precedence over X-Frame-Options in modern browsers.
14
+ // Multiple CSP headers are comma-joined; a frame-ancestors in any of them restricts framing.
15
+ const ancestors = csp
16
+ ?.split(",")
17
+ .map((policy) => cspDirective(policy, "frame-ancestors"))
18
+ .find((v) => v !== undefined);
19
+ if (ancestors !== undefined) {
20
+ const sources = ancestors.split(/\s+/).filter(Boolean);
21
+ const permissive = sources.some((s) => s === "*" || /^(https?|wss?):?$/i.test(s));
22
+ if (permissive) {
23
+ return { status: "fail", detail: `CSP frame-ancestors allows any site to frame the page ("${ancestors}").`, evidence };
24
+ }
25
+ return { status: "pass", detail: `Framing restricted by CSP frame-ancestors ${ancestors || "(none)"}.`, evidence };
26
+ }
27
+ if (!xfo) {
28
+ return {
29
+ status: "fail",
30
+ detail: "Neither X-Frame-Options nor CSP frame-ancestors is set; the page can be framed.",
31
+ evidence,
32
+ };
33
+ }
34
+ const values = xfo.split(",").map((v) => v.trim().toUpperCase());
35
+ if (values.every((v) => v === "DENY" || v === "SAMEORIGIN")) {
36
+ return { status: "pass", detail: `X-Frame-Options: ${values[0]}.`, evidence };
37
+ }
38
+ if (values.some((v) => v.startsWith("ALLOW-FROM"))) {
39
+ return {
40
+ status: "fail",
41
+ detail: "X-Frame-Options ALLOW-FROM is ignored by modern browsers; use CSP frame-ancestors.",
42
+ evidence,
43
+ };
44
+ }
45
+ return { status: "fail", detail: `X-Frame-Options value "${xfo}" is invalid.`, evidence };
46
+ },
47
+ };
48
+ /** Returns a CSP directive's value ("" if present but empty), or undefined if absent. */
49
+ export function cspDirective(policy, name) {
50
+ for (const part of policy.split(";")) {
51
+ const [directive, ...sources] = part.trim().split(/\s+/);
52
+ if (directive?.toLowerCase() === name)
53
+ return sources.join(" ");
54
+ }
55
+ return undefined;
56
+ }
57
+ //# sourceMappingURL=clickjacking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clickjacking.js","sourceRoot":"","sources":["../../../src/checks/headers/clickjacking.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Check } from "../../types.js";
2
+ export declare const contentTypeOptions: Check;
3
+ //# sourceMappingURL=content-type-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-type-options.d.ts","sourceRoot":"","sources":["../../../src/checks/headers/content-type-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAG5C,eAAO,MAAM,kBAAkB,EAAE,KAchC,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { landingPage } from "../util.js";
2
+ export const contentTypeOptions = {
3
+ key: "x-content-type-options",
4
+ kind: "url",
5
+ async run(ctx) {
6
+ const res = await landingPage(ctx);
7
+ const value = res.headers["x-content-type-options"];
8
+ if (!value) {
9
+ return { status: "fail", detail: "X-Content-Type-Options header is missing." };
10
+ }
11
+ if (value.trim().toLowerCase() !== "nosniff") {
12
+ return { status: "fail", detail: `X-Content-Type-Options is "${value}", expected "nosniff".`, evidence: [value] };
13
+ }
14
+ return { status: "pass", detail: "X-Content-Type-Options: nosniff is set.", evidence: [value] };
15
+ },
16
+ };
17
+ //# sourceMappingURL=content-type-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-type-options.js","sourceRoot":"","sources":["../../../src/checks/headers/content-type-options.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,CAAC,MAAM,kBAAkB,GAAU;IACvC,GAAG,EAAE,wBAAwB;IAC7B,IAAI,EAAE,KAAK;IACX,KAAK,CAAC,GAAG,CAAC,GAAG;QACX,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;QACpD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,2CAA2C,EAAE,CAAC;QACjF,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,SAAS,EAAE,CAAC;YAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,8BAA8B,KAAK,wBAAwB,EAAE,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;QACpH,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,yCAAyC,EAAE,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;IAClG,CAAC;CACF,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Check } from "../../types.js";
2
+ /** #98 Insecure cross-domain access policy (CORS, Flash/Silverlight policy files). */
3
+ export declare const crossDomainPolicy: Check;
4
+ //# sourceMappingURL=cors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../../src/checks/headers/cors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAM5C,sFAAsF;AACtF,eAAO,MAAM,iBAAiB,EAAE,KA8B/B,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { effectiveOrigin, landingPage } from "../util.js";
2
+ /** An origin that cannot exist, to see whether the server reflects arbitrary origins. */
3
+ const PROBE_ORIGIN = "https://insa-check-origin.invalid";
4
+ /** #98 Insecure cross-domain access policy (CORS, Flash/Silverlight policy files). */
5
+ export const crossDomainPolicy = {
6
+ key: "cross-domain-policy",
7
+ kind: "url",
8
+ async run(ctx) {
9
+ const origin = await effectiveOrigin(ctx);
10
+ const page = await landingPage(ctx);
11
+ const res = await ctx.request(page.url, { headers: { origin: PROBE_ORIGIN } });
12
+ const acao = res.headers["access-control-allow-origin"];
13
+ const credentials = (res.headers["access-control-allow-credentials"] ?? "").toLowerCase() === "true";
14
+ const problems = [];
15
+ const review = [];
16
+ if (acao === PROBE_ORIGIN || acao === "null") {
17
+ (credentials ? problems : review).push(`Access-Control-Allow-Origin reflects any origin (${acao})${credentials ? " and allows credentials: other sites can read authenticated responses" : ""}`);
18
+ }
19
+ else if (acao === "*" && credentials) {
20
+ problems.push("Access-Control-Allow-Origin: * is combined with Allow-Credentials: true");
21
+ }
22
+ const flash = await ctx.request(`${origin}/crossdomain.xml`, { followRedirects: false });
23
+ if (flash.status === 200 && /<allow-access-from[^>]+domain\s*=\s*["']\*["']/i.test(flash.body))
24
+ problems.push("/crossdomain.xml allows access from any domain");
25
+ const silverlight = await ctx.request(`${origin}/clientaccesspolicy.xml`, { followRedirects: false });
26
+ if (silverlight.status === 200 && /<domain[^>]+uri\s*=\s*["']\*["']/i.test(silverlight.body))
27
+ problems.push("/clientaccesspolicy.xml allows access from any domain");
28
+ if (problems.length)
29
+ return { status: "fail", detail: `${problems.length} insecure cross-domain setting(s).`, evidence: problems };
30
+ if (review.length)
31
+ return { status: "manual", detail: "Any origin may read responses (without credentials). Acceptable only for fully public data.", evidence: review };
32
+ return {
33
+ status: "pass",
34
+ detail: acao === "*" ? "CORS allows any origin without credentials (public data only); no permissive policy files." : "No permissive CORS headers or cross-domain policy files found.",
35
+ };
36
+ },
37
+ };
38
+ //# sourceMappingURL=cors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cors.js","sourceRoot":"","sources":["../../../src/checks/headers/cors.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1D,yFAAyF;AACzF,MAAM,YAAY,GAAG,mCAAmC,CAAC;AAEzD,sFAAsF;AACtF,MAAM,CAAC,MAAM,iBAAiB,GAAU;IACtC,GAAG,EAAE,qBAAqB;IAC1B,IAAI,EAAE,KAAK;IACX,KAAK,CAAC,GAAG,CAAC,GAAG;QACX,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC;QAC/E,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC;QACxD,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,kCAAkC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC;QACrG,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,IAAI,KAAK,YAAY,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YAC7C,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CACpC,oDAAoD,IAAI,IAAI,WAAW,CAAC,CAAC,CAAC,uEAAuE,CAAC,CAAC,CAAC,EAAE,EAAE,CACzJ,CAAC;QACJ,CAAC;aAAM,IAAI,IAAI,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC;YACvC,QAAQ,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAC;QAC3F,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,MAAM,kBAAkB,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;QACzF,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,IAAI,iDAAiD,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;QAChK,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,MAAM,yBAAyB,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;QACtG,IAAI,WAAW,CAAC,MAAM,KAAK,GAAG,IAAI,mCAAmC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC;QAErK,IAAI,QAAQ,CAAC,MAAM;YAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,oCAAoC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;QACnI,IAAI,MAAM,CAAC,MAAM;YAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,6FAA6F,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QACxK,OAAO;YACL,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,4FAA4F,CAAC,CAAC,CAAC,gEAAgE;SACvL,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,11 @@
1
+ /** Minimal HTML helpers for passive checks. Regex-based: good enough to read attributes, not a full parser. */
2
+ export interface Tag {
3
+ name: string;
4
+ attrs: Record<string, string>;
5
+ }
6
+ /** Opening tags of the given names with their attributes (names lower-cased; valueless attributes = ""). */
7
+ export declare function findTags(html: string, names: string[]): Tag[];
8
+ export declare function htmlComments(html: string): string[];
9
+ /** Resolves a possibly relative URL; undefined if it cannot be parsed or is not http(s). */
10
+ export declare function resolveUrl(value: string | undefined, base: string): URL | undefined;
11
+ //# sourceMappingURL=html.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/checks/html.ts"],"names":[],"mappings":"AAAA,+GAA+G;AAE/G,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,4GAA4G;AAC5G,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,GAAG,EAAE,CAW7D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEnD;AAED,4FAA4F;AAC5F,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,CAQnF"}
@@ -0,0 +1,30 @@
1
+ /** Minimal HTML helpers for passive checks. Regex-based: good enough to read attributes, not a full parser. */
2
+ /** Opening tags of the given names with their attributes (names lower-cased; valueless attributes = ""). */
3
+ export function findTags(html, names) {
4
+ const out = [];
5
+ const tagRe = new RegExp(`<(${names.join("|")})\\b([^>]*)>`, "gi");
6
+ for (const m of html.matchAll(tagRe)) {
7
+ const attrs = {};
8
+ for (const a of (m[2] ?? "").matchAll(/([\w:-]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>]+)))?/g)) {
9
+ attrs[a[1].toLowerCase()] = a[2] ?? a[3] ?? a[4] ?? "";
10
+ }
11
+ out.push({ name: m[1].toLowerCase(), attrs });
12
+ }
13
+ return out;
14
+ }
15
+ export function htmlComments(html) {
16
+ return [...html.matchAll(/<!--([\s\S]*?)-->/g)].map((m) => m[1].trim());
17
+ }
18
+ /** Resolves a possibly relative URL; undefined if it cannot be parsed or is not http(s). */
19
+ export function resolveUrl(value, base) {
20
+ if (!value)
21
+ return undefined;
22
+ try {
23
+ const url = new URL(value, base);
24
+ return url.protocol === "http:" || url.protocol === "https:" ? url : undefined;
25
+ }
26
+ catch {
27
+ return undefined;
28
+ }
29
+ }
30
+ //# sourceMappingURL=html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/checks/html.ts"],"names":[],"mappings":"AAAA,+GAA+G;AAO/G,4GAA4G;AAC5G,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,KAAe;IACpD,MAAM,GAAG,GAAU,EAAE,CAAC;IACtB,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;IACnE,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,KAAK,GAA2B,EAAE,CAAC;QACzC,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,2DAA2D,CAAC,EAAE,CAAC;YACnG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1D,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3E,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,UAAU,CAAC,KAAyB,EAAE,IAAY;IAChE,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACjC,OAAO,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IACjF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { Check } from "../types.js";
2
+ /**
3
+ * All automated checks, keyed by Check.key. Annex B items opt in via AnnexItem.check.
4
+ * Tier 2 (code scanning) and Tier 3 (assisted manual) checks register here too.
5
+ */
6
+ export declare const CHECKS: ReadonlyMap<string, Check>;
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/checks/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAiBzC;;;GAGG;AACH,eAAO,MAAM,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,KAAK,CA6B7C,CAAC"}
@@ -0,0 +1,48 @@
1
+ import { cookieHttpOnly, cookieSecure } from "./cookies/cookie-flags.js";
2
+ import { charset, contentType, insecureForms, mixedContent, thirdPartyContent } from "./content/page.js";
3
+ import { cookieDomain, cookiePath } from "./cookies/cookie-scope.js";
4
+ import { serverBanner } from "./deployment/server-banner.js";
5
+ import { traceMethod } from "./deployment/trace.js";
6
+ import { crossDomainPolicy } from "./headers/cors.js";
7
+ import { archivedPages, debugPages, errorMessages, internalAddresses, pageSource, robotsTxt } from "./info-disclosure/more.js";
8
+ import { clickjacking } from "./headers/clickjacking.js";
9
+ import { contentTypeOptions } from "./headers/content-type-options.js";
10
+ import { directoryListing } from "./info-disclosure/directory-listing.js";
11
+ import { exposedFiles } from "./info-disclosure/exposed-files.js";
12
+ import { certificate } from "./tls/certificate.js";
13
+ import { hsts } from "./tls/hsts.js";
14
+ import { httpsRedirect } from "./tls/https-redirect.js";
15
+ import { legacyProtocols } from "./tls/legacy-protocols.js";
16
+ /**
17
+ * All automated checks, keyed by Check.key. Annex B items opt in via AnnexItem.check.
18
+ * Tier 2 (code scanning) and Tier 3 (assisted manual) checks register here too.
19
+ */
20
+ export const CHECKS = new Map([
21
+ httpsRedirect,
22
+ hsts,
23
+ certificate,
24
+ legacyProtocols,
25
+ contentTypeOptions,
26
+ clickjacking,
27
+ cookieSecure,
28
+ cookieHttpOnly,
29
+ traceMethod,
30
+ exposedFiles,
31
+ directoryListing,
32
+ debugPages,
33
+ errorMessages,
34
+ robotsTxt,
35
+ pageSource,
36
+ internalAddresses,
37
+ archivedPages,
38
+ thirdPartyContent,
39
+ insecureForms,
40
+ mixedContent,
41
+ cookieDomain,
42
+ cookiePath,
43
+ contentType,
44
+ charset,
45
+ serverBanner,
46
+ crossDomainPolicy,
47
+ ].map((c) => [c.key, c]));
48
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/checks/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACzG,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,iBAAiB,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC/H,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D;;;GAGG;AACH,MAAM,CAAC,MAAM,MAAM,GAA+B,IAAI,GAAG,CACvD;IACE,aAAa;IACb,IAAI;IACJ,WAAW;IACX,eAAe;IACf,kBAAkB;IAClB,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,WAAW;IACX,YAAY;IACZ,gBAAgB;IAChB,UAAU;IACV,aAAa;IACb,SAAS;IACT,UAAU;IACV,iBAAiB;IACjB,aAAa;IACb,iBAAiB;IACjB,aAAa;IACb,YAAY;IACZ,YAAY;IACZ,UAAU;IACV,WAAW;IACX,OAAO;IACP,YAAY;IACZ,iBAAiB;CAClB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CACzB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { Check } from "../../types.js";
2
+ export declare function isDirectoryListing(body: string): boolean;
3
+ /** Parent directories of same-origin resources referenced by the page, e.g. /static/js/app.js -> /static/js/, /static/. */
4
+ export declare function directoriesFromHtml(html: string, pageUrl: string): string[];
5
+ export declare const directoryListing: Check;
6
+ //# sourceMappingURL=directory-listing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directory-listing.d.ts","sourceRoot":"","sources":["../../../src/checks/info-disclosure/directory-listing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAc5C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,2HAA2H;AAC3H,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAiB3E;AAED,eAAO,MAAM,gBAAgB,EAAE,KA0B9B,CAAC"}
@@ -0,0 +1,60 @@
1
+ import { landingPage } from "../util.js";
2
+ const COMMON_DIRS = ["/images/", "/img/", "/uploads/", "/assets/", "/static/", "/css/", "/js/", "/files/"];
3
+ const MAX_PROBES = 12;
4
+ const LISTING_SIGNATURES = [
5
+ /<title>\s*Index of \//i, // Apache, nginx autoindex
6
+ /<h1>\s*Index of \//i,
7
+ /Directory listing for \//i, // Python http.server
8
+ /<title>\s*Directory Listing For/i, // Tomcat
9
+ /\[To Parent Directory\]/i, // IIS
10
+ ];
11
+ export function isDirectoryListing(body) {
12
+ return LISTING_SIGNATURES.some((re) => re.test(body));
13
+ }
14
+ /** Parent directories of same-origin resources referenced by the page, e.g. /static/js/app.js -> /static/js/, /static/. */
15
+ export function directoriesFromHtml(html, pageUrl) {
16
+ const base = new URL(pageUrl);
17
+ const dirs = new Set();
18
+ for (const match of html.matchAll(/(?:src|href)\s*=\s*["']([^"'#?]+)/gi)) {
19
+ let url;
20
+ try {
21
+ url = new URL(match[1], base);
22
+ }
23
+ catch {
24
+ continue;
25
+ }
26
+ if (url.origin !== base.origin)
27
+ continue;
28
+ const segments = url.pathname.split("/").slice(1, -1);
29
+ for (let i = segments.length; i > 0; i--) {
30
+ dirs.add(`/${segments.slice(0, i).join("/")}/`);
31
+ }
32
+ }
33
+ return [...dirs];
34
+ }
35
+ export const directoryListing = {
36
+ key: "directory-listing",
37
+ kind: "url",
38
+ async run(ctx) {
39
+ const page = await landingPage(ctx);
40
+ const origin = new URL(page.url).origin;
41
+ const candidates = [...new Set([...directoriesFromHtml(page.body, page.url), ...COMMON_DIRS])].slice(0, MAX_PROBES);
42
+ const listed = [];
43
+ if (isDirectoryListing(page.body))
44
+ listed.push(page.url);
45
+ await Promise.all(candidates.map(async (dir) => {
46
+ const res = await ctx.request(`${origin}${dir}`);
47
+ if (res.status === 200 && isDirectoryListing(res.body))
48
+ listed.push(`${origin}${dir}`);
49
+ }));
50
+ if (listed.length > 0) {
51
+ return { status: "fail", detail: `Directory listing is enabled on ${listed.length} path(s).`, evidence: listed.sort() };
52
+ }
53
+ return {
54
+ status: "pass",
55
+ detail: `No directory listing found on ${candidates.length + 1} paths checked.`,
56
+ evidence: candidates,
57
+ };
58
+ },
59
+ };
60
+ //# sourceMappingURL=directory-listing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directory-listing.js","sourceRoot":"","sources":["../../../src/checks/info-disclosure/directory-listing.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,WAAW,GAAG,CAAC,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;AAC3G,MAAM,UAAU,GAAG,EAAE,CAAC;AAEtB,MAAM,kBAAkB,GAAG;IACzB,wBAAwB,EAAE,0BAA0B;IACpD,qBAAqB;IACrB,2BAA2B,EAAE,qBAAqB;IAClD,kCAAkC,EAAE,SAAS;IAC7C,0BAA0B,EAAE,MAAM;CACnC,CAAC;AAEF,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AACxD,CAAC;AAED,2HAA2H;AAC3H,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,OAAe;IAC/D,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,qCAAqC,CAAC,EAAE,CAAC;QACzE,IAAI,GAAQ,CAAC;QACb,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAE,EAAE,IAAI,CAAC,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM;YAAE,SAAS;QACzC,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACtD,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAU;IACrC,GAAG,EAAE,mBAAmB;IACxB,IAAI,EAAE,KAAK;IACX,KAAK,CAAC,GAAG,CAAC,GAAG;QACX,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;QACxC,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,mBAAmB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QAEpH,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzD,MAAM,OAAO,CAAC,GAAG,CACf,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YAC3B,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC;YACjD,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC;QACzF,CAAC,CAAC,CACH,CAAC;QAEF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,mCAAmC,MAAM,CAAC,MAAM,WAAW,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QAC1H,CAAC;QACD,OAAO;YACL,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,iCAAiC,UAAU,CAAC,MAAM,GAAG,CAAC,iBAAiB;YAC/E,QAAQ,EAAE,UAAU;SACrB,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Check } from "../../types.js";
2
+ export declare const EXPOSED_FILE_PATHS: string[];
3
+ export declare const exposedFiles: Check;
4
+ //# sourceMappingURL=exposed-files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exposed-files.d.ts","sourceRoot":"","sources":["../../../src/checks/info-disclosure/exposed-files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAgD5C,eAAO,MAAM,kBAAkB,UAA4B,CAAC;AAE5D,eAAO,MAAM,YAAY,EAAE,KAmB1B,CAAC"}
@@ -0,0 +1,56 @@
1
+ import { effectiveOrigin } from "../util.js";
2
+ const PROBES = [
3
+ {
4
+ path: "/.git/HEAD",
5
+ matches: (b) => /^(ref: refs\/|[0-9a-f]{40}\s*$)/.test(b),
6
+ describe: () => "Git repository metadata (HEAD) is downloadable",
7
+ },
8
+ {
9
+ path: "/.git/config",
10
+ matches: (b) => /^\s*\[core\]/m.test(b),
11
+ describe: () => "Git repository config is downloadable",
12
+ },
13
+ {
14
+ path: "/.env",
15
+ matches: (b) => !/^\s*</.test(b) && envAssignments(b) >= 2,
16
+ describe: (b) => `Environment file with ${envAssignments(b)} variable assignments (values not shown)`,
17
+ },
18
+ {
19
+ path: "/.svn/wc.db",
20
+ matches: (b) => b.startsWith("SQLite format 3"),
21
+ describe: () => "Subversion working-copy database is downloadable",
22
+ },
23
+ {
24
+ path: "/.DS_Store",
25
+ matches: (b) => b.slice(0, 8).includes("Bud1"),
26
+ describe: () => "macOS .DS_Store (reveals file names) is downloadable",
27
+ },
28
+ {
29
+ path: "/.htpasswd",
30
+ matches: (b) => !/^\s*</.test(b) && /^[^:\s]+:(\$|\{SHA\}|[./0-9A-Za-z]{13}$)/m.test(b),
31
+ describe: () => "Password hash file .htpasswd is downloadable",
32
+ },
33
+ ];
34
+ function envAssignments(body) {
35
+ return body.split("\n").filter((line) => /^\s*(export\s+)?[A-Za-z_][A-Za-z0-9_]*\s*=/.test(line)).length;
36
+ }
37
+ export const EXPOSED_FILE_PATHS = PROBES.map((p) => p.path);
38
+ export const exposedFiles = {
39
+ key: "exposed-files",
40
+ kind: "url",
41
+ async run(ctx) {
42
+ const origin = await effectiveOrigin(ctx);
43
+ const findings = [];
44
+ await Promise.all(PROBES.map(async (probe) => {
45
+ const res = await ctx.request(`${origin}${probe.path}`, { followRedirects: false });
46
+ if (res.status === 200 && probe.matches(res.body)) {
47
+ findings.push(`${origin}${probe.path}: ${probe.describe(res.body)}`);
48
+ }
49
+ }));
50
+ if (findings.length > 0) {
51
+ return { status: "fail", detail: `${findings.length} sensitive file(s) are publicly accessible.`, evidence: findings.sort() };
52
+ }
53
+ return { status: "pass", detail: `None of ${EXPOSED_FILE_PATHS.join(", ")} are exposed.` };
54
+ },
55
+ };
56
+ //# sourceMappingURL=exposed-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exposed-files.js","sourceRoot":"","sources":["../../../src/checks/info-disclosure/exposed-files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { Check } from "../../types.js";
2
+ export declare const debugPages: Check;
3
+ export declare const errorMessages: Check;
4
+ export declare const robotsTxt: Check;
5
+ export declare const pageSource: Check;
6
+ export declare const internalAddresses: Check;
7
+ export declare const archivedPages: Check;
8
+ //# sourceMappingURL=more.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"more.d.ts","sourceRoot":"","sources":["../../../src/checks/info-disclosure/more.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAsB5C,eAAO,MAAM,UAAU,EAAE,KAexB,CAAC;AAgBF,eAAO,MAAM,aAAa,EAAE,KAgB3B,CAAC;AAMF,eAAO,MAAM,SAAS,EAAE,KAoBvB,CAAC;AAoBF,eAAO,MAAM,UAAU,EAAE,KA6BxB,CAAC;AAMF,eAAO,MAAM,iBAAiB,EAAE,KAmB/B,CAAC;AAGF,eAAO,MAAM,aAAa,EAAE,KAY3B,CAAC"}