haris 0.7.0__tar.gz

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 (505) hide show
  1. haris-0.7.0/LICENSE +21 -0
  2. haris-0.7.0/PKG-INFO +253 -0
  3. haris-0.7.0/README.md +212 -0
  4. haris-0.7.0/pyproject.toml +138 -0
  5. haris-0.7.0/setup.cfg +4 -0
  6. haris-0.7.0/src/haris/__init__.py +6 -0
  7. haris-0.7.0/src/haris/__main__.py +5 -0
  8. haris-0.7.0/src/haris/agent/__init__.py +21 -0
  9. haris-0.7.0/src/haris/agent/audit.py +67 -0
  10. haris-0.7.0/src/haris/agent/budget.py +52 -0
  11. haris-0.7.0/src/haris/agent/coordinator.py +253 -0
  12. haris-0.7.0/src/haris/agent/docker_runtime.py +403 -0
  13. haris-0.7.0/src/haris/agent/guardrails.py +176 -0
  14. haris-0.7.0/src/haris/agent/models.py +43 -0
  15. haris-0.7.0/src/haris/agent/policy.py +127 -0
  16. haris-0.7.0/src/haris/agent/prompts.py +17 -0
  17. haris-0.7.0/src/haris/agent/proxy.py +309 -0
  18. haris-0.7.0/src/haris/agent/proxy_auth.py +26 -0
  19. haris-0.7.0/src/haris/agent/runtime.py +133 -0
  20. haris-0.7.0/src/haris/agent/settings.py +45 -0
  21. haris-0.7.0/src/haris/agent/stages.py +5 -0
  22. haris-0.7.0/src/haris/agent/turn.py +118 -0
  23. haris-0.7.0/src/haris/agent/validator.py +121 -0
  24. haris-0.7.0/src/haris/ai_security/__init__.py +3 -0
  25. haris-0.7.0/src/haris/ai_security/active.py +294 -0
  26. haris-0.7.0/src/haris/ai_security/adapters.py +151 -0
  27. haris-0.7.0/src/haris/ai_security/body_validators.py +174 -0
  28. haris-0.7.0/src/haris/ai_security/bundles.py +47 -0
  29. haris-0.7.0/src/haris/ai_security/discovery.py +94 -0
  30. haris-0.7.0/src/haris/ai_security/findings.py +81 -0
  31. haris-0.7.0/src/haris/ai_security/mcp_probe.py +133 -0
  32. haris-0.7.0/src/haris/ai_security/mcp_static.py +169 -0
  33. haris-0.7.0/src/haris/ai_security/options.py +37 -0
  34. haris-0.7.0/src/haris/ai_security/owasp_ai.py +86 -0
  35. haris-0.7.0/src/haris/ai_security/passive.py +275 -0
  36. haris-0.7.0/src/haris/ai_security/probes.py +82 -0
  37. haris-0.7.0/src/haris/ai_security/rpc.py +64 -0
  38. haris-0.7.0/src/haris/ai_security/scanner.py +70 -0
  39. haris-0.7.0/src/haris/ai_security/signatures.py +67 -0
  40. haris-0.7.0/src/haris/auth/__init__.py +0 -0
  41. haris-0.7.0/src/haris/auth/api_tokens.py +63 -0
  42. haris-0.7.0/src/haris/auth/audit.py +54 -0
  43. haris-0.7.0/src/haris/auth/bearer.py +57 -0
  44. haris-0.7.0/src/haris/auth/bootstrap.py +37 -0
  45. haris-0.7.0/src/haris/auth/config.py +87 -0
  46. haris-0.7.0/src/haris/auth/cookies.py +47 -0
  47. haris-0.7.0/src/haris/auth/csrf.py +65 -0
  48. haris-0.7.0/src/haris/auth/database.py +49 -0
  49. haris-0.7.0/src/haris/auth/email.py +100 -0
  50. haris-0.7.0/src/haris/auth/middleware.py +75 -0
  51. haris-0.7.0/src/haris/auth/models.py +104 -0
  52. haris-0.7.0/src/haris/auth/oidc.py +115 -0
  53. haris-0.7.0/src/haris/auth/public.py +16 -0
  54. haris-0.7.0/src/haris/auth/redirects.py +38 -0
  55. haris-0.7.0/src/haris/auth/security_headers.py +72 -0
  56. haris-0.7.0/src/haris/auth/service.py +276 -0
  57. haris-0.7.0/src/haris/auth/tokens.py +5 -0
  58. haris-0.7.0/src/haris/auth/users.py +167 -0
  59. haris-0.7.0/src/haris/auth/verification.py +94 -0
  60. haris-0.7.0/src/haris/bench/__init__.py +0 -0
  61. haris-0.7.0/src/haris/bench/__main__.py +49 -0
  62. haris-0.7.0/src/haris/bench/render.py +34 -0
  63. haris-0.7.0/src/haris/bench/score.py +205 -0
  64. haris-0.7.0/src/haris/bench/truth.py +87 -0
  65. haris-0.7.0/src/haris/checks/__init__.py +35 -0
  66. haris-0.7.0/src/haris/checks/baseline.py +243 -0
  67. haris-0.7.0/src/haris/checks/cache_checks.py +67 -0
  68. haris-0.7.0/src/haris/checks/cookie_checks.py +259 -0
  69. haris-0.7.0/src/haris/checks/cookie_policy.py +79 -0
  70. haris-0.7.0/src/haris/checks/dns_checks.py +164 -0
  71. haris-0.7.0/src/haris/checks/dns_wire.py +123 -0
  72. haris-0.7.0/src/haris/checks/findings.py +30 -0
  73. haris-0.7.0/src/haris/checks/graphql_checks.py +82 -0
  74. haris-0.7.0/src/haris/checks/header_checks.py +231 -0
  75. haris-0.7.0/src/haris/checks/header_policy.py +175 -0
  76. haris-0.7.0/src/haris/checks/info_disclosure.py +229 -0
  77. haris-0.7.0/src/haris/checks/info_patterns.py +142 -0
  78. haris-0.7.0/src/haris/checks/listing_checks.py +75 -0
  79. haris-0.7.0/src/haris/checks/method_checks.py +76 -0
  80. haris-0.7.0/src/haris/checks/misc_checks.py +239 -0
  81. haris-0.7.0/src/haris/checks/openapi_checks.py +67 -0
  82. haris-0.7.0/src/haris/checks/path_probe.py +50 -0
  83. haris-0.7.0/src/haris/checks/probe_scanner.py +26 -0
  84. haris-0.7.0/src/haris/checks/redirect_checks.py +80 -0
  85. haris-0.7.0/src/haris/checks/requesting.py +66 -0
  86. haris-0.7.0/src/haris/checks/sri_checks.py +87 -0
  87. haris-0.7.0/src/haris/checks/tls_checks.py +218 -0
  88. haris-0.7.0/src/haris/checks/tls_probe.py +150 -0
  89. haris-0.7.0/src/haris/checks/validators.py +173 -0
  90. haris-0.7.0/src/haris/cli.py +648 -0
  91. haris-0.7.0/src/haris/config/__init__.py +6 -0
  92. haris-0.7.0/src/haris/config/loader.py +201 -0
  93. haris-0.7.0/src/haris/config/paths.py +14 -0
  94. haris-0.7.0/src/haris/core/__init__.py +71 -0
  95. haris-0.7.0/src/haris/core/confidence.py +76 -0
  96. haris-0.7.0/src/haris/core/context_extract.py +89 -0
  97. haris-0.7.0/src/haris/core/correlator.py +64 -0
  98. haris-0.7.0/src/haris/core/decorators.py +105 -0
  99. haris-0.7.0/src/haris/core/engine.py +378 -0
  100. haris-0.7.0/src/haris/core/exit_codes.py +24 -0
  101. haris-0.7.0/src/haris/core/identity.py +93 -0
  102. haris-0.7.0/src/haris/core/llm_enrichment.py +83 -0
  103. haris-0.7.0/src/haris/core/owasp.py +222 -0
  104. haris-0.7.0/src/haris/core/profiles.py +193 -0
  105. haris-0.7.0/src/haris/core/remediation.py +119 -0
  106. haris-0.7.0/src/haris/core/risk.py +221 -0
  107. haris-0.7.0/src/haris/core/runner.py +218 -0
  108. haris-0.7.0/src/haris/core/scanner.py +141 -0
  109. haris-0.7.0/src/haris/core/tool_vet.py +35 -0
  110. haris-0.7.0/src/haris/core/vuln_class.py +66 -0
  111. haris-0.7.0/src/haris/data/__init__.py +1 -0
  112. haris-0.7.0/src/haris/data/scanner_config.py +305 -0
  113. haris-0.7.0/src/haris/db/__init__.py +5 -0
  114. haris-0.7.0/src/haris/db/api_tokens.py +86 -0
  115. haris-0.7.0/src/haris/db/baseline.py +236 -0
  116. haris-0.7.0/src/haris/db/connection.py +22 -0
  117. haris-0.7.0/src/haris/db/findings.py +48 -0
  118. haris-0.7.0/src/haris/db/jobs.py +166 -0
  119. haris-0.7.0/src/haris/db/llm_data.py +119 -0
  120. haris-0.7.0/src/haris/db/migrate.py +70 -0
  121. haris-0.7.0/src/haris/db/migrations/0001_baseline.py +5 -0
  122. haris-0.7.0/src/haris/db/migrations/0002_hash_tokens.py +21 -0
  123. haris-0.7.0/src/haris/db/migrations/0003_finding_identity.py +77 -0
  124. haris-0.7.0/src/haris/db/migrations/0004_scan_owner_state.py +33 -0
  125. haris-0.7.0/src/haris/db/migrations/0005_api_tokens.py +30 -0
  126. haris-0.7.0/src/haris/db/migrations/0006_authorized_targets.py +26 -0
  127. haris-0.7.0/src/haris/db/migrations/0007_job_queue.py +29 -0
  128. haris-0.7.0/src/haris/db/migrations/0008_agent_fields.py +20 -0
  129. haris-0.7.0/src/haris/db/scans.py +162 -0
  130. haris-0.7.0/src/haris/db/session_read.py +180 -0
  131. haris-0.7.0/src/haris/db/session_write.py +163 -0
  132. haris-0.7.0/src/haris/db/store.py +149 -0
  133. haris-0.7.0/src/haris/db/targets.py +73 -0
  134. haris-0.7.0/src/haris/db/template_defaults.py +144 -0
  135. haris-0.7.0/src/haris/db/templates.py +157 -0
  136. haris-0.7.0/src/haris/db/websites.py +194 -0
  137. haris-0.7.0/src/haris/diff.py +154 -0
  138. haris-0.7.0/src/haris/ignore.py +111 -0
  139. haris-0.7.0/src/haris/llm/__init__.py +28 -0
  140. haris-0.7.0/src/haris/llm/backend.py +239 -0
  141. haris-0.7.0/src/haris/llm/base.py +88 -0
  142. haris-0.7.0/src/haris/llm/budget.py +106 -0
  143. haris-0.7.0/src/haris/llm/catalog.py +86 -0
  144. haris-0.7.0/src/haris/llm/correlation.py +77 -0
  145. haris-0.7.0/src/haris/llm/enrichment.py +117 -0
  146. haris-0.7.0/src/haris/llm/enrichment_prompts.py +86 -0
  147. haris-0.7.0/src/haris/llm/parsing.py +84 -0
  148. haris-0.7.0/src/haris/llm/prompts.py +253 -0
  149. haris-0.7.0/src/haris/llm/providers.py +221 -0
  150. haris-0.7.0/src/haris/llm/qa.py +249 -0
  151. haris-0.7.0/src/haris/llm/redaction.py +75 -0
  152. haris-0.7.0/src/haris/llm/retriever.py +113 -0
  153. haris-0.7.0/src/haris/llm/retry.py +92 -0
  154. haris-0.7.0/src/haris/llm/router.py +70 -0
  155. haris-0.7.0/src/haris/llm/schemas.py +91 -0
  156. haris-0.7.0/src/haris/llm/settings.py +98 -0
  157. haris-0.7.0/src/haris/llm/structured.py +117 -0
  158. haris-0.7.0/src/haris/llm/template_loader.py +47 -0
  159. haris-0.7.0/src/haris/llm/templates/enrichment/assess_false_positives.j2 +22 -0
  160. haris-0.7.0/src/haris/llm/templates/enrichment/enrich_finding.j2 +33 -0
  161. haris-0.7.0/src/haris/llm/templates/enrichment/identify_attack_chains.j2 +23 -0
  162. haris-0.7.0/src/haris/llm/templates/enrichment/suggest_variants.j2 +26 -0
  163. haris-0.7.0/src/haris/llm/templates/enrichment/system.j2 +7 -0
  164. haris-0.7.0/src/haris/llm/templates/enrichment/triage_findings.j2 +24 -0
  165. haris-0.7.0/src/haris/llm/templates/qa/explain_finding.j2 +12 -0
  166. haris-0.7.0/src/haris/llm/templates/qa/filter_and_explain.j2 +12 -0
  167. haris-0.7.0/src/haris/llm/templates/qa/freeform_question.j2 +6 -0
  168. haris-0.7.0/src/haris/llm/templates/qa/generate_test_cases.j2 +12 -0
  169. haris-0.7.0/src/haris/llm/templates/qa/remediation_plan.j2 +4 -0
  170. haris-0.7.0/src/haris/llm/templates/qa/suggest_mitigations.j2 +12 -0
  171. haris-0.7.0/src/haris/llm/templates/qa/summarize_report.j2 +4 -0
  172. haris-0.7.0/src/haris/llm/templates/qa/system.j2 +8 -0
  173. haris-0.7.0/src/haris/llm/triage.py +97 -0
  174. haris-0.7.0/src/haris/llm/variant_analysis.py +76 -0
  175. haris-0.7.0/src/haris/models/__init__.py +89 -0
  176. haris-0.7.0/src/haris/models/chat.py +41 -0
  177. haris-0.7.0/src/haris/models/config.py +62 -0
  178. haris-0.7.0/src/haris/models/correlator.py +25 -0
  179. haris-0.7.0/src/haris/models/enrichment.py +69 -0
  180. haris-0.7.0/src/haris/models/enums.py +131 -0
  181. haris-0.7.0/src/haris/models/finding.py +131 -0
  182. haris-0.7.0/src/haris/models/llm.py +18 -0
  183. haris-0.7.0/src/haris/models/owasp.py +67 -0
  184. haris-0.7.0/src/haris/models/profiles.py +18 -0
  185. haris-0.7.0/src/haris/models/remediation.py +36 -0
  186. haris-0.7.0/src/haris/models/risk.py +12 -0
  187. haris-0.7.0/src/haris/models/scan_config_template.py +60 -0
  188. haris-0.7.0/src/haris/models/scan_context.py +63 -0
  189. haris-0.7.0/src/haris/models/scanner.py +21 -0
  190. haris-0.7.0/src/haris/models/session.py +121 -0
  191. haris-0.7.0/src/haris/models/target.py +230 -0
  192. haris-0.7.0/src/haris/models/templates.py +82 -0
  193. haris-0.7.0/src/haris/models/verification.py +69 -0
  194. haris-0.7.0/src/haris/net/__init__.py +26 -0
  195. haris-0.7.0/src/haris/net/errors.py +18 -0
  196. haris-0.7.0/src/haris/net/policy.py +22 -0
  197. haris-0.7.0/src/haris/net/ratelimit.py +53 -0
  198. haris-0.7.0/src/haris/net/redact.py +16 -0
  199. haris-0.7.0/src/haris/net/requestlog.py +76 -0
  200. haris-0.7.0/src/haris/net/retry.py +20 -0
  201. haris-0.7.0/src/haris/net/scoped_client.py +348 -0
  202. haris-0.7.0/src/haris/net/ssrf.py +86 -0
  203. haris-0.7.0/src/haris/net/transport.py +108 -0
  204. haris-0.7.0/src/haris/reporting/__init__.py +65 -0
  205. haris-0.7.0/src/haris/reporting/base.py +28 -0
  206. haris-0.7.0/src/haris/reporting/csv_report.py +59 -0
  207. haris-0.7.0/src/haris/reporting/escape.py +43 -0
  208. haris-0.7.0/src/haris/reporting/findings.py +33 -0
  209. haris-0.7.0/src/haris/reporting/html_report.py +126 -0
  210. haris-0.7.0/src/haris/reporting/json_report.py +48 -0
  211. haris-0.7.0/src/haris/reporting/junit_report.py +62 -0
  212. haris-0.7.0/src/haris/reporting/markdown_report.py +236 -0
  213. haris-0.7.0/src/haris/reporting/report_schema.py +92 -0
  214. haris-0.7.0/src/haris/reporting/sarif_report.py +192 -0
  215. haris-0.7.0/src/haris/resources/__init__.py +0 -0
  216. haris-0.7.0/src/haris/resources/config/agent.yaml +24 -0
  217. haris-0.7.0/src/haris/resources/config/ai_mappings.yaml +221 -0
  218. haris-0.7.0/src/haris/resources/config/ai_probes.yaml +47 -0
  219. haris-0.7.0/src/haris/resources/config/ai_signatures.yaml +168 -0
  220. haris-0.7.0/src/haris/resources/config/confidence.yaml +73 -0
  221. haris-0.7.0/src/haris/resources/config/default_config.yaml +159 -0
  222. haris-0.7.0/src/haris/resources/config/llm_models.yaml +68 -0
  223. haris-0.7.0/src/haris/resources/config/scanner_data.yaml +43 -0
  224. haris-0.7.0/src/haris/resources/config/scanners/garak.yaml +14 -0
  225. haris-0.7.0/src/haris/resources/config/scanners/nikto.yaml +116 -0
  226. haris-0.7.0/src/haris/resources/config/scanners/nmap.yaml +48 -0
  227. haris-0.7.0/src/haris/resources/config/scanners/nuclei.yaml +361 -0
  228. haris-0.7.0/src/haris/resources/config/scanners/promptfoo.yaml +23 -0
  229. haris-0.7.0/src/haris/resources/config/scanners/sslyze.yaml +64 -0
  230. haris-0.7.0/src/haris/resources/config/scanners/wapiti.yaml +83 -0
  231. haris-0.7.0/src/haris/resources/config/scanners/zap.yaml +22 -0
  232. haris-0.7.0/src/haris/resources/config/verify.yaml +56 -0
  233. haris-0.7.0/src/haris/resources/config/vuln_classes.yaml +356 -0
  234. haris-0.7.0/src/haris/resources/schema/report.schema.json +670 -0
  235. haris-0.7.0/src/haris/scan_files.py +30 -0
  236. haris-0.7.0/src/haris/scanners/__init__.py +44 -0
  237. haris-0.7.0/src/haris/scanners/argv_policy.py +47 -0
  238. haris-0.7.0/src/haris/scanners/base.py +76 -0
  239. haris-0.7.0/src/haris/scanners/garak_scanner.py +183 -0
  240. haris-0.7.0/src/haris/scanners/nikto_scanner.py +258 -0
  241. haris-0.7.0/src/haris/scanners/nmap_scanner.py +261 -0
  242. haris-0.7.0/src/haris/scanners/nuclei_results.py +239 -0
  243. haris-0.7.0/src/haris/scanners/nuclei_scanner.py +470 -0
  244. haris-0.7.0/src/haris/scanners/nuclei_templates.py +26 -0
  245. haris-0.7.0/src/haris/scanners/nuclei_urls.py +55 -0
  246. haris-0.7.0/src/haris/scanners/option_policy.py +242 -0
  247. haris-0.7.0/src/haris/scanners/option_values.py +74 -0
  248. haris-0.7.0/src/haris/scanners/process.py +60 -0
  249. haris-0.7.0/src/haris/scanners/promptfoo_scanner.py +247 -0
  250. haris-0.7.0/src/haris/scanners/redaction.py +57 -0
  251. haris-0.7.0/src/haris/scanners/sslyze_scanner.py +244 -0
  252. haris-0.7.0/src/haris/scanners/wapiti_exclude.py +27 -0
  253. haris-0.7.0/src/haris/scanners/wapiti_scanner.py +264 -0
  254. haris-0.7.0/src/haris/scanners/wapiti_session.py +104 -0
  255. haris-0.7.0/src/haris/scanners/zap_plan.py +155 -0
  256. haris-0.7.0/src/haris/scanners/zap_scanner.py +244 -0
  257. haris-0.7.0/src/haris/templates/__init__.py +9 -0
  258. haris-0.7.0/src/haris/templates/adapters.py +336 -0
  259. haris-0.7.0/src/haris/templates/manager.py +174 -0
  260. haris-0.7.0/src/haris/templates/report.py +49 -0
  261. haris-0.7.0/src/haris/templates/updater.py +201 -0
  262. haris-0.7.0/src/haris/verify/__init__.py +15 -0
  263. haris-0.7.0/src/haris/verify/evidence.py +41 -0
  264. haris-0.7.0/src/haris/verify/llm_verdict.py +148 -0
  265. haris-0.7.0/src/haris/verify/oracles.py +150 -0
  266. haris-0.7.0/src/haris/verify/oracles_baseline.py +54 -0
  267. haris-0.7.0/src/haris/verify/pipeline.py +66 -0
  268. haris-0.7.0/src/haris/verify/probe.py +88 -0
  269. haris-0.7.0/src/haris/verify/replay.py +142 -0
  270. haris-0.7.0/src/haris/verify/settings.py +71 -0
  271. haris-0.7.0/src/haris/verify/timing.py +63 -0
  272. haris-0.7.0/src/haris/verify/verdict_prompt.py +72 -0
  273. haris-0.7.0/src/haris/web/__init__.py +1 -0
  274. haris-0.7.0/src/haris/web/access.py +64 -0
  275. haris-0.7.0/src/haris/web/agent_gate.py +158 -0
  276. haris-0.7.0/src/haris/web/app.py +108 -0
  277. haris-0.7.0/src/haris/web/conversations.py +51 -0
  278. haris-0.7.0/src/haris/web/job_queue.py +148 -0
  279. haris-0.7.0/src/haris/web/llm_support.py +43 -0
  280. haris-0.7.0/src/haris/web/logging_setup.py +23 -0
  281. haris-0.7.0/src/haris/web/page_data.py +19 -0
  282. haris-0.7.0/src/haris/web/routers/__init__.py +43 -0
  283. haris-0.7.0/src/haris/web/routers/account.py +88 -0
  284. haris-0.7.0/src/haris/web/routers/admin.py +153 -0
  285. haris-0.7.0/src/haris/web/routers/admin_api.py +15 -0
  286. haris-0.7.0/src/haris/web/routers/auth_login.py +309 -0
  287. haris-0.7.0/src/haris/web/routers/health.py +8 -0
  288. haris-0.7.0/src/haris/web/routers/llm_chat.py +159 -0
  289. haris-0.7.0/src/haris/web/routers/llm_scan.py +96 -0
  290. haris-0.7.0/src/haris/web/routers/oidc.py +76 -0
  291. haris-0.7.0/src/haris/web/routers/pages.py +146 -0
  292. haris-0.7.0/src/haris/web/routers/scan_data.py +92 -0
  293. haris-0.7.0/src/haris/web/routers/scan_templates.py +106 -0
  294. haris-0.7.0/src/haris/web/routers/scans.py +93 -0
  295. haris-0.7.0/src/haris/web/routers/scans_api.py +334 -0
  296. haris-0.7.0/src/haris/web/routers/targets.py +85 -0
  297. haris-0.7.0/src/haris/web/routers/templates_api.py +226 -0
  298. haris-0.7.0/src/haris/web/routers/tokens.py +78 -0
  299. haris-0.7.0/src/haris/web/routers/websites.py +58 -0
  300. haris-0.7.0/src/haris/web/routers/websites_api.py +50 -0
  301. haris-0.7.0/src/haris/web/routing.py +80 -0
  302. haris-0.7.0/src/haris/web/scan_runtime.py +169 -0
  303. haris-0.7.0/src/haris/web/scanner_info.py +32 -0
  304. haris-0.7.0/src/haris/web/schemas/__init__.py +0 -0
  305. haris-0.7.0/src/haris/web/schemas/access.py +46 -0
  306. haris-0.7.0/src/haris/web/schemas/llm.py +99 -0
  307. haris-0.7.0/src/haris/web/schemas/scans.py +58 -0
  308. haris-0.7.0/src/haris/web/schemas/sites.py +77 -0
  309. haris-0.7.0/src/haris/web/settings.py +46 -0
  310. haris-0.7.0/src/haris/web/state.py +40 -0
  311. haris-0.7.0/src/haris/web/static/css/findings.css +248 -0
  312. haris-0.7.0/src/haris/web/static/css/fonts.css +28 -0
  313. haris-0.7.0/src/haris/web/static/css/layout.css +241 -0
  314. haris-0.7.0/src/haris/web/static/css/pages.css +220 -0
  315. haris-0.7.0/src/haris/web/static/css/template_form.css +54 -0
  316. haris-0.7.0/src/haris/web/static/favicon.svg +4 -0
  317. haris-0.7.0/src/haris/web/static/haris_logo.png +0 -0
  318. haris-0.7.0/src/haris/web/static/js/dashboard.js +12 -0
  319. haris-0.7.0/src/haris/web/static/js/login.js +4 -0
  320. haris-0.7.0/src/haris/web/static/js/password_form.js +25 -0
  321. haris-0.7.0/src/haris/web/static/js/profile.js +16 -0
  322. haris-0.7.0/src/haris/web/static/js/reload.js +1 -0
  323. haris-0.7.0/src/haris/web/static/js/scan_detail.js +161 -0
  324. haris-0.7.0/src/haris/web/static/js/scan_new.js +97 -0
  325. haris-0.7.0/src/haris/web/static/js/scans.js +8 -0
  326. haris-0.7.0/src/haris/web/static/js/template_form.js +303 -0
  327. haris-0.7.0/src/haris/web/static/js/templates_page.js +102 -0
  328. haris-0.7.0/src/haris/web/static/js/users.js +44 -0
  329. haris-0.7.0/src/haris/web/static/js/website_detail.js +98 -0
  330. haris-0.7.0/src/haris/web/static/main.js +135 -0
  331. haris-0.7.0/src/haris/web/static/style.css +335 -0
  332. haris-0.7.0/src/haris/web/static/theme-init.js +4 -0
  333. haris-0.7.0/src/haris/web/static/vendor/LICENSE.chartjs +9 -0
  334. haris-0.7.0/src/haris/web/static/vendor/LICENSE.dompurify +202 -0
  335. haris-0.7.0/src/haris/web/static/vendor/LICENSE.htmx +13 -0
  336. haris-0.7.0/src/haris/web/static/vendor/LICENSE.inter +93 -0
  337. haris-0.7.0/src/haris/web/static/vendor/LICENSE.marked +44 -0
  338. haris-0.7.0/src/haris/web/static/vendor/README +32 -0
  339. haris-0.7.0/src/haris/web/static/vendor/chart.umd.min.js +14 -0
  340. haris-0.7.0/src/haris/web/static/vendor/fonts/inter-latin-400-normal.woff2 +0 -0
  341. haris-0.7.0/src/haris/web/static/vendor/fonts/inter-latin-500-normal.woff2 +0 -0
  342. haris-0.7.0/src/haris/web/static/vendor/fonts/inter-latin-600-normal.woff2 +0 -0
  343. haris-0.7.0/src/haris/web/static/vendor/fonts/inter-latin-700-normal.woff2 +0 -0
  344. haris-0.7.0/src/haris/web/static/vendor/htmx.min.js +1 -0
  345. haris-0.7.0/src/haris/web/static/vendor/marked.umd.js +86 -0
  346. haris-0.7.0/src/haris/web/static/vendor/purify.min.js +7 -0
  347. haris-0.7.0/src/haris/web/targets.py +190 -0
  348. haris-0.7.0/src/haris/web/templates/_scan_rows.html +43 -0
  349. haris-0.7.0/src/haris/web/templates/auth/audit_log.html +107 -0
  350. haris-0.7.0/src/haris/web/templates/auth/login.html +101 -0
  351. haris-0.7.0/src/haris/web/templates/auth/profile.html +165 -0
  352. haris-0.7.0/src/haris/web/templates/auth/register.html +85 -0
  353. haris-0.7.0/src/haris/web/templates/auth/setup.html +88 -0
  354. haris-0.7.0/src/haris/web/templates/auth/users.html +155 -0
  355. haris-0.7.0/src/haris/web/templates/auth/verify_email.html +54 -0
  356. haris-0.7.0/src/haris/web/templates/base.html +121 -0
  357. haris-0.7.0/src/haris/web/templates/dashboard.html +113 -0
  358. haris-0.7.0/src/haris/web/templates/licenses.html +82 -0
  359. haris-0.7.0/src/haris/web/templates/partials/scan_ai_insights.html +82 -0
  360. haris-0.7.0/src/haris/web/templates/partials/template_form_scanners_b.html +198 -0
  361. haris-0.7.0/src/haris/web/templates/scan_detail.html +332 -0
  362. haris-0.7.0/src/haris/web/templates/scan_new.html +147 -0
  363. haris-0.7.0/src/haris/web/templates/scans.html +89 -0
  364. haris-0.7.0/src/haris/web/templates/settings.html +54 -0
  365. haris-0.7.0/src/haris/web/templates/template_form.html +321 -0
  366. haris-0.7.0/src/haris/web/templates/templates.html +190 -0
  367. haris-0.7.0/src/haris/web/templates/website_detail.html +111 -0
  368. haris-0.7.0/src/haris/web/templates/websites.html +42 -0
  369. haris-0.7.0/src/haris/web/templating.py +38 -0
  370. haris-0.7.0/src/haris.egg-info/PKG-INFO +253 -0
  371. haris-0.7.0/src/haris.egg-info/SOURCES.txt +503 -0
  372. haris-0.7.0/src/haris.egg-info/dependency_links.txt +1 -0
  373. haris-0.7.0/src/haris.egg-info/entry_points.txt +2 -0
  374. haris-0.7.0/src/haris.egg-info/requires.txt +24 -0
  375. haris-0.7.0/src/haris.egg-info/top_level.txt +1 -0
  376. haris-0.7.0/tests/test_agent_budget.py +183 -0
  377. haris-0.7.0/tests/test_agent_docker.py +191 -0
  378. haris-0.7.0/tests/test_agent_fields.py +102 -0
  379. haris-0.7.0/tests/test_agent_guardrails.py +137 -0
  380. haris-0.7.0/tests/test_agent_injection.py +110 -0
  381. haris-0.7.0/tests/test_agent_policy.py +153 -0
  382. haris-0.7.0/tests/test_agent_post_reexec.py +277 -0
  383. haris-0.7.0/tests/test_agent_proxy.py +245 -0
  384. haris-0.7.0/tests/test_agent_runtime.py +60 -0
  385. haris-0.7.0/tests/test_agent_sandbox_probe.py +48 -0
  386. haris-0.7.0/tests/test_agent_stage.py +89 -0
  387. haris-0.7.0/tests/test_agent_tunnel.py +44 -0
  388. haris-0.7.0/tests/test_agent_validator.py +208 -0
  389. haris-0.7.0/tests/test_ai_active.py +325 -0
  390. haris-0.7.0/tests/test_ai_adapter_gate.py +46 -0
  391. haris-0.7.0/tests/test_ai_adapter_preflight.py +157 -0
  392. haris-0.7.0/tests/test_ai_classes.py +33 -0
  393. haris-0.7.0/tests/test_ai_cli.py +79 -0
  394. haris-0.7.0/tests/test_ai_discovery.py +127 -0
  395. haris-0.7.0/tests/test_ai_garak.py +169 -0
  396. haris-0.7.0/tests/test_ai_mcp.py +245 -0
  397. haris-0.7.0/tests/test_ai_owasp.py +131 -0
  398. haris-0.7.0/tests/test_ai_passive.py +197 -0
  399. haris-0.7.0/tests/test_ai_promptfoo.py +199 -0
  400. haris-0.7.0/tests/test_ai_sse.py +48 -0
  401. haris-0.7.0/tests/test_auth_email.py +350 -0
  402. haris-0.7.0/tests/test_auth_fixes.py +181 -0
  403. haris-0.7.0/tests/test_auth_oidc.py +186 -0
  404. haris-0.7.0/tests/test_auth_service.py +570 -0
  405. haris-0.7.0/tests/test_bench_callback.py +213 -0
  406. haris-0.7.0/tests/test_bench_fixtures.py +175 -0
  407. haris-0.7.0/tests/test_bench_ground_truth.py +146 -0
  408. haris-0.7.0/tests/test_bench_login.py +283 -0
  409. haris-0.7.0/tests/test_bench_run.py +227 -0
  410. haris-0.7.0/tests/test_bench_scanner_args.py +113 -0
  411. haris-0.7.0/tests/test_bench_score.py +418 -0
  412. haris-0.7.0/tests/test_chat.py +163 -0
  413. haris-0.7.0/tests/test_checks_baseline.py +252 -0
  414. haris-0.7.0/tests/test_checks_cookies.py +187 -0
  415. haris-0.7.0/tests/test_checks_dns.py +145 -0
  416. haris-0.7.0/tests/test_checks_exposure.py +151 -0
  417. haris-0.7.0/tests/test_checks_headers.py +205 -0
  418. haris-0.7.0/tests/test_checks_info.py +173 -0
  419. haris-0.7.0/tests/test_checks_probes.py +229 -0
  420. haris-0.7.0/tests/test_checks_registry.py +43 -0
  421. haris-0.7.0/tests/test_checks_tls.py +128 -0
  422. haris-0.7.0/tests/test_cli_exit.py +146 -0
  423. haris-0.7.0/tests/test_cli_web.py +24 -0
  424. haris-0.7.0/tests/test_config_paths.py +24 -0
  425. haris-0.7.0/tests/test_config_scope.py +14 -0
  426. haris-0.7.0/tests/test_correlator.py +146 -0
  427. haris-0.7.0/tests/test_db.py +333 -0
  428. haris-0.7.0/tests/test_db_identity.py +160 -0
  429. haris-0.7.0/tests/test_db_jobs.py +68 -0
  430. haris-0.7.0/tests/test_db_ownership.py +104 -0
  431. haris-0.7.0/tests/test_db_rollback.py +69 -0
  432. haris-0.7.0/tests/test_db_scope.py +96 -0
  433. haris-0.7.0/tests/test_docker_exec.py +149 -0
  434. haris-0.7.0/tests/test_engine.py +453 -0
  435. haris-0.7.0/tests/test_engine_pipeline.py +293 -0
  436. haris-0.7.0/tests/test_enrichment.py +344 -0
  437. haris-0.7.0/tests/test_excluded_paths_syntax.py +55 -0
  438. haris-0.7.0/tests/test_finding.py +189 -0
  439. haris-0.7.0/tests/test_identity.py +177 -0
  440. haris-0.7.0/tests/test_ignore_diff.py +252 -0
  441. haris-0.7.0/tests/test_l6_jsonrpc.py +8 -0
  442. haris-0.7.0/tests/test_llm.py +238 -0
  443. haris-0.7.0/tests/test_llm_budget.py +155 -0
  444. haris-0.7.0/tests/test_llm_catalog.py +160 -0
  445. haris-0.7.0/tests/test_llm_injection.py +142 -0
  446. haris-0.7.0/tests/test_llm_parsing.py +93 -0
  447. haris-0.7.0/tests/test_llm_redaction.py +98 -0
  448. haris-0.7.0/tests/test_llm_retry.py +97 -0
  449. haris-0.7.0/tests/test_migrations.py +148 -0
  450. haris-0.7.0/tests/test_nuclei_phases.py +319 -0
  451. haris-0.7.0/tests/test_nuclei_scanner.py +844 -0
  452. haris-0.7.0/tests/test_option_policy.py +159 -0
  453. haris-0.7.0/tests/test_owasp.py +72 -0
  454. haris-0.7.0/tests/test_profiles.py +40 -0
  455. haris-0.7.0/tests/test_ratelimit.py +50 -0
  456. haris-0.7.0/tests/test_remediation.py +101 -0
  457. haris-0.7.0/tests/test_report_escape.py +132 -0
  458. haris-0.7.0/tests/test_report_integrations.py +23 -0
  459. haris-0.7.0/tests/test_report_sarif.py +97 -0
  460. haris-0.7.0/tests/test_report_schema.py +73 -0
  461. haris-0.7.0/tests/test_report_tabular.py +75 -0
  462. haris-0.7.0/tests/test_reporting.py +165 -0
  463. haris-0.7.0/tests/test_retriever.py +360 -0
  464. haris-0.7.0/tests/test_risk.py +104 -0
  465. haris-0.7.0/tests/test_router.py +170 -0
  466. haris-0.7.0/tests/test_runner.py +194 -0
  467. haris-0.7.0/tests/test_scan_config_templates.py +613 -0
  468. haris-0.7.0/tests/test_scan_context.py +106 -0
  469. haris-0.7.0/tests/test_scanner_config.py +66 -0
  470. haris-0.7.0/tests/test_scanner_golden.py +367 -0
  471. haris-0.7.0/tests/test_scanner_runtime.py +250 -0
  472. haris-0.7.0/tests/test_schema_v6.py +225 -0
  473. haris-0.7.0/tests/test_scoped_client.py +362 -0
  474. haris-0.7.0/tests/test_scoped_stream.py +197 -0
  475. haris-0.7.0/tests/test_session_revoke.py +32 -0
  476. haris-0.7.0/tests/test_ssrf.py +151 -0
  477. haris-0.7.0/tests/test_target.py +174 -0
  478. haris-0.7.0/tests/test_templates.py +543 -0
  479. haris-0.7.0/tests/test_tool_vet.py +67 -0
  480. haris-0.7.0/tests/test_verify_baseline_oracles.py +249 -0
  481. haris-0.7.0/tests/test_verify_llm.py +324 -0
  482. haris-0.7.0/tests/test_verify_oracles.py +287 -0
  483. haris-0.7.0/tests/test_verify_pipeline.py +207 -0
  484. haris-0.7.0/tests/test_verify_unclassified_external.py +124 -0
  485. haris-0.7.0/tests/test_vuln_class_external_aliases.py +178 -0
  486. haris-0.7.0/tests/test_vuln_class_wapiti.py +70 -0
  487. haris-0.7.0/tests/test_wapiti_argv.py +161 -0
  488. haris-0.7.0/tests/test_wapiti_session.py +210 -0
  489. haris-0.7.0/tests/test_web_agent.py +283 -0
  490. haris-0.7.0/tests/test_web_agent_gate_audit.py +146 -0
  491. haris-0.7.0/tests/test_web_auth_fixes.py +390 -0
  492. haris-0.7.0/tests/test_web_csrf.py +236 -0
  493. haris-0.7.0/tests/test_web_env.py +277 -0
  494. haris-0.7.0/tests/test_web_execute.py +172 -0
  495. haris-0.7.0/tests/test_web_llm.py +195 -0
  496. haris-0.7.0/tests/test_web_ownership.py +249 -0
  497. haris-0.7.0/tests/test_web_proofs.py +250 -0
  498. haris-0.7.0/tests/test_web_queue.py +294 -0
  499. haris-0.7.0/tests/test_web_routes.py +246 -0
  500. haris-0.7.0/tests/test_web_scanner_options.py +123 -0
  501. haris-0.7.0/tests/test_web_targets.py +140 -0
  502. haris-0.7.0/tests/test_web_templates.py +294 -0
  503. haris-0.7.0/tests/test_web_tokens.py +338 -0
  504. haris-0.7.0/tests/test_web_verify.py +166 -0
  505. haris-0.7.0/tests/test_zap_scanner.py +315 -0
haris-0.7.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 HARIS contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
haris-0.7.0/PKG-INFO ADDED
@@ -0,0 +1,253 @@
1
+ Metadata-Version: 2.4
2
+ Name: haris
3
+ Version: 0.7.0
4
+ Summary: Black-box web application security audit framework
5
+ Author: HARIS contributors
6
+ License: MIT
7
+ Keywords: security,audit,pentest,owasp,vulnerability-scanner
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Intended Audience :: Information Technology
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Programming Language :: Python :: 3.14
15
+ Classifier: Topic :: Security
16
+ Requires-Python: >=3.13
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: pydantic>=2.14.3
20
+ Requires-Dist: requests>=2.34.2
21
+ Requires-Dist: pyyaml>=6.0.3
22
+ Requires-Dist: jinja2>=3.1.6
23
+ Requires-Dist: openai>=3.46.0
24
+ Requires-Dist: anthropic>=2.6.0
25
+ Requires-Dist: bcrypt>=5.0.0
26
+ Requires-Dist: starlette>=1.10.0
27
+ Requires-Dist: yoyo-migrations>=9.0.0
28
+ Provides-Extra: web
29
+ Requires-Dist: fastapi>=0.162.2; extra == "web"
30
+ Requires-Dist: uvicorn[standard]>=0.54.0; extra == "web"
31
+ Requires-Dist: python-multipart>=0.0.33; extra == "web"
32
+ Requires-Dist: authlib>=1.9.5; extra == "web"
33
+ Requires-Dist: httpx>=0.28.1; extra == "web"
34
+ Requires-Dist: itsdangerous>=2.2.0; extra == "web"
35
+ Requires-Dist: dnspython>=2.8.0; extra == "web"
36
+ Provides-Extra: reporting
37
+ Requires-Dist: markdown>=3.11.3; extra == "reporting"
38
+ Provides-Extra: all
39
+ Requires-Dist: haris[reporting,web]; extra == "all"
40
+ Dynamic: license-file
41
+
42
+ <p align="center">
43
+ <img src="assets/haris_logo.png" alt="HARIS" width="400"><br>
44
+ <em>Black-box web security audit framework. Scan, correlate, prioritise, remediate.</em><br><br>
45
+ <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License"></a>
46
+ <a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.13+-blue.svg" alt="Python"></a>
47
+ <a href="https://owasp.org/www-project-top-ten/"><img src="https://img.shields.io/badge/OWASP-Top%2010%202025-red.svg" alt="OWASP"></a>
48
+ </p>
49
+
50
+ Orchestrates security scanners, correlates findings, and writes one prioritised report. LLM analysis is optional.
51
+
52
+ ## What this does
53
+
54
+ 1. **Cross-tool correlation.** Findings that share a fingerprint become one finding. The score combines the scanners that reported it.
55
+ 2. **Cross-scanner context.** Built-in checks and nmap fill a `ScanContext`. Later scanners read it. Nuclei uses detected technologies in phase 2b.
56
+ 3. **Business-risk text.** Plain-language impact sits next to the technical finding.
57
+ 4. **Prioritised remediation.** Fixes are grouped and ordered by impact and effort.
58
+ 5. **Profiles.** `quick`, `pre-launch`, `full`, `ai-security`, `regression`, `compliance`.
59
+ 6. **Scan templates.** Named presets with per-scanner overrides, stored and reused from the web UI.
60
+ 7. **LLM analysis.** Q&A, Jira text, test cases and enrichment, from the scan data.
61
+ 8. **OWASP Top 10 (2025).** Findings are mapped, including Software Supply Chain Failures and Mishandling of Exceptional Conditions.
62
+ 9. **Verification.** Replay oracles, an optional LLM verdict, and an opt-in agent. A refuted finding stays in the report. See [`docs/verification.md`](docs/verification.md).
63
+
64
+ ## Scanners
65
+
66
+ | Scanner | What it tests | Install | Version recorded |
67
+ | ------- | ------------- | ------- | ---------------- |
68
+ | Wapiti | SQLi, XSS, SSRF, command injection, CRLF, XXE | `pipx install wapiti3` | 3.3 |
69
+ | SSLyze | TLS protocols, cipher suites, certificate chain, Heartbleed, ROBOT | `pipx install sslyze` | 6.x |
70
+ | Nmap | Open ports, service versions, exposed databases | system package manager | 7.x |
71
+ | Nikto | Web server misconfigurations, outdated software, dangerous files | `brew install nikto` | 2.x |
72
+ | Nuclei | CVE checks, default credentials, exposed panels, tech fingerprint (phase 1, 2a, 2b) | `brew install nuclei` | 3.x |
73
+ | ZAP | Active and passive web scan. Off by default and in no profile. `--scanners zap` | [ZAP download](https://www.zaproxy.org/download/) | 2.16 |
74
+ | garak | Injection and leakage probes on a discovered chat route. Runs only with `--ai-active` and `--i-have-authorization` | install the binary | 0.17 |
75
+ | promptfoo | Red-team plugins on a discovered chat route. Same flags as garak | install the binary | 0.125 |
76
+
77
+ The version column is the adapter `version` attribute. The Wapiti docstring names 3.3.2. The Nikto docstring names 2.6. Nuclei fixtures in `tests/fixtures/scanners/README.md` are 3.7.1. `garak.yaml` comments 0.17.1 and `promptfoo.yaml` comments 0.125.1. HARIS does not check the tool version at runtime.
78
+
79
+ Install Wapiti and SSLyze with `pipx`, outside the HARIS environment.
80
+
81
+ ## Built-in checks
82
+
83
+ Fourteen checks. `quick` runs every check except `ai_security`.
84
+
85
+ | Check | What it tests |
86
+ | ----- | ------------- |
87
+ | `header_checks` | Six headers: HSTS, CSP, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy. Also weak CSP or HSTS, a versioned Server banner, and any X-Powered-By header |
88
+ | `tls_checks` | Certificate and TLS basics |
89
+ | `misc_checks` | CORS, HTTP to HTTPS redirect, 14 sensitive paths |
90
+ | `info_disclosure` | Error pages, debug endpoints, HTML comments |
91
+ | `cookie_checks` | Session cookie flags, scope, expiry and name |
92
+ | `sri_checks` | Subresource Integrity on third-party resources |
93
+ | `cache_checks` | Cache-Control on login, account and session-setting responses |
94
+ | `method_checks` | OPTIONS advertisement and TRACE |
95
+ | `redirect_checks` | Open redirect via common redirect parameters |
96
+ | `graphql_checks` | GraphQL introspection |
97
+ | `openapi_checks` | Exposed OpenAPI or Swagger documents |
98
+ | `listing_checks` | Directory listing |
99
+ | `dns_checks` | CAA, SPF and DMARC |
100
+ | `ai_security` | AI endpoints and MCP servers. Prompts only with `--ai-active` and `--i-have-authorization`. See [`docs/ai_security.md`](docs/ai_security.md) |
101
+
102
+ The 14 sensitive paths are `/.env`, `/.git/config`, `/robots.txt`, `/sitemap.xml`, `/.well-known/security.txt`, `/wp-login.php`, `/admin`, `/phpmyadmin`, `/server-status`, `/server-info`, `/.DS_Store`, `/crossdomain.xml`, `/elmah.axd` and `/trace.axd`.
103
+
104
+ ## Setup
105
+
106
+ The console script is `haris`, entry point `haris.cli:main`.
107
+
108
+ ```bash
109
+ git clone https://github.com/calghar/HARIS
110
+ cd HARIS
111
+ uv sync --extra web --extra reporting
112
+ uv run haris --help
113
+ ```
114
+
115
+ Nmap, Nikto, Nuclei, SSLyze, Wapiti and optional ZAP, garak and promptfoo are separate programs. For LLM features set `ANTHROPIC_API_KEY` or `OPENAI_API_KEY`. Ollama needs no key. Its client uses `http://localhost:11434` unless the backend is constructed with another base URL.
116
+
117
+ ## Authentication
118
+
119
+ The web dashboard requires login. On first start an admin account is created from:
120
+
121
+ ```bash
122
+ HARIS_ADMIN_EMAIL=admin@example.com
123
+ HARIS_ADMIN_PASSWORD=changeme123
124
+ HARIS_SECRET_KEY=<random-32-char-string> # python -c "import secrets; print(secrets.token_hex(32))"
125
+ ```
126
+
127
+ Startup creates that admin when both `HARIS_ADMIN_EMAIL` and `HARIS_ADMIN_PASSWORD` are set and the user table is empty. `/auth/setup` answers 404 until `HARIS_SETUP_TOKEN` is set, and once a user exists.
128
+
129
+ Self-registration uses `HARIS_ALLOWED_EMAIL_DOMAINS`. New accounts need email verification, or an admin activates them when SMTP is off.
130
+
131
+ Roles are `admin` and `user`. An admin manages users, settings, and any user's scans and templates. A user scans, and views and deletes their own scans, and uses Q&A.
132
+
133
+ OIDC uses `HARIS_OIDC_ENABLED=true` plus `HARIS_OIDC_ISSUER`, `HARIS_OIDC_CLIENT_ID` and `HARIS_OIDC_CLIENT_SECRET`. See [`docs/authentication.md`](docs/authentication.md).
134
+
135
+ ## Usage
136
+
137
+ ```bash
138
+ # CLI. --verify defaults to replay (off, replay, llm).
139
+ uv run haris --url https://example.com --profile quick --yes
140
+ uv run haris --list-profiles
141
+
142
+ # Web dashboard. Bind defaults are 127.0.0.1 and port 8000.
143
+ uv run haris --web
144
+
145
+ # Docker
146
+ docker compose up
147
+ docker compose run --rm cli --url https://example.com --profile quick --yes
148
+ make reload
149
+
150
+ # LLM analysis after a scan
151
+ uv run haris llm ask --scan-id <id> --question "Top 3 risks for an exec"
152
+ uv run haris llm remediate --scan-id <id> --format jira
153
+ uv run haris llm summarize --scan-id <id> --audience developer
154
+
155
+ # In-pipeline LLM enrichment
156
+ uv run haris --url https://example.com --profile quick --yes --llm-enrich
157
+
158
+ # Scanner template updates
159
+ uv run haris update-templates
160
+ uv run haris update-templates --scanner nuclei --list
161
+ ```
162
+
163
+ ## Scan profiles
164
+
165
+ Estimates are the `estimated_duration` strings on each profile.
166
+
167
+ | Profile | Scanners | Use |
168
+ | ------- | -------- | --- |
169
+ | `quick` | The 13 built-in checks other than `ai_security` | First look. 1-3 minutes |
170
+ | `pre-launch` | `quick` plus `nmap`, `sslyze`, `wapiti` | Before production. 10-30 minutes |
171
+ | `full` | `pre-launch` plus `nikto`, `nuclei` | Full audit. 20-30 minutes. ZAP, garak and promptfoo are absent |
172
+ | `ai-security` | `header_checks`, `tls_checks`, `info_disclosure`, `ai_security`, `garak`, `promptfoo` | AI endpoints. 1-10 minutes |
173
+ | `regression` | `header_checks`, `tls_checks`, `misc_checks` | CI gate. 30-60 seconds |
174
+ | `compliance` | `header_checks`, `tls_checks`, `misc_checks`, `info_disclosure`, `cookie_checks`, `nmap`, `sslyze` | TLS, headers, cookies, disclosure, ports. 5-15 minutes |
175
+
176
+ ## Configuration
177
+
178
+ Copy `.env.example` to `.env`. The option file is `src/haris/resources/config/default_config.yaml`. Override it with `HARIS_CONFIG` or `./config/default_config.yaml` in the working directory.
179
+
180
+ | Variable | Purpose |
181
+ | -------- | ------- |
182
+ | `HARIS_ADMIN_EMAIL` | Bootstrap admin email, used on first start when no users exist |
183
+ | `HARIS_ADMIN_PASSWORD` | Bootstrap admin password |
184
+ | `HARIS_SECRET_KEY` | Session signing secret |
185
+ | `HARIS_TARGET_URL` | Default scan target |
186
+ | `HARIS_PROFILE` | Default scan profile |
187
+ | `HARIS_AUTH_HEADER` | Auth header value for the target |
188
+ | `HARIS_AUTH_COOKIE` | Auth cookie value for the target |
189
+ | `HARIS_AUTH_USERNAME` | Auth username for the target |
190
+ | `HARIS_AUTH_PASSWORD` | Auth password for the target |
191
+ | `ANTHROPIC_API_KEY` | Anthropic LLM backend |
192
+ | `OPENAI_API_KEY` | OpenAI LLM backend |
193
+ | `HARIS_OIDC_CLIENT_SECRET` | OIDC client secret |
194
+ | `HARIS_SMTP_USERNAME` | SMTP username for email verification |
195
+ | `HARIS_SMTP_PASSWORD` | SMTP password |
196
+
197
+ `OLLAMA_BASE_URL` is not read. The Ollama client default is the constructor argument above.
198
+
199
+ Web server variables. Flags accept `1`, `true` or `yes`, except where noted.
200
+
201
+ | Variable | Default | Effect |
202
+ | -------- | ------- | ------ |
203
+ | `HARIS_WEB_VERIFY_DEFAULT` | `replay` | Verification mode for web scans when the request sets none: `off`, `replay` or `llm` |
204
+ | `HARIS_TARGET_ALLOWLIST` | empty | Comma-separated host globs that skip ownership proof |
205
+ | `HARIS_ALLOW_PRIVATE_TARGETS` | `false` | Allow private and loopback target addresses. Only the value `true` enables it |
206
+ | `HARIS_SHARE_SCANS_ORG_WIDE` | `false` | Every user can read all scans. Only owners and admins can change them |
207
+ | `HARIS_AGENT_DISABLED` | unset | The value `1` stops the agent from running on any scan |
208
+ | `HARIS_MAX_CONCURRENT_SCANS` | `2` | Scans that run at once. At least 1 |
209
+ | `HARIS_FORCE_HTTPS` | `false` | Redirect `http://` requests to `https://` |
210
+ | `HARIS_ALLOWED_EMAIL_DOMAINS` | `techforpalestine.org` | Comma-separated registration domains. Empty allows any |
211
+ | `HARIS_OIDC_ENABLED` | `false` | Turn on OIDC sign-in |
212
+ | `HARIS_OIDC_ISSUER`, `HARIS_OIDC_CLIENT_ID` | empty | OIDC provider issuer URL and client ID |
213
+ | `HARIS_SMTP_ENABLED` | `false` | Send verification email. Otherwise the link is logged |
214
+ | `HARIS_SMTP_HOST`, `HARIS_SMTP_PORT` | `localhost`, `587` | SMTP server |
215
+ | `HARIS_SMTP_USE_TLS` | `true` | Any value other than `false` keeps TLS on |
216
+ | `HARIS_SMTP_FROM`, `HARIS_SMTP_FROM_NAME` | `noreply@techforpalestine.org`, `HARIS Security Platform` | Sender address and name |
217
+ | `HARIS_PUBLIC_URL` | unset | When set, the only base for emailed verification links. When unset, SMTP does not send and the link is logged from the request base URL |
218
+ | `HARIS_ALLOWED_HOSTS` | unset | Comma-separated hosts. When set, any other Host header is rejected and www redirect is off. When unset, there is no host check |
219
+ | `HARIS_COOKIE_SECURE` | `auto` | `true` forces the Secure flag and `false` omits it. Any other value, including `1` and `yes`, follows the request scheme. Session cookie and CSRF seed cookie |
220
+ | `HARIS_SETUP_TOKEN` | unset | `/auth/setup` answers 404 until this is set, and once a user exists. The form field `setup_token` is compared with this value |
221
+
222
+ ## Documentation
223
+
224
+ - Architecture: [`docs/architecture.md`](docs/architecture.md)
225
+ - Methodology: [`docs/methodology.md`](docs/methodology.md)
226
+ - Verification: [`docs/verification.md`](docs/verification.md)
227
+ - Benchmarks: [`docs/benchmarks.md`](docs/benchmarks.md)
228
+ - Agent safety: [`docs/agent_safety.md`](docs/agent_safety.md)
229
+ - AI security: [`docs/ai_security.md`](docs/ai_security.md)
230
+ - Authentication: [`docs/authentication.md`](docs/authentication.md)
231
+ - LLM integration: [`docs/llm_integration.md`](docs/llm_integration.md)
232
+ - CI integrations: [`docs/integrations.md`](docs/integrations.md)
233
+ - Writing a check: [`docs/writing_checks.md`](docs/writing_checks.md)
234
+ - Integrating a tool: [`docs/integrating_tools.md`](docs/integrating_tools.md)
235
+
236
+ A new scanner subclasses `BaseScanner` and uses `@register_scanner`. A new check uses `@register_check`. A report subclasses `BaseReporter` and implements `generate()`. An LLM backend subclasses `BaseLLMBackend` and implements `complete()`.
237
+
238
+ ## Limitations
239
+
240
+ - Black-box only. No source code analysis.
241
+ - Target auth methods on `AuthConfig` are `none`, `cookie`, `header` and `form`.
242
+ - LLM features need an API key and have a cost. They are optional.
243
+ - Email verification needs SMTP. Without it, an admin activates accounts.
244
+ - A security professional should confirm a finding before anyone acts on it.
245
+ - External scanner results depend on those tools being installed.
246
+
247
+ ## Legal
248
+
249
+ For authorised testing only. See [LEGAL_NOTICE.md](LEGAL_NOTICE.md).
250
+
251
+ ## License
252
+
253
+ MIT. See [LICENSE](LICENSE).
haris-0.7.0/README.md ADDED
@@ -0,0 +1,212 @@
1
+ <p align="center">
2
+ <img src="assets/haris_logo.png" alt="HARIS" width="400"><br>
3
+ <em>Black-box web security audit framework. Scan, correlate, prioritise, remediate.</em><br><br>
4
+ <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License"></a>
5
+ <a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.13+-blue.svg" alt="Python"></a>
6
+ <a href="https://owasp.org/www-project-top-ten/"><img src="https://img.shields.io/badge/OWASP-Top%2010%202025-red.svg" alt="OWASP"></a>
7
+ </p>
8
+
9
+ Orchestrates security scanners, correlates findings, and writes one prioritised report. LLM analysis is optional.
10
+
11
+ ## What this does
12
+
13
+ 1. **Cross-tool correlation.** Findings that share a fingerprint become one finding. The score combines the scanners that reported it.
14
+ 2. **Cross-scanner context.** Built-in checks and nmap fill a `ScanContext`. Later scanners read it. Nuclei uses detected technologies in phase 2b.
15
+ 3. **Business-risk text.** Plain-language impact sits next to the technical finding.
16
+ 4. **Prioritised remediation.** Fixes are grouped and ordered by impact and effort.
17
+ 5. **Profiles.** `quick`, `pre-launch`, `full`, `ai-security`, `regression`, `compliance`.
18
+ 6. **Scan templates.** Named presets with per-scanner overrides, stored and reused from the web UI.
19
+ 7. **LLM analysis.** Q&A, Jira text, test cases and enrichment, from the scan data.
20
+ 8. **OWASP Top 10 (2025).** Findings are mapped, including Software Supply Chain Failures and Mishandling of Exceptional Conditions.
21
+ 9. **Verification.** Replay oracles, an optional LLM verdict, and an opt-in agent. A refuted finding stays in the report. See [`docs/verification.md`](docs/verification.md).
22
+
23
+ ## Scanners
24
+
25
+ | Scanner | What it tests | Install | Version recorded |
26
+ | ------- | ------------- | ------- | ---------------- |
27
+ | Wapiti | SQLi, XSS, SSRF, command injection, CRLF, XXE | `pipx install wapiti3` | 3.3 |
28
+ | SSLyze | TLS protocols, cipher suites, certificate chain, Heartbleed, ROBOT | `pipx install sslyze` | 6.x |
29
+ | Nmap | Open ports, service versions, exposed databases | system package manager | 7.x |
30
+ | Nikto | Web server misconfigurations, outdated software, dangerous files | `brew install nikto` | 2.x |
31
+ | Nuclei | CVE checks, default credentials, exposed panels, tech fingerprint (phase 1, 2a, 2b) | `brew install nuclei` | 3.x |
32
+ | ZAP | Active and passive web scan. Off by default and in no profile. `--scanners zap` | [ZAP download](https://www.zaproxy.org/download/) | 2.16 |
33
+ | garak | Injection and leakage probes on a discovered chat route. Runs only with `--ai-active` and `--i-have-authorization` | install the binary | 0.17 |
34
+ | promptfoo | Red-team plugins on a discovered chat route. Same flags as garak | install the binary | 0.125 |
35
+
36
+ The version column is the adapter `version` attribute. The Wapiti docstring names 3.3.2. The Nikto docstring names 2.6. Nuclei fixtures in `tests/fixtures/scanners/README.md` are 3.7.1. `garak.yaml` comments 0.17.1 and `promptfoo.yaml` comments 0.125.1. HARIS does not check the tool version at runtime.
37
+
38
+ Install Wapiti and SSLyze with `pipx`, outside the HARIS environment.
39
+
40
+ ## Built-in checks
41
+
42
+ Fourteen checks. `quick` runs every check except `ai_security`.
43
+
44
+ | Check | What it tests |
45
+ | ----- | ------------- |
46
+ | `header_checks` | Six headers: HSTS, CSP, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy. Also weak CSP or HSTS, a versioned Server banner, and any X-Powered-By header |
47
+ | `tls_checks` | Certificate and TLS basics |
48
+ | `misc_checks` | CORS, HTTP to HTTPS redirect, 14 sensitive paths |
49
+ | `info_disclosure` | Error pages, debug endpoints, HTML comments |
50
+ | `cookie_checks` | Session cookie flags, scope, expiry and name |
51
+ | `sri_checks` | Subresource Integrity on third-party resources |
52
+ | `cache_checks` | Cache-Control on login, account and session-setting responses |
53
+ | `method_checks` | OPTIONS advertisement and TRACE |
54
+ | `redirect_checks` | Open redirect via common redirect parameters |
55
+ | `graphql_checks` | GraphQL introspection |
56
+ | `openapi_checks` | Exposed OpenAPI or Swagger documents |
57
+ | `listing_checks` | Directory listing |
58
+ | `dns_checks` | CAA, SPF and DMARC |
59
+ | `ai_security` | AI endpoints and MCP servers. Prompts only with `--ai-active` and `--i-have-authorization`. See [`docs/ai_security.md`](docs/ai_security.md) |
60
+
61
+ The 14 sensitive paths are `/.env`, `/.git/config`, `/robots.txt`, `/sitemap.xml`, `/.well-known/security.txt`, `/wp-login.php`, `/admin`, `/phpmyadmin`, `/server-status`, `/server-info`, `/.DS_Store`, `/crossdomain.xml`, `/elmah.axd` and `/trace.axd`.
62
+
63
+ ## Setup
64
+
65
+ The console script is `haris`, entry point `haris.cli:main`.
66
+
67
+ ```bash
68
+ git clone https://github.com/calghar/HARIS
69
+ cd HARIS
70
+ uv sync --extra web --extra reporting
71
+ uv run haris --help
72
+ ```
73
+
74
+ Nmap, Nikto, Nuclei, SSLyze, Wapiti and optional ZAP, garak and promptfoo are separate programs. For LLM features set `ANTHROPIC_API_KEY` or `OPENAI_API_KEY`. Ollama needs no key. Its client uses `http://localhost:11434` unless the backend is constructed with another base URL.
75
+
76
+ ## Authentication
77
+
78
+ The web dashboard requires login. On first start an admin account is created from:
79
+
80
+ ```bash
81
+ HARIS_ADMIN_EMAIL=admin@example.com
82
+ HARIS_ADMIN_PASSWORD=changeme123
83
+ HARIS_SECRET_KEY=<random-32-char-string> # python -c "import secrets; print(secrets.token_hex(32))"
84
+ ```
85
+
86
+ Startup creates that admin when both `HARIS_ADMIN_EMAIL` and `HARIS_ADMIN_PASSWORD` are set and the user table is empty. `/auth/setup` answers 404 until `HARIS_SETUP_TOKEN` is set, and once a user exists.
87
+
88
+ Self-registration uses `HARIS_ALLOWED_EMAIL_DOMAINS`. New accounts need email verification, or an admin activates them when SMTP is off.
89
+
90
+ Roles are `admin` and `user`. An admin manages users, settings, and any user's scans and templates. A user scans, and views and deletes their own scans, and uses Q&A.
91
+
92
+ OIDC uses `HARIS_OIDC_ENABLED=true` plus `HARIS_OIDC_ISSUER`, `HARIS_OIDC_CLIENT_ID` and `HARIS_OIDC_CLIENT_SECRET`. See [`docs/authentication.md`](docs/authentication.md).
93
+
94
+ ## Usage
95
+
96
+ ```bash
97
+ # CLI. --verify defaults to replay (off, replay, llm).
98
+ uv run haris --url https://example.com --profile quick --yes
99
+ uv run haris --list-profiles
100
+
101
+ # Web dashboard. Bind defaults are 127.0.0.1 and port 8000.
102
+ uv run haris --web
103
+
104
+ # Docker
105
+ docker compose up
106
+ docker compose run --rm cli --url https://example.com --profile quick --yes
107
+ make reload
108
+
109
+ # LLM analysis after a scan
110
+ uv run haris llm ask --scan-id <id> --question "Top 3 risks for an exec"
111
+ uv run haris llm remediate --scan-id <id> --format jira
112
+ uv run haris llm summarize --scan-id <id> --audience developer
113
+
114
+ # In-pipeline LLM enrichment
115
+ uv run haris --url https://example.com --profile quick --yes --llm-enrich
116
+
117
+ # Scanner template updates
118
+ uv run haris update-templates
119
+ uv run haris update-templates --scanner nuclei --list
120
+ ```
121
+
122
+ ## Scan profiles
123
+
124
+ Estimates are the `estimated_duration` strings on each profile.
125
+
126
+ | Profile | Scanners | Use |
127
+ | ------- | -------- | --- |
128
+ | `quick` | The 13 built-in checks other than `ai_security` | First look. 1-3 minutes |
129
+ | `pre-launch` | `quick` plus `nmap`, `sslyze`, `wapiti` | Before production. 10-30 minutes |
130
+ | `full` | `pre-launch` plus `nikto`, `nuclei` | Full audit. 20-30 minutes. ZAP, garak and promptfoo are absent |
131
+ | `ai-security` | `header_checks`, `tls_checks`, `info_disclosure`, `ai_security`, `garak`, `promptfoo` | AI endpoints. 1-10 minutes |
132
+ | `regression` | `header_checks`, `tls_checks`, `misc_checks` | CI gate. 30-60 seconds |
133
+ | `compliance` | `header_checks`, `tls_checks`, `misc_checks`, `info_disclosure`, `cookie_checks`, `nmap`, `sslyze` | TLS, headers, cookies, disclosure, ports. 5-15 minutes |
134
+
135
+ ## Configuration
136
+
137
+ Copy `.env.example` to `.env`. The option file is `src/haris/resources/config/default_config.yaml`. Override it with `HARIS_CONFIG` or `./config/default_config.yaml` in the working directory.
138
+
139
+ | Variable | Purpose |
140
+ | -------- | ------- |
141
+ | `HARIS_ADMIN_EMAIL` | Bootstrap admin email, used on first start when no users exist |
142
+ | `HARIS_ADMIN_PASSWORD` | Bootstrap admin password |
143
+ | `HARIS_SECRET_KEY` | Session signing secret |
144
+ | `HARIS_TARGET_URL` | Default scan target |
145
+ | `HARIS_PROFILE` | Default scan profile |
146
+ | `HARIS_AUTH_HEADER` | Auth header value for the target |
147
+ | `HARIS_AUTH_COOKIE` | Auth cookie value for the target |
148
+ | `HARIS_AUTH_USERNAME` | Auth username for the target |
149
+ | `HARIS_AUTH_PASSWORD` | Auth password for the target |
150
+ | `ANTHROPIC_API_KEY` | Anthropic LLM backend |
151
+ | `OPENAI_API_KEY` | OpenAI LLM backend |
152
+ | `HARIS_OIDC_CLIENT_SECRET` | OIDC client secret |
153
+ | `HARIS_SMTP_USERNAME` | SMTP username for email verification |
154
+ | `HARIS_SMTP_PASSWORD` | SMTP password |
155
+
156
+ `OLLAMA_BASE_URL` is not read. The Ollama client default is the constructor argument above.
157
+
158
+ Web server variables. Flags accept `1`, `true` or `yes`, except where noted.
159
+
160
+ | Variable | Default | Effect |
161
+ | -------- | ------- | ------ |
162
+ | `HARIS_WEB_VERIFY_DEFAULT` | `replay` | Verification mode for web scans when the request sets none: `off`, `replay` or `llm` |
163
+ | `HARIS_TARGET_ALLOWLIST` | empty | Comma-separated host globs that skip ownership proof |
164
+ | `HARIS_ALLOW_PRIVATE_TARGETS` | `false` | Allow private and loopback target addresses. Only the value `true` enables it |
165
+ | `HARIS_SHARE_SCANS_ORG_WIDE` | `false` | Every user can read all scans. Only owners and admins can change them |
166
+ | `HARIS_AGENT_DISABLED` | unset | The value `1` stops the agent from running on any scan |
167
+ | `HARIS_MAX_CONCURRENT_SCANS` | `2` | Scans that run at once. At least 1 |
168
+ | `HARIS_FORCE_HTTPS` | `false` | Redirect `http://` requests to `https://` |
169
+ | `HARIS_ALLOWED_EMAIL_DOMAINS` | `techforpalestine.org` | Comma-separated registration domains. Empty allows any |
170
+ | `HARIS_OIDC_ENABLED` | `false` | Turn on OIDC sign-in |
171
+ | `HARIS_OIDC_ISSUER`, `HARIS_OIDC_CLIENT_ID` | empty | OIDC provider issuer URL and client ID |
172
+ | `HARIS_SMTP_ENABLED` | `false` | Send verification email. Otherwise the link is logged |
173
+ | `HARIS_SMTP_HOST`, `HARIS_SMTP_PORT` | `localhost`, `587` | SMTP server |
174
+ | `HARIS_SMTP_USE_TLS` | `true` | Any value other than `false` keeps TLS on |
175
+ | `HARIS_SMTP_FROM`, `HARIS_SMTP_FROM_NAME` | `noreply@techforpalestine.org`, `HARIS Security Platform` | Sender address and name |
176
+ | `HARIS_PUBLIC_URL` | unset | When set, the only base for emailed verification links. When unset, SMTP does not send and the link is logged from the request base URL |
177
+ | `HARIS_ALLOWED_HOSTS` | unset | Comma-separated hosts. When set, any other Host header is rejected and www redirect is off. When unset, there is no host check |
178
+ | `HARIS_COOKIE_SECURE` | `auto` | `true` forces the Secure flag and `false` omits it. Any other value, including `1` and `yes`, follows the request scheme. Session cookie and CSRF seed cookie |
179
+ | `HARIS_SETUP_TOKEN` | unset | `/auth/setup` answers 404 until this is set, and once a user exists. The form field `setup_token` is compared with this value |
180
+
181
+ ## Documentation
182
+
183
+ - Architecture: [`docs/architecture.md`](docs/architecture.md)
184
+ - Methodology: [`docs/methodology.md`](docs/methodology.md)
185
+ - Verification: [`docs/verification.md`](docs/verification.md)
186
+ - Benchmarks: [`docs/benchmarks.md`](docs/benchmarks.md)
187
+ - Agent safety: [`docs/agent_safety.md`](docs/agent_safety.md)
188
+ - AI security: [`docs/ai_security.md`](docs/ai_security.md)
189
+ - Authentication: [`docs/authentication.md`](docs/authentication.md)
190
+ - LLM integration: [`docs/llm_integration.md`](docs/llm_integration.md)
191
+ - CI integrations: [`docs/integrations.md`](docs/integrations.md)
192
+ - Writing a check: [`docs/writing_checks.md`](docs/writing_checks.md)
193
+ - Integrating a tool: [`docs/integrating_tools.md`](docs/integrating_tools.md)
194
+
195
+ A new scanner subclasses `BaseScanner` and uses `@register_scanner`. A new check uses `@register_check`. A report subclasses `BaseReporter` and implements `generate()`. An LLM backend subclasses `BaseLLMBackend` and implements `complete()`.
196
+
197
+ ## Limitations
198
+
199
+ - Black-box only. No source code analysis.
200
+ - Target auth methods on `AuthConfig` are `none`, `cookie`, `header` and `form`.
201
+ - LLM features need an API key and have a cost. They are optional.
202
+ - Email verification needs SMTP. Without it, an admin activates accounts.
203
+ - A security professional should confirm a finding before anyone acts on it.
204
+ - External scanner results depend on those tools being installed.
205
+
206
+ ## Legal
207
+
208
+ For authorised testing only. See [LEGAL_NOTICE.md](LEGAL_NOTICE.md).
209
+
210
+ ## License
211
+
212
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,138 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "haris"
7
+ version = "0.7.0"
8
+ description = "Black-box web application security audit framework"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ requires-python = ">=3.13"
12
+ authors = [
13
+ {name = "HARIS contributors"},
14
+ ]
15
+ keywords = ["security", "audit", "pentest", "owasp", "vulnerability-scanner"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Intended Audience :: Developers",
19
+ "Intended Audience :: Information Technology",
20
+ "License :: OSI Approved :: MIT License",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Programming Language :: Python :: 3.14",
24
+ "Topic :: Security",
25
+ ]
26
+
27
+ dependencies = [
28
+ "pydantic>=2.14.3",
29
+ "requests>=2.34.2",
30
+ "pyyaml>=6.0.3",
31
+ "jinja2>=3.1.6",
32
+ "openai>=3.46.0",
33
+ "anthropic>=2.6.0",
34
+ "bcrypt>=5.0.0",
35
+ "starlette>=1.10.0",
36
+ "yoyo-migrations>=9.0.0",
37
+ ]
38
+
39
+ [project.optional-dependencies]
40
+ # Web dashboard
41
+ web = [
42
+ "fastapi>=0.162.2",
43
+ "uvicorn[standard]>=0.54.0",
44
+ "python-multipart>=0.0.33",
45
+ "authlib>=1.9.5",
46
+ "httpx>=0.28.1",
47
+ "itsdangerous>=2.2.0",
48
+ "dnspython>=2.8.0",
49
+ ]
50
+ # Report generation extras
51
+ reporting = [
52
+ "markdown>=3.11.3",
53
+ ]
54
+ # Everything installable alongside the web dashboard
55
+ all = [
56
+ "haris[web,reporting]",
57
+ ]
58
+
59
+ [dependency-groups]
60
+ dev = [
61
+ "pytest>=9.2.0",
62
+ "pytest-cov>=7.1.0",
63
+ "ruff>=0.17.4",
64
+ "mypy>=2.4.1",
65
+ "types-requests",
66
+ "types-PyYAML",
67
+ "types-authlib",
68
+ "bandit[toml]>=1.9.4",
69
+ "pip-audit>=2.10.1",
70
+ "pre-commit>=4.7.0",
71
+ "jsonschema>=4.26.0",
72
+ "types-jsonschema>=4.26.0.20261006",
73
+ ]
74
+ docs = [
75
+ "mkdocs-material>=9.8.1",
76
+ ]
77
+
78
+ [project.scripts]
79
+ haris = "haris.cli:main"
80
+
81
+ [tool.setuptools.packages.find]
82
+ where = ["src"]
83
+ include = ["haris*"]
84
+
85
+ [tool.setuptools.package-data]
86
+ haris = [
87
+ "web/templates/**/*",
88
+ "web/static/**/*",
89
+ "llm/templates/**/*",
90
+ "resources/config/**/*",
91
+ "resources/schema/**/*",
92
+ "db/migrations/*",
93
+ ]
94
+
95
+ [tool.pytest.ini_options]
96
+ testpaths = ["tests"]
97
+ addopts = "-v --tb=short"
98
+ markers = [
99
+ "docker: requires a local Docker daemon and the haris-agent-sandbox image",
100
+ ]
101
+ filterwarnings = ["ignore:The default datetime adapter:DeprecationWarning"]
102
+
103
+ [tool.ruff]
104
+ target-version = "py313"
105
+ line-length = 88
106
+
107
+ [tool.ruff.lint]
108
+ select = ["E", "F", "W", "I", "N", "UP", "B", "SIM", "TID251"]
109
+ # B008: FastAPI's Depends() in function defaults is the standard DI pattern
110
+ ignore = ["B008"]
111
+
112
+ [tool.ruff.lint.flake8-tidy-imports.banned-api]
113
+ "requests".msg = "Send HTTP through haris.net.ScopedClient."
114
+ "httpx".msg = "Send HTTP through haris.net.ScopedClient."
115
+ "urllib3".msg = "Send HTTP through haris.net.ScopedClient."
116
+
117
+ [tool.ruff.lint.per-file-ignores]
118
+ "src/haris/net/**" = ["TID251"]
119
+ # LLM provider SDK calls; not target traffic
120
+ "src/haris/llm/providers.py" = ["TID251"]
121
+ # Fake transports and test servers
122
+ "tests/**" = ["TID251"]
123
+ # Benchmark harness talks to its own local fixtures
124
+ "bench/**" = ["TID251"]
125
+
126
+ [tool.mypy]
127
+ python_version = "3.13"
128
+ warn_return_any = true
129
+ warn_unused_configs = true
130
+
131
+ [[tool.mypy.overrides]]
132
+ module = "yoyo.*"
133
+ ignore_missing_imports = true
134
+
135
+ [tool.bandit]
136
+ exclude_dirs = ["tests", ".venv", "venv"]
137
+ # B603/B607: scanners intentionally call external tools (nmap, nuclei, etc.) by name
138
+ skips = ["B603", "B607"]
haris-0.7.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,6 @@
1
+ from importlib.metadata import PackageNotFoundError, version
2
+
3
+ try:
4
+ __version__ = version("haris")
5
+ except PackageNotFoundError:
6
+ __version__ = "0+unknown"
@@ -0,0 +1,5 @@
1
+ import sys
2
+
3
+ from .cli import main
4
+
5
+ sys.exit(main())
@@ -0,0 +1,21 @@
1
+ from .policy import (
2
+ AgentPolicy,
3
+ activation_result,
4
+ bind_cli,
5
+ bind_policy,
6
+ current_policy,
7
+ policy_for_web,
8
+ reset_policy,
9
+ )
10
+ from .stages import note_stage
11
+
12
+ __all__ = [
13
+ "AgentPolicy",
14
+ "activation_result",
15
+ "bind_cli",
16
+ "bind_policy",
17
+ "current_policy",
18
+ "note_stage",
19
+ "policy_for_web",
20
+ "reset_policy",
21
+ ]