regscale-cli 6.16.0.0__py3-none-any.whl

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.

Potentially problematic release.


This version of regscale-cli might be problematic. Click here for more details.

Files changed (481) hide show
  1. regscale/__init__.py +1 -0
  2. regscale/airflow/__init__.py +9 -0
  3. regscale/airflow/azure/__init__.py +9 -0
  4. regscale/airflow/azure/cli.py +89 -0
  5. regscale/airflow/azure/upload_dags.py +116 -0
  6. regscale/airflow/click_dags.py +127 -0
  7. regscale/airflow/click_mixins.py +82 -0
  8. regscale/airflow/config.py +25 -0
  9. regscale/airflow/factories/__init__.py +0 -0
  10. regscale/airflow/factories/connections.py +58 -0
  11. regscale/airflow/factories/workflows.py +78 -0
  12. regscale/airflow/hierarchy.py +88 -0
  13. regscale/airflow/operators/__init__.py +0 -0
  14. regscale/airflow/operators/click.py +36 -0
  15. regscale/airflow/sensors/__init__.py +0 -0
  16. regscale/airflow/sensors/sql.py +107 -0
  17. regscale/airflow/sessions/__init__.py +0 -0
  18. regscale/airflow/sessions/sql/__init__.py +3 -0
  19. regscale/airflow/sessions/sql/queries.py +64 -0
  20. regscale/airflow/sessions/sql/sql_server_queries.py +248 -0
  21. regscale/airflow/tasks/__init__.py +0 -0
  22. regscale/airflow/tasks/branches.py +22 -0
  23. regscale/airflow/tasks/cli.py +116 -0
  24. regscale/airflow/tasks/click.py +73 -0
  25. regscale/airflow/tasks/debugging.py +9 -0
  26. regscale/airflow/tasks/groups.py +116 -0
  27. regscale/airflow/tasks/init.py +60 -0
  28. regscale/airflow/tasks/states.py +47 -0
  29. regscale/airflow/tasks/workflows.py +36 -0
  30. regscale/ansible/__init__.py +9 -0
  31. regscale/core/__init__.py +0 -0
  32. regscale/core/app/__init__.py +3 -0
  33. regscale/core/app/api.py +571 -0
  34. regscale/core/app/application.py +665 -0
  35. regscale/core/app/internal/__init__.py +136 -0
  36. regscale/core/app/internal/admin_actions.py +230 -0
  37. regscale/core/app/internal/assessments_editor.py +873 -0
  38. regscale/core/app/internal/catalog.py +316 -0
  39. regscale/core/app/internal/comparison.py +459 -0
  40. regscale/core/app/internal/control_editor.py +571 -0
  41. regscale/core/app/internal/encrypt.py +79 -0
  42. regscale/core/app/internal/evidence.py +1240 -0
  43. regscale/core/app/internal/file_uploads.py +151 -0
  44. regscale/core/app/internal/healthcheck.py +66 -0
  45. regscale/core/app/internal/login.py +305 -0
  46. regscale/core/app/internal/migrations.py +240 -0
  47. regscale/core/app/internal/model_editor.py +1701 -0
  48. regscale/core/app/internal/poam_editor.py +632 -0
  49. regscale/core/app/internal/workflow.py +105 -0
  50. regscale/core/app/logz.py +74 -0
  51. regscale/core/app/utils/XMLIR.py +258 -0
  52. regscale/core/app/utils/__init__.py +0 -0
  53. regscale/core/app/utils/api_handler.py +358 -0
  54. regscale/core/app/utils/app_utils.py +1110 -0
  55. regscale/core/app/utils/catalog_utils/__init__.py +0 -0
  56. regscale/core/app/utils/catalog_utils/common.py +91 -0
  57. regscale/core/app/utils/catalog_utils/compare_catalog.py +193 -0
  58. regscale/core/app/utils/catalog_utils/diagnostic_catalog.py +97 -0
  59. regscale/core/app/utils/catalog_utils/download_catalog.py +103 -0
  60. regscale/core/app/utils/catalog_utils/update_catalog.py +718 -0
  61. regscale/core/app/utils/catalog_utils/update_catalog_v2.py +1378 -0
  62. regscale/core/app/utils/catalog_utils/update_catalog_v3.py +1272 -0
  63. regscale/core/app/utils/catalog_utils/update_plans.py +334 -0
  64. regscale/core/app/utils/file_utils.py +238 -0
  65. regscale/core/app/utils/parser_utils.py +81 -0
  66. regscale/core/app/utils/pickle_file_handler.py +57 -0
  67. regscale/core/app/utils/regscale_utils.py +319 -0
  68. regscale/core/app/utils/report_utils.py +119 -0
  69. regscale/core/app/utils/variables.py +226 -0
  70. regscale/core/decorators.py +31 -0
  71. regscale/core/lazy_group.py +65 -0
  72. regscale/core/login.py +63 -0
  73. regscale/core/server/__init__.py +0 -0
  74. regscale/core/server/flask_api.py +473 -0
  75. regscale/core/server/helpers.py +373 -0
  76. regscale/core/server/rest.py +64 -0
  77. regscale/core/server/static/css/bootstrap.css +6030 -0
  78. regscale/core/server/static/css/bootstrap.min.css +6 -0
  79. regscale/core/server/static/css/main.css +176 -0
  80. regscale/core/server/static/images/regscale-cli.svg +49 -0
  81. regscale/core/server/static/images/regscale.svg +38 -0
  82. regscale/core/server/templates/base.html +74 -0
  83. regscale/core/server/templates/index.html +43 -0
  84. regscale/core/server/templates/login.html +28 -0
  85. regscale/core/server/templates/make_base64.html +22 -0
  86. regscale/core/server/templates/upload_STIG.html +109 -0
  87. regscale/core/server/templates/upload_STIG_result.html +26 -0
  88. regscale/core/server/templates/upload_ssp.html +144 -0
  89. regscale/core/server/templates/upload_ssp_result.html +128 -0
  90. regscale/core/static/__init__.py +0 -0
  91. regscale/core/static/regex.py +14 -0
  92. regscale/core/utils/__init__.py +117 -0
  93. regscale/core/utils/click_utils.py +13 -0
  94. regscale/core/utils/date.py +238 -0
  95. regscale/core/utils/graphql.py +254 -0
  96. regscale/core/utils/urls.py +23 -0
  97. regscale/dev/__init__.py +6 -0
  98. regscale/dev/analysis.py +454 -0
  99. regscale/dev/cli.py +235 -0
  100. regscale/dev/code_gen.py +492 -0
  101. regscale/dev/dirs.py +69 -0
  102. regscale/dev/docs.py +384 -0
  103. regscale/dev/monitoring.py +26 -0
  104. regscale/dev/profiling.py +216 -0
  105. regscale/exceptions/__init__.py +4 -0
  106. regscale/exceptions/license_exception.py +7 -0
  107. regscale/exceptions/validation_exception.py +9 -0
  108. regscale/integrations/__init__.py +1 -0
  109. regscale/integrations/commercial/__init__.py +486 -0
  110. regscale/integrations/commercial/ad.py +433 -0
  111. regscale/integrations/commercial/amazon/__init__.py +0 -0
  112. regscale/integrations/commercial/amazon/common.py +106 -0
  113. regscale/integrations/commercial/aqua/__init__.py +0 -0
  114. regscale/integrations/commercial/aqua/aqua.py +91 -0
  115. regscale/integrations/commercial/aws/__init__.py +6 -0
  116. regscale/integrations/commercial/aws/cli.py +322 -0
  117. regscale/integrations/commercial/aws/inventory/__init__.py +110 -0
  118. regscale/integrations/commercial/aws/inventory/base.py +64 -0
  119. regscale/integrations/commercial/aws/inventory/resources/__init__.py +19 -0
  120. regscale/integrations/commercial/aws/inventory/resources/compute.py +234 -0
  121. regscale/integrations/commercial/aws/inventory/resources/containers.py +113 -0
  122. regscale/integrations/commercial/aws/inventory/resources/database.py +101 -0
  123. regscale/integrations/commercial/aws/inventory/resources/integration.py +237 -0
  124. regscale/integrations/commercial/aws/inventory/resources/networking.py +253 -0
  125. regscale/integrations/commercial/aws/inventory/resources/security.py +240 -0
  126. regscale/integrations/commercial/aws/inventory/resources/storage.py +91 -0
  127. regscale/integrations/commercial/aws/scanner.py +823 -0
  128. regscale/integrations/commercial/azure/__init__.py +0 -0
  129. regscale/integrations/commercial/azure/common.py +32 -0
  130. regscale/integrations/commercial/azure/intune.py +488 -0
  131. regscale/integrations/commercial/azure/scanner.py +49 -0
  132. regscale/integrations/commercial/burp.py +78 -0
  133. regscale/integrations/commercial/cpe.py +144 -0
  134. regscale/integrations/commercial/crowdstrike.py +1117 -0
  135. regscale/integrations/commercial/defender.py +1511 -0
  136. regscale/integrations/commercial/dependabot.py +210 -0
  137. regscale/integrations/commercial/durosuite/__init__.py +0 -0
  138. regscale/integrations/commercial/durosuite/api.py +1546 -0
  139. regscale/integrations/commercial/durosuite/process_devices.py +101 -0
  140. regscale/integrations/commercial/durosuite/scanner.py +637 -0
  141. regscale/integrations/commercial/durosuite/variables.py +21 -0
  142. regscale/integrations/commercial/ecr.py +90 -0
  143. regscale/integrations/commercial/gcp/__init__.py +237 -0
  144. regscale/integrations/commercial/gcp/auth.py +96 -0
  145. regscale/integrations/commercial/gcp/control_tests.py +238 -0
  146. regscale/integrations/commercial/gcp/variables.py +18 -0
  147. regscale/integrations/commercial/gitlab.py +332 -0
  148. regscale/integrations/commercial/grype.py +165 -0
  149. regscale/integrations/commercial/ibm.py +90 -0
  150. regscale/integrations/commercial/import_all/__init__.py +0 -0
  151. regscale/integrations/commercial/import_all/import_all_cmd.py +467 -0
  152. regscale/integrations/commercial/import_all/scan_file_fingerprints.json +27 -0
  153. regscale/integrations/commercial/jira.py +1046 -0
  154. regscale/integrations/commercial/mappings/__init__.py +0 -0
  155. regscale/integrations/commercial/mappings/csf_controls.json +713 -0
  156. regscale/integrations/commercial/mappings/nist_800_53_r5_controls.json +1516 -0
  157. regscale/integrations/commercial/nessus/__init__.py +0 -0
  158. regscale/integrations/commercial/nessus/nessus_utils.py +429 -0
  159. regscale/integrations/commercial/nessus/scanner.py +416 -0
  160. regscale/integrations/commercial/nexpose.py +90 -0
  161. regscale/integrations/commercial/okta.py +798 -0
  162. regscale/integrations/commercial/opentext/__init__.py +0 -0
  163. regscale/integrations/commercial/opentext/click.py +99 -0
  164. regscale/integrations/commercial/opentext/scanner.py +143 -0
  165. regscale/integrations/commercial/prisma.py +91 -0
  166. regscale/integrations/commercial/qualys.py +1462 -0
  167. regscale/integrations/commercial/salesforce.py +980 -0
  168. regscale/integrations/commercial/sap/__init__.py +0 -0
  169. regscale/integrations/commercial/sap/click.py +31 -0
  170. regscale/integrations/commercial/sap/sysdig/__init__.py +0 -0
  171. regscale/integrations/commercial/sap/sysdig/click.py +57 -0
  172. regscale/integrations/commercial/sap/sysdig/sysdig_scanner.py +190 -0
  173. regscale/integrations/commercial/sap/tenable/__init__.py +0 -0
  174. regscale/integrations/commercial/sap/tenable/click.py +49 -0
  175. regscale/integrations/commercial/sap/tenable/scanner.py +196 -0
  176. regscale/integrations/commercial/servicenow.py +1756 -0
  177. regscale/integrations/commercial/sicura/__init__.py +0 -0
  178. regscale/integrations/commercial/sicura/api.py +855 -0
  179. regscale/integrations/commercial/sicura/commands.py +73 -0
  180. regscale/integrations/commercial/sicura/scanner.py +481 -0
  181. regscale/integrations/commercial/sicura/variables.py +16 -0
  182. regscale/integrations/commercial/snyk.py +90 -0
  183. regscale/integrations/commercial/sonarcloud.py +260 -0
  184. regscale/integrations/commercial/sqlserver.py +369 -0
  185. regscale/integrations/commercial/stig_mapper_integration/__init__.py +0 -0
  186. regscale/integrations/commercial/stig_mapper_integration/click_commands.py +38 -0
  187. regscale/integrations/commercial/stig_mapper_integration/mapping_engine.py +353 -0
  188. regscale/integrations/commercial/stigv2/__init__.py +0 -0
  189. regscale/integrations/commercial/stigv2/ckl_parser.py +349 -0
  190. regscale/integrations/commercial/stigv2/click_commands.py +95 -0
  191. regscale/integrations/commercial/stigv2/stig_integration.py +202 -0
  192. regscale/integrations/commercial/synqly/__init__.py +0 -0
  193. regscale/integrations/commercial/synqly/assets.py +46 -0
  194. regscale/integrations/commercial/synqly/ticketing.py +132 -0
  195. regscale/integrations/commercial/synqly/vulnerabilities.py +223 -0
  196. regscale/integrations/commercial/synqly_jira.py +840 -0
  197. regscale/integrations/commercial/tenablev2/__init__.py +0 -0
  198. regscale/integrations/commercial/tenablev2/authenticate.py +31 -0
  199. regscale/integrations/commercial/tenablev2/click.py +1584 -0
  200. regscale/integrations/commercial/tenablev2/scanner.py +504 -0
  201. regscale/integrations/commercial/tenablev2/stig_parsers.py +140 -0
  202. regscale/integrations/commercial/tenablev2/utils.py +78 -0
  203. regscale/integrations/commercial/tenablev2/variables.py +17 -0
  204. regscale/integrations/commercial/trivy.py +162 -0
  205. regscale/integrations/commercial/veracode.py +96 -0
  206. regscale/integrations/commercial/wizv2/WizDataMixin.py +97 -0
  207. regscale/integrations/commercial/wizv2/__init__.py +0 -0
  208. regscale/integrations/commercial/wizv2/click.py +429 -0
  209. regscale/integrations/commercial/wizv2/constants.py +1001 -0
  210. regscale/integrations/commercial/wizv2/issue.py +361 -0
  211. regscale/integrations/commercial/wizv2/models.py +112 -0
  212. regscale/integrations/commercial/wizv2/parsers.py +339 -0
  213. regscale/integrations/commercial/wizv2/sbom.py +115 -0
  214. regscale/integrations/commercial/wizv2/scanner.py +416 -0
  215. regscale/integrations/commercial/wizv2/utils.py +796 -0
  216. regscale/integrations/commercial/wizv2/variables.py +39 -0
  217. regscale/integrations/commercial/wizv2/wiz_auth.py +159 -0
  218. regscale/integrations/commercial/xray.py +91 -0
  219. regscale/integrations/integration/__init__.py +2 -0
  220. regscale/integrations/integration/integration.py +26 -0
  221. regscale/integrations/integration/inventory.py +17 -0
  222. regscale/integrations/integration/issue.py +100 -0
  223. regscale/integrations/integration_override.py +149 -0
  224. regscale/integrations/public/__init__.py +103 -0
  225. regscale/integrations/public/cisa.py +641 -0
  226. regscale/integrations/public/criticality_updater.py +70 -0
  227. regscale/integrations/public/emass.py +411 -0
  228. regscale/integrations/public/emass_slcm_import.py +697 -0
  229. regscale/integrations/public/fedramp/__init__.py +0 -0
  230. regscale/integrations/public/fedramp/appendix_parser.py +548 -0
  231. regscale/integrations/public/fedramp/click.py +479 -0
  232. regscale/integrations/public/fedramp/components.py +714 -0
  233. regscale/integrations/public/fedramp/docx_parser.py +259 -0
  234. regscale/integrations/public/fedramp/fedramp_cis_crm.py +1124 -0
  235. regscale/integrations/public/fedramp/fedramp_common.py +3181 -0
  236. regscale/integrations/public/fedramp/fedramp_docx.py +388 -0
  237. regscale/integrations/public/fedramp/fedramp_five.py +2343 -0
  238. regscale/integrations/public/fedramp/fedramp_traversal.py +138 -0
  239. regscale/integrations/public/fedramp/import_fedramp_r4_ssp.py +279 -0
  240. regscale/integrations/public/fedramp/import_workbook.py +495 -0
  241. regscale/integrations/public/fedramp/inventory_items.py +244 -0
  242. regscale/integrations/public/fedramp/mappings/__init__.py +0 -0
  243. regscale/integrations/public/fedramp/mappings/fedramp_r4_parts.json +7388 -0
  244. regscale/integrations/public/fedramp/mappings/fedramp_r5_params.json +8636 -0
  245. regscale/integrations/public/fedramp/mappings/fedramp_r5_parts.json +9605 -0
  246. regscale/integrations/public/fedramp/mappings/system_roles.py +34 -0
  247. regscale/integrations/public/fedramp/mappings/user.py +175 -0
  248. regscale/integrations/public/fedramp/mappings/values.py +141 -0
  249. regscale/integrations/public/fedramp/markdown_parser.py +150 -0
  250. regscale/integrations/public/fedramp/metadata.py +689 -0
  251. regscale/integrations/public/fedramp/models/__init__.py +59 -0
  252. regscale/integrations/public/fedramp/models/leveraged_auth_new.py +168 -0
  253. regscale/integrations/public/fedramp/models/poam_importer.py +522 -0
  254. regscale/integrations/public/fedramp/parts_mapper.py +107 -0
  255. regscale/integrations/public/fedramp/poam/__init__.py +0 -0
  256. regscale/integrations/public/fedramp/poam/scanner.py +851 -0
  257. regscale/integrations/public/fedramp/properties.py +201 -0
  258. regscale/integrations/public/fedramp/reporting.py +84 -0
  259. regscale/integrations/public/fedramp/resources.py +496 -0
  260. regscale/integrations/public/fedramp/rosetta.py +110 -0
  261. regscale/integrations/public/fedramp/ssp_logger.py +87 -0
  262. regscale/integrations/public/fedramp/system_characteristics.py +922 -0
  263. regscale/integrations/public/fedramp/system_control_implementations.py +582 -0
  264. regscale/integrations/public/fedramp/system_implementation.py +190 -0
  265. regscale/integrations/public/fedramp/xml_utils.py +87 -0
  266. regscale/integrations/public/nist_catalog.py +275 -0
  267. regscale/integrations/public/oscal.py +1946 -0
  268. regscale/integrations/public/otx.py +169 -0
  269. regscale/integrations/scanner_integration.py +2692 -0
  270. regscale/integrations/variables.py +25 -0
  271. regscale/models/__init__.py +7 -0
  272. regscale/models/app_models/__init__.py +5 -0
  273. regscale/models/app_models/catalog_compare.py +213 -0
  274. regscale/models/app_models/click.py +252 -0
  275. regscale/models/app_models/datetime_encoder.py +21 -0
  276. regscale/models/app_models/import_validater.py +321 -0
  277. regscale/models/app_models/mapping.py +260 -0
  278. regscale/models/app_models/pipeline.py +37 -0
  279. regscale/models/click_models.py +413 -0
  280. regscale/models/config.py +154 -0
  281. regscale/models/email_style.css +67 -0
  282. regscale/models/hierarchy.py +8 -0
  283. regscale/models/inspect_models.py +79 -0
  284. regscale/models/integration_models/__init__.py +0 -0
  285. regscale/models/integration_models/amazon_models/__init__.py +0 -0
  286. regscale/models/integration_models/amazon_models/inspector.py +262 -0
  287. regscale/models/integration_models/amazon_models/inspector_scan.py +206 -0
  288. regscale/models/integration_models/aqua.py +247 -0
  289. regscale/models/integration_models/azure_alerts.py +255 -0
  290. regscale/models/integration_models/base64.py +23 -0
  291. regscale/models/integration_models/burp.py +433 -0
  292. regscale/models/integration_models/burp_models.py +128 -0
  293. regscale/models/integration_models/cisa_kev_data.json +19333 -0
  294. regscale/models/integration_models/defender_data.py +93 -0
  295. regscale/models/integration_models/defenderimport.py +143 -0
  296. regscale/models/integration_models/drf.py +443 -0
  297. regscale/models/integration_models/ecr_models/__init__.py +0 -0
  298. regscale/models/integration_models/ecr_models/data.py +69 -0
  299. regscale/models/integration_models/ecr_models/ecr.py +239 -0
  300. regscale/models/integration_models/flat_file_importer.py +1079 -0
  301. regscale/models/integration_models/grype_import.py +247 -0
  302. regscale/models/integration_models/ibm.py +126 -0
  303. regscale/models/integration_models/implementation_results.py +85 -0
  304. regscale/models/integration_models/nexpose.py +140 -0
  305. regscale/models/integration_models/prisma.py +202 -0
  306. regscale/models/integration_models/qualys.py +720 -0
  307. regscale/models/integration_models/qualys_scanner.py +160 -0
  308. regscale/models/integration_models/sbom/__init__.py +0 -0
  309. regscale/models/integration_models/sbom/cyclone_dx.py +139 -0
  310. regscale/models/integration_models/send_reminders.py +620 -0
  311. regscale/models/integration_models/snyk.py +155 -0
  312. regscale/models/integration_models/synqly_models/__init__.py +0 -0
  313. regscale/models/integration_models/synqly_models/capabilities.json +1 -0
  314. regscale/models/integration_models/synqly_models/connector_types.py +22 -0
  315. regscale/models/integration_models/synqly_models/connectors/__init__.py +7 -0
  316. regscale/models/integration_models/synqly_models/connectors/assets.py +97 -0
  317. regscale/models/integration_models/synqly_models/connectors/ticketing.py +583 -0
  318. regscale/models/integration_models/synqly_models/connectors/vulnerabilities.py +169 -0
  319. regscale/models/integration_models/synqly_models/ocsf_mapper.py +331 -0
  320. regscale/models/integration_models/synqly_models/param.py +72 -0
  321. regscale/models/integration_models/synqly_models/synqly_model.py +733 -0
  322. regscale/models/integration_models/synqly_models/tenants.py +39 -0
  323. regscale/models/integration_models/tenable_models/__init__.py +0 -0
  324. regscale/models/integration_models/tenable_models/integration.py +187 -0
  325. regscale/models/integration_models/tenable_models/models.py +513 -0
  326. regscale/models/integration_models/trivy_import.py +231 -0
  327. regscale/models/integration_models/veracode.py +217 -0
  328. regscale/models/integration_models/xray.py +135 -0
  329. regscale/models/locking.py +100 -0
  330. regscale/models/platform.py +110 -0
  331. regscale/models/regscale_models/__init__.py +67 -0
  332. regscale/models/regscale_models/assessment.py +570 -0
  333. regscale/models/regscale_models/assessment_plan.py +52 -0
  334. regscale/models/regscale_models/asset.py +567 -0
  335. regscale/models/regscale_models/asset_mapping.py +190 -0
  336. regscale/models/regscale_models/case.py +42 -0
  337. regscale/models/regscale_models/catalog.py +261 -0
  338. regscale/models/regscale_models/cci.py +46 -0
  339. regscale/models/regscale_models/change.py +167 -0
  340. regscale/models/regscale_models/checklist.py +372 -0
  341. regscale/models/regscale_models/comment.py +49 -0
  342. regscale/models/regscale_models/compliance_settings.py +112 -0
  343. regscale/models/regscale_models/component.py +412 -0
  344. regscale/models/regscale_models/component_mapping.py +65 -0
  345. regscale/models/regscale_models/control.py +38 -0
  346. regscale/models/regscale_models/control_implementation.py +1128 -0
  347. regscale/models/regscale_models/control_objective.py +261 -0
  348. regscale/models/regscale_models/control_parameter.py +100 -0
  349. regscale/models/regscale_models/control_test.py +34 -0
  350. regscale/models/regscale_models/control_test_plan.py +75 -0
  351. regscale/models/regscale_models/control_test_result.py +52 -0
  352. regscale/models/regscale_models/custom_field.py +245 -0
  353. regscale/models/regscale_models/data.py +109 -0
  354. regscale/models/regscale_models/data_center.py +40 -0
  355. regscale/models/regscale_models/deviation.py +203 -0
  356. regscale/models/regscale_models/email.py +97 -0
  357. regscale/models/regscale_models/evidence.py +47 -0
  358. regscale/models/regscale_models/evidence_mapping.py +40 -0
  359. regscale/models/regscale_models/facility.py +59 -0
  360. regscale/models/regscale_models/file.py +382 -0
  361. regscale/models/regscale_models/filetag.py +37 -0
  362. regscale/models/regscale_models/form_field_value.py +94 -0
  363. regscale/models/regscale_models/group.py +169 -0
  364. regscale/models/regscale_models/implementation_objective.py +335 -0
  365. regscale/models/regscale_models/implementation_option.py +275 -0
  366. regscale/models/regscale_models/implementation_role.py +33 -0
  367. regscale/models/regscale_models/incident.py +177 -0
  368. regscale/models/regscale_models/interconnection.py +43 -0
  369. regscale/models/regscale_models/issue.py +1176 -0
  370. regscale/models/regscale_models/leveraged_authorization.py +125 -0
  371. regscale/models/regscale_models/line_of_inquiry.py +52 -0
  372. regscale/models/regscale_models/link.py +205 -0
  373. regscale/models/regscale_models/meta_data.py +64 -0
  374. regscale/models/regscale_models/mixins/__init__.py +0 -0
  375. regscale/models/regscale_models/mixins/parent_cache.py +124 -0
  376. regscale/models/regscale_models/module.py +224 -0
  377. regscale/models/regscale_models/modules.py +191 -0
  378. regscale/models/regscale_models/objective.py +14 -0
  379. regscale/models/regscale_models/parameter.py +87 -0
  380. regscale/models/regscale_models/ports_protocol.py +81 -0
  381. regscale/models/regscale_models/privacy.py +89 -0
  382. regscale/models/regscale_models/profile.py +50 -0
  383. regscale/models/regscale_models/profile_link.py +68 -0
  384. regscale/models/regscale_models/profile_mapping.py +124 -0
  385. regscale/models/regscale_models/project.py +63 -0
  386. regscale/models/regscale_models/property.py +278 -0
  387. regscale/models/regscale_models/question.py +85 -0
  388. regscale/models/regscale_models/questionnaire.py +87 -0
  389. regscale/models/regscale_models/questionnaire_instance.py +177 -0
  390. regscale/models/regscale_models/rbac.py +132 -0
  391. regscale/models/regscale_models/reference.py +86 -0
  392. regscale/models/regscale_models/regscale_model.py +1643 -0
  393. regscale/models/regscale_models/requirement.py +29 -0
  394. regscale/models/regscale_models/risk.py +274 -0
  395. regscale/models/regscale_models/sbom.py +54 -0
  396. regscale/models/regscale_models/scan_history.py +436 -0
  397. regscale/models/regscale_models/search.py +53 -0
  398. regscale/models/regscale_models/security_control.py +132 -0
  399. regscale/models/regscale_models/security_plan.py +204 -0
  400. regscale/models/regscale_models/software_inventory.py +159 -0
  401. regscale/models/regscale_models/stake_holder.py +64 -0
  402. regscale/models/regscale_models/stig.py +647 -0
  403. regscale/models/regscale_models/supply_chain.py +152 -0
  404. regscale/models/regscale_models/system_role.py +188 -0
  405. regscale/models/regscale_models/system_role_external_assignment.py +40 -0
  406. regscale/models/regscale_models/tag.py +37 -0
  407. regscale/models/regscale_models/tag_mapping.py +19 -0
  408. regscale/models/regscale_models/task.py +133 -0
  409. regscale/models/regscale_models/threat.py +196 -0
  410. regscale/models/regscale_models/user.py +175 -0
  411. regscale/models/regscale_models/user_group.py +55 -0
  412. regscale/models/regscale_models/vulnerability.py +242 -0
  413. regscale/models/regscale_models/vulnerability_mapping.py +162 -0
  414. regscale/models/regscale_models/workflow.py +55 -0
  415. regscale/models/regscale_models/workflow_action.py +34 -0
  416. regscale/models/regscale_models/workflow_instance.py +269 -0
  417. regscale/models/regscale_models/workflow_instance_step.py +114 -0
  418. regscale/models/regscale_models/workflow_template.py +58 -0
  419. regscale/models/regscale_models/workflow_template_step.py +45 -0
  420. regscale/regscale.py +815 -0
  421. regscale/utils/__init__.py +7 -0
  422. regscale/utils/b64conversion.py +14 -0
  423. regscale/utils/click_utils.py +118 -0
  424. regscale/utils/decorators.py +48 -0
  425. regscale/utils/dict_utils.py +59 -0
  426. regscale/utils/files.py +79 -0
  427. regscale/utils/fxns.py +30 -0
  428. regscale/utils/graphql_client.py +113 -0
  429. regscale/utils/lists.py +16 -0
  430. regscale/utils/numbers.py +12 -0
  431. regscale/utils/shell.py +148 -0
  432. regscale/utils/string.py +121 -0
  433. regscale/utils/synqly_utils.py +165 -0
  434. regscale/utils/threading/__init__.py +8 -0
  435. regscale/utils/threading/threadhandler.py +131 -0
  436. regscale/utils/threading/threadsafe_counter.py +47 -0
  437. regscale/utils/threading/threadsafe_dict.py +242 -0
  438. regscale/utils/threading/threadsafe_list.py +83 -0
  439. regscale/utils/version.py +104 -0
  440. regscale/validation/__init__.py +0 -0
  441. regscale/validation/address.py +37 -0
  442. regscale/validation/record.py +48 -0
  443. regscale/visualization/__init__.py +5 -0
  444. regscale/visualization/click.py +34 -0
  445. regscale_cli-6.16.0.0.dist-info/LICENSE +21 -0
  446. regscale_cli-6.16.0.0.dist-info/METADATA +659 -0
  447. regscale_cli-6.16.0.0.dist-info/RECORD +481 -0
  448. regscale_cli-6.16.0.0.dist-info/WHEEL +5 -0
  449. regscale_cli-6.16.0.0.dist-info/entry_points.txt +6 -0
  450. regscale_cli-6.16.0.0.dist-info/top_level.txt +2 -0
  451. tests/fixtures/__init__.py +2 -0
  452. tests/fixtures/api.py +87 -0
  453. tests/fixtures/models.py +91 -0
  454. tests/fixtures/test_fixture.py +144 -0
  455. tests/mocks/__init__.py +0 -0
  456. tests/mocks/objects.py +3 -0
  457. tests/mocks/response.py +32 -0
  458. tests/mocks/xml.py +13 -0
  459. tests/regscale/__init__.py +0 -0
  460. tests/regscale/core/__init__.py +0 -0
  461. tests/regscale/core/test_api.py +232 -0
  462. tests/regscale/core/test_app.py +406 -0
  463. tests/regscale/core/test_login.py +37 -0
  464. tests/regscale/core/test_logz.py +66 -0
  465. tests/regscale/core/test_sbom_generator.py +87 -0
  466. tests/regscale/core/test_validation_utils.py +163 -0
  467. tests/regscale/core/test_version.py +78 -0
  468. tests/regscale/models/__init__.py +0 -0
  469. tests/regscale/models/test_asset.py +71 -0
  470. tests/regscale/models/test_config.py +26 -0
  471. tests/regscale/models/test_control_implementation.py +27 -0
  472. tests/regscale/models/test_import.py +97 -0
  473. tests/regscale/models/test_issue.py +36 -0
  474. tests/regscale/models/test_mapping.py +52 -0
  475. tests/regscale/models/test_platform.py +31 -0
  476. tests/regscale/models/test_regscale_model.py +346 -0
  477. tests/regscale/models/test_report.py +32 -0
  478. tests/regscale/models/test_tenable_integrations.py +118 -0
  479. tests/regscale/models/test_user_model.py +121 -0
  480. tests/regscale/test_about.py +19 -0
  481. tests/regscale/test_authorization.py +65 -0
@@ -0,0 +1,433 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Pydantic model for a Burp Scan"""
4
+ import os
5
+ import re
6
+ import shutil
7
+ from datetime import datetime, timedelta
8
+ from pathlib import Path
9
+ from typing import Any, Generator, List, Optional, TextIO
10
+ from urllib.parse import urlparse
11
+ from xml.etree.ElementTree import Element, ParseError, fromstring, parse
12
+
13
+ from regscale.core.app.api import Api
14
+ from regscale.core.app.application import Application
15
+ from regscale.core.app.logz import create_logger
16
+ from regscale.core.app.utils.app_utils import check_file_path, get_current_datetime
17
+ from regscale.integrations.scanner_integration import IntegrationAsset, IntegrationFinding
18
+ from regscale.models.integration_models.burp_models import BurpRequest, BurpResponse, Issue, RequestResponse
19
+ from regscale.models.regscale_models import File
20
+ from regscale.models.regscale_models import Issue as RegscaleIssue
21
+
22
+ # standard python imports
23
+
24
+
25
+ class Burp:
26
+ """Burp Scan information"""
27
+
28
+ def __init__(self, app: Application, file_path: str, encoding="utf-8", **kwargs) -> "Burp":
29
+ logger = create_logger("Burp")
30
+ logger.info("Now processing %s", file_path)
31
+ self.integration_assets: Generator[IntegrationAsset, None, None] = (x for x in [])
32
+ self.integration_findings: Generator[IntegrationFinding, None, None] = (x for x in [])
33
+ self.num_assets = 0
34
+ self.num_findings = 0
35
+ self.job_complete = False
36
+ self.logger = logger
37
+ self.app = app
38
+ self.api = Api()
39
+ self.parent_id = 0
40
+ self.parent_module = "assets"
41
+ if "parentId" in kwargs and kwargs["parentId"]:
42
+ self.parent_id = kwargs["parentId"]
43
+ if "parentModule" in kwargs and kwargs["parentModule"]:
44
+ self.parent_module = kwargs["parentModule"]
45
+ self.encoding = encoding
46
+ self.file_path = Path(file_path)
47
+ self.version = None
48
+ self.export_time = None
49
+ self.burp_issues = []
50
+ self.existing_issues = []
51
+ self.from_file()
52
+
53
+ def move_files(self, upload_file: Optional[bool] = True) -> None:
54
+ """
55
+ Move files to processed directory and upload to RegScale after processing
56
+
57
+ :param Optional[bool] upload_file: Whether to upload the file to RegScale after processing. Default is True.
58
+ :rtype: None
59
+ """
60
+ api = Api()
61
+ # Create processed directory if it doesn't exist, and copy file to it.
62
+
63
+ new_file_path: Path = Path()
64
+ processed_dir = self.file_path.parent / "processed"
65
+ check_file_path(str(processed_dir.absolute()))
66
+ try:
67
+ if self.parent_id and self.job_complete:
68
+ file_name = f"{self.file_path.stem}_{get_current_datetime('%Y%m%d-%I%M%S%p')}".replace(" ", "_")
69
+ # Rename to friendly file name and post to Regscale
70
+ new_file_path = self.file_path.rename(self.file_path.parent / (file_name + ".xml"))
71
+ self.logger.info(
72
+ "Renaming %s to %s...",
73
+ self.file_path.name,
74
+ new_file_path.name,
75
+ )
76
+ if upload_file and File.upload_file_to_regscale(
77
+ file_name=str(new_file_path.absolute()),
78
+ parent_id=self.parent_id,
79
+ parent_module="securityplans",
80
+ api=api,
81
+ ):
82
+ self.logger.info("Uploaded %s to RegScale securityplans #%i.", new_file_path.name, self.parent_id)
83
+ shutil.move(new_file_path, processed_dir)
84
+ try:
85
+ # Clean up the gzipped file created
86
+ os.remove(new_file_path.with_suffix(".gz"))
87
+ except FileNotFoundError:
88
+ self.logger.debug(
89
+ "File %s already exists in %s",
90
+ new_file_path.with_suffix(".gz").name,
91
+ processed_dir,
92
+ )
93
+ except shutil.Error:
94
+ self.logger.debug(
95
+ "File %s already exists in %s",
96
+ new_file_path.name,
97
+ processed_dir,
98
+ )
99
+
100
+ def from_file(self) -> None:
101
+ """
102
+ Read Burp Scan file
103
+
104
+ :rtype: None
105
+ """
106
+ self.logger.debug(os.getcwd())
107
+ try:
108
+ with open(file=self.file_path, mode="r", encoding=self.encoding) as file:
109
+ root = self.file_root_element(file)
110
+ self.version = root.attrib["burpVersion"]
111
+ self.export_time = root.attrib["exportTime"]
112
+ self.gen_findings(root)
113
+ self.gen_assets()
114
+ self.job_complete = True
115
+ except (FileNotFoundError, ParseError):
116
+ self.logger.error("File not found: %s", self.file_path)
117
+
118
+ @staticmethod
119
+ def file_root_element(file: TextIO) -> Element:
120
+ """
121
+ Function returns the root element for tree of given file with scan results
122
+
123
+ :param TextIO file: file with scan results
124
+ :return: root element for this tree
125
+ :rtype: Element
126
+ """
127
+
128
+ scan_file_parsed = parse(file)
129
+ root = scan_file_parsed.getroot()
130
+ return root
131
+
132
+ def create_issue(self, xml: Element) -> Issue:
133
+ """
134
+ Create an issue from the XML
135
+
136
+ :param Element xml: XML
137
+ :return: Issue object from XML
138
+ :rtype: Issue
139
+ """
140
+ issue = Issue()
141
+ issue.serialNumber = self.get(xml, "serialNumber")
142
+ issue.type = self.get(xml, "type")
143
+ issue.host = self.get_domain_name(self.get(xml, "host"))
144
+ issue.path = self.get(xml, "path")
145
+ issue.name = self.get(xml, "name")
146
+ issue.location = self.get(xml, "location")
147
+ issue.severity = self.get(xml, "severity")
148
+ issue.confidence = self.get(xml, "confidence")
149
+ issue.background = self.strip_html_tags(self.get(xml, "issueBackground"))
150
+ issue.detail = self.get(xml, "issueDetail")
151
+ issue.remediation_background = self.strip_html_tags(self.get(xml, "remediationBackground"))
152
+ issue.remediation_detail = self.strip_html_tags(self.get(xml, "remediationDetail"))
153
+ issue.links = self.extract_links(self.get(xml, "vulnerabilityClassifications"))
154
+ issue.cwes = self.extract_classifications(self.get(xml, "vulnerabilityClassifications"))
155
+ issue.request_response = self.get_io(xml)
156
+ return issue
157
+
158
+ def create_regscale_finding(self, issue: Issue, scan_time: datetime, fmt: str) -> Optional[IntegrationFinding]:
159
+ """
160
+ Create a RegScale finding from a Burp Issue
161
+
162
+ :param Issue issue: Burp Issue
163
+ :param datetime scan_time: Scan time
164
+ :param str fmt: Format for datetime object
165
+ :return: RegScale Issue
166
+ :rtype: Optional[IntegrationFinding]
167
+ """
168
+ remediation_actions = None
169
+ if issue.severity.lower() == "info":
170
+ return None
171
+ due_date = self.get_due_delta(issue.severity)
172
+ if issue.detail and issue.remediation_background:
173
+ remediation_actions = issue.detail + "<br>" + issue.remediation_background
174
+ elif issue.remediation_background:
175
+ remediation_actions = issue.remediation_background
176
+ elif issue.detail:
177
+ remediation_actions = issue.detail
178
+ # No CVE available, must use background
179
+ cve = self.extract_cve(issue.background)
180
+ external_id = str(hex(int(issue.type)) if issue.type and (issue.type).isdigit() else issue.type).replace(
181
+ "0x", "0x00"
182
+ ) # Use burp hexidecimal issue type and format as external_id
183
+ finding = IntegrationFinding(
184
+ control_labels=[], # Add an empty list for control_labels
185
+ category="Burp Vulnerability", # Add a default category
186
+ title=issue.name,
187
+ description=(issue.background if issue.background else "")[:255],
188
+ severity=RegscaleIssue.assign_severity(issue.severity),
189
+ status="Open",
190
+ asset_identifier=issue.host,
191
+ external_id=external_id,
192
+ remediation=(remediation_actions if remediation_actions else "update affected package")[:255],
193
+ cvss_score=None,
194
+ cve=cve,
195
+ cvss_v3_base_score=None,
196
+ source_rule_id=str(issue.type),
197
+ vulnerability_type="Vulnerability Scan",
198
+ baseline="Burp Host",
199
+ recommendation_for_mitigation=issue.remediation_background,
200
+ results=issue.detail,
201
+ plugin_name=issue.type,
202
+ plugin_id=issue.type,
203
+ ip_address=issue.host,
204
+ )
205
+ if issue.detail:
206
+ finding.description = finding.description + "<br>" + issue.detail
207
+ if issue.cwes:
208
+ finding.description = finding.description + "<br>" + ", ".join(issue.cwes)
209
+ finding.first_seen = datetime.strftime(scan_time, fmt)
210
+ finding.last_seen = datetime.strftime(scan_time, fmt)
211
+ if scan_time + timedelta(days=due_date) < datetime.now():
212
+ finding.due_date = datetime.strftime(datetime.now() + timedelta(days=due_date), fmt)
213
+ else:
214
+ finding.due_date = datetime.strftime(scan_time + timedelta(days=due_date), fmt)
215
+ finding.basis_for_adjustment = "Burp Scan import"
216
+
217
+ return finding
218
+
219
+ def gen_findings(self, root: Element) -> None:
220
+ """
221
+ Generate issues
222
+
223
+ :param Element root: Root
224
+ :rtype: None
225
+ """
226
+ issues = []
227
+ findings = set()
228
+ self.existing_issues = RegscaleIssue.get_all_by_parent(parent_id=self.parent_id, parent_module="securityplans")
229
+ root_issues = root.findall("issue")
230
+ fmt = "%Y-%m-%d %H:%M:%S"
231
+ scan_time = datetime.strptime(root.attrib["exportTime"], "%a %b %d %H:%M:%S %Z %Y")
232
+ for xml in root_issues:
233
+ issue = self.create_issue(xml)
234
+ issues.append(issue)
235
+ regscale_finding = self.create_regscale_finding(issue, scan_time, fmt)
236
+ if regscale_finding and regscale_finding not in findings:
237
+ findings.add(regscale_finding)
238
+ self.num_findings += 1
239
+ self.burp_issues = issues
240
+ self.integration_findings = (x for x in findings)
241
+
242
+ def get_due_delta(self, severity: str) -> int:
243
+ """
244
+ Find the due delta from the config file
245
+
246
+ :param str severity: The severity level
247
+ :return: Due date delta
248
+ :rtype: int
249
+ """
250
+ # Leave at Tenable for now
251
+ due_delta = self.app.config["issues"]["tenable"]["low"]
252
+ if severity.lower() in ["medium", "moderate"]:
253
+ due_delta = self.app.config["issues"]["tenable"]["moderate"]
254
+ elif severity.lower() == "high":
255
+ due_delta = self.app.config["issues"]["tenable"]["high"]
256
+ elif severity.lower() == "critical":
257
+ due_delta = self.app.config["issues"]["tenable"]["critical"]
258
+ return due_delta
259
+
260
+ @classmethod
261
+ def get(cls, item: Any, key: Any) -> Optional[Any]:
262
+ """
263
+ Get item
264
+
265
+ :param Any item: Object to try and get value from
266
+ :param Any key: The key to get the value with
267
+ :return: item stored at the provided key, or None if not found
268
+ :rtype: Optional[Any]
269
+ """
270
+ try:
271
+ return item.find(key).text
272
+ except (AttributeError, KeyError):
273
+ return None
274
+
275
+ @staticmethod
276
+ def extract_numbers(string: str) -> List[int]:
277
+ """
278
+ Extract numbers from string
279
+
280
+ :param str string: string with numbers
281
+ :return: List of numbers found in provided string
282
+ :rtype: List[int]
283
+ """
284
+ return re.findall(r"\d+", string)
285
+
286
+ @staticmethod
287
+ def get_request_response(item: Element) -> RequestResponse:
288
+ """
289
+ Get the Request/Response object
290
+
291
+ :param Element item: item
292
+ :return: The Request/Response object
293
+ :rtype: RequestResponse
294
+ """
295
+ request_data = item.find(".//request")
296
+ if response_data := item.find(".//response"):
297
+ base64_dat = bool(request_data.attrib["base64"]) if "base64" in item.attrib else False
298
+ response_data_is_base64 = BurpResponse.is_base64(response_data.text)
299
+ method = request_data.attrib["method"] if "method" in item.attrib else "GET"
300
+ request = (
301
+ BurpRequest(dataString=request_data.text, base64=base64_dat, method=method)
302
+ if BurpRequest.is_base64(request_data.text)
303
+ else None
304
+ )
305
+ response = BurpResponse(
306
+ dataString=response_data.text if response_data_is_base64 else None,
307
+ base64=(bool(item.find(".//response").attrib["base64"]) if response_data_is_base64 else False),
308
+ )
309
+ return RequestResponse(request=request, response=response)
310
+ return RequestResponse(request=None, response=None)
311
+
312
+ def get_io(self, xml: Element) -> RequestResponse:
313
+ """
314
+ Generate the Response Request object
315
+
316
+ :param Element xml: xml
317
+ :return: The Request/Response object
318
+ :rtype: RequestResponse
319
+ """
320
+ for item in xml.findall("requestresponse"):
321
+ dat = item.find(".//request")
322
+ if dat.tag == "request":
323
+ return self.get_request_response(item)
324
+
325
+ def gen_assets(self) -> None:
326
+ """
327
+ Generate RegScale Assets from Burp Issues
328
+
329
+ :rtype: None
330
+ :return: None
331
+ """
332
+ assets: List[IntegrationAsset] = []
333
+ for issue in self.burp_issues:
334
+ host_name = None
335
+ hosts = self.extract_ip_address(issue.host)
336
+ host_name = issue.host
337
+ if hosts:
338
+ host_name = hosts[0]
339
+ integration_asset = IntegrationAsset(
340
+ name=host_name,
341
+ identifier=host_name,
342
+ asset_type="Virtual Machine (VM)",
343
+ asset_owner_id=self.app.config["userId"],
344
+ parent_id=self.parent_id,
345
+ parent_module=self.parent_module,
346
+ asset_category="Hardware",
347
+ date_last_updated=get_current_datetime(),
348
+ status="Active (On Network)",
349
+ ip_address=host_name if hosts else None,
350
+ is_public_facing=False,
351
+ mac_address="",
352
+ fqdn="",
353
+ disk_storage=0,
354
+ cpu=0,
355
+ ram=0,
356
+ )
357
+ if integration_asset.name not in [asset.name for asset in assets]:
358
+ assets.append(integration_asset)
359
+ self.num_assets += 1
360
+ self.integration_assets = (x for x in assets)
361
+
362
+ @staticmethod
363
+ def extract_ip_address(string: str) -> List[str]:
364
+ """
365
+ Extract IP address from string
366
+
367
+ :param str string: string to extract IP address from
368
+ :return: List of IP addresses found in provided string
369
+ :rtype: List[str]
370
+ """
371
+ ip_pattern = r"\b(?:\d{1,3}\.){3}\d{1,3}\b"
372
+ return re.findall(ip_pattern, string)
373
+
374
+ @staticmethod
375
+ def extract_links(html: str) -> List[str]:
376
+ """
377
+ Extract links from html with standard library
378
+
379
+ :param str html: HTML
380
+ :return: List containing links found in the provided HTML string
381
+ :rtype: List[str]
382
+ """
383
+ root = fromstring(html)
384
+ return [link.attrib["href"] for link in root.iter("a")]
385
+
386
+ @staticmethod
387
+ def extract_classifications(html: str) -> List[str]:
388
+ """
389
+ Extract classifications from html with standard library
390
+
391
+ :param str html: HTML to parse classifications from
392
+ :return: List containing classifications found in the provided HTML string
393
+ :rtype: List[str]
394
+ """
395
+ root = fromstring(html)
396
+ return [link.text.strip() for link in root.iter("a")]
397
+
398
+ def get_domain_name(self, url: str) -> str:
399
+ """
400
+ Get the domain name from a URL
401
+
402
+ :param str url: URL
403
+ :return: Domain name
404
+ :rtype: str
405
+ """
406
+ parsed_url = urlparse(url)
407
+ domain_name = parsed_url.hostname
408
+ return domain_name
409
+
410
+ def strip_html_tags(self, text: str) -> str:
411
+ """
412
+ Strip HTML tags from a string.
413
+
414
+ :param str text: The string containing HTML tags
415
+ :return: The string without HTML tags
416
+ :rtype: str
417
+ """
418
+ if not text:
419
+ return text
420
+ clean = re.sub(r"<.*?>", "", text)
421
+ return clean
422
+
423
+ def extract_cve(self, input_string: str) -> Optional[str]:
424
+ """
425
+ Extract CVEs from a string.
426
+
427
+ :param str input_string: The string to extract CVEs from
428
+ :return: List of CVEs found in the provided string
429
+ :rtype: Optional[str]
430
+ """
431
+ cve_pattern = r"CVE-\d{4}-\d{4,7}"
432
+ cve_ids = re.findall(cve_pattern, input_string)
433
+ return cve_ids.pop() if cve_ids else None
@@ -0,0 +1,128 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Pydantic models for Burp Scans"""
4
+
5
+ # standard python imports
6
+ import base64
7
+ import json
8
+ from typing import List, Optional, Union, Any
9
+
10
+ from pydantic import BaseModel
11
+
12
+ from regscale.models.integration_models.base64 import Base64String
13
+
14
+
15
+ class BurpResponse(BaseModel):
16
+ """Response information"""
17
+
18
+ base64: Optional[bool] = None
19
+ dataString: Optional[Union[Base64String, str]] = None
20
+
21
+ def convert_to_response(self) -> Optional[str]:
22
+ """
23
+ Convert base64 encoded response to a requests Response object
24
+
25
+ :return: Base64 decoded response as a string
26
+ :rtype: Optional[str]
27
+ """
28
+ try:
29
+ bytes_data = base64.b64decode(self.dataString)
30
+ if bytes_data:
31
+ # Decode bytes to string
32
+ res = bytes_data.decode("utf-8")
33
+ except Exception:
34
+ res = None
35
+ return res
36
+
37
+ def convert_to_json(self) -> Optional[dict]:
38
+ """
39
+ Convert base64 encoded response to a JSON object
40
+
41
+ :return: Base64 decoded response as a JSON object or None
42
+ :rtype: Optional[dict]
43
+ """
44
+ res = self.convert_to_response()
45
+ data = None
46
+ if res:
47
+ # Find the start and end of the JSON data
48
+ start = res.find("{") # +1 to include the closing brace
49
+
50
+ # Extract the JSON data and convert it to a Python dictionary
51
+ try:
52
+ data = json.loads(res[start:])
53
+ except json.decoder.JSONDecodeError:
54
+ data = None
55
+ return data
56
+
57
+ @classmethod
58
+ def is_base64(cls, sb: Any) -> bool:
59
+ """
60
+ Check if string is base64 encoded
61
+
62
+ :param Any sb: String to check
63
+ :raises ValueError: If argument is not a string or bytes
64
+ :return: True if base64 encoded
65
+ :rtype: bool
66
+ """
67
+ try:
68
+ if isinstance(sb, str):
69
+ # If there's any unicode here, an exception will be thrown and the function will return false
70
+ sb_bytes = bytes(sb, "ascii")
71
+ elif isinstance(sb, bytes):
72
+ sb_bytes = sb
73
+ else:
74
+ raise ValueError("Argument must be string or bytes")
75
+ # If this works, there's base64-encoded data here.
76
+ _ = base64.b64encode(base64.b64decode(sb_bytes)) == sb_bytes
77
+ except Exception:
78
+ return False
79
+ return True
80
+
81
+
82
+ class Host(BaseModel):
83
+ """Host information"""
84
+
85
+ ip: str
86
+ hostname: str
87
+
88
+
89
+ class IssueDetailItem(BaseModel):
90
+ """Issue Detail Item information"""
91
+
92
+ issueDetailItem: Optional[str] = None
93
+
94
+
95
+ class BurpRequest(BurpResponse):
96
+ """Request information"""
97
+
98
+ method: str
99
+
100
+
101
+ class RequestResponse(BaseModel):
102
+ """Request Response information"""
103
+
104
+ request: Optional[BurpRequest] = None
105
+ response: Optional[BurpResponse] = None
106
+
107
+
108
+ class Issue(BaseModel):
109
+ """Issue information"""
110
+
111
+ serialNumber: Optional[str] = None
112
+ type: Optional[str] = None
113
+ name: Optional[str] = None
114
+ host: Optional[Host] = None
115
+ path: Optional[str] = None
116
+ location: Optional[str] = None
117
+ severity: Optional[str] = None
118
+ confidence: Optional[str] = None
119
+ background: Optional[str] = None
120
+ remediation_background: Optional[str] = None
121
+ detail: Optional[str] = None
122
+ detail_items: Optional[List[IssueDetailItem]] = None
123
+ request_response: Optional[RequestResponse] = None
124
+ remediation_detail: Optional[str] = None
125
+ references: Optional[str] = None
126
+ vulnerability_classifications: Optional[str] = None
127
+ cwes: Optional[List[str]] = None
128
+ links: Optional[List[str]] = None