secator 0.11.1__tar.gz → 0.12.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.

Potentially problematic release.


This version of secator might be problematic. Click here for more details.

Files changed (199) hide show
  1. {secator-0.11.1 → secator-0.12.0}/CHANGELOG.md +15 -0
  2. {secator-0.11.1 → secator-0.12.0}/PKG-INFO +1 -1
  3. {secator-0.11.1 → secator-0.12.0}/pyproject.toml +1 -1
  4. {secator-0.11.1 → secator-0.12.0}/secator/cli.py +1 -1
  5. {secator-0.11.1 → secator-0.12.0}/secator/config.py +1 -0
  6. {secator-0.11.1 → secator-0.12.0}/secator/configs/workflows/url_params_fuzz.yaml +2 -0
  7. {secator-0.11.1 → secator-0.12.0}/secator/decorators.py +39 -21
  8. {secator-0.11.1 → secator-0.12.0}/secator/runners/command.py +1 -0
  9. {secator-0.11.1 → secator-0.12.0}/secator/tasks/arjun.py +9 -1
  10. {secator-0.11.1 → secator-0.12.0}/secator/template.py +12 -0
  11. {secator-0.11.1 → secator-0.12.0}/.docker/Dockerfile.alpine +0 -0
  12. {secator-0.11.1 → secator-0.12.0}/.docker/Dockerfile.arch +0 -0
  13. {secator-0.11.1 → secator-0.12.0}/.docker/Dockerfile.debian +0 -0
  14. {secator-0.11.1 → secator-0.12.0}/.docker/Dockerfile.kali +0 -0
  15. {secator-0.11.1 → secator-0.12.0}/.docker/Dockerfile.osx +0 -0
  16. {secator-0.11.1 → secator-0.12.0}/.docker/Dockerfile.ubuntu +0 -0
  17. {secator-0.11.1 → secator-0.12.0}/.docker/build_all.sh +0 -0
  18. {secator-0.11.1 → secator-0.12.0}/.dockerignore +0 -0
  19. {secator-0.11.1 → secator-0.12.0}/.flake8 +0 -0
  20. {secator-0.11.1 → secator-0.12.0}/.gitignore +0 -0
  21. {secator-0.11.1 → secator-0.12.0}/CONTRIBUTING.md +0 -0
  22. {secator-0.11.1 → secator-0.12.0}/Dockerfile +0 -0
  23. {secator-0.11.1 → secator-0.12.0}/LICENSE +0 -0
  24. {secator-0.11.1 → secator-0.12.0}/README.md +0 -0
  25. {secator-0.11.1 → secator-0.12.0}/SECURITY.md +0 -0
  26. {secator-0.11.1 → secator-0.12.0}/cloudbuild.yaml +0 -0
  27. {secator-0.11.1 → secator-0.12.0}/helm/.helmignore +0 -0
  28. {secator-0.11.1 → secator-0.12.0}/helm/Chart.yaml +0 -0
  29. {secator-0.11.1 → secator-0.12.0}/helm/templates/redis-service.yaml +0 -0
  30. {secator-0.11.1 → secator-0.12.0}/helm/templates/redis.yaml +0 -0
  31. {secator-0.11.1 → secator-0.12.0}/helm/templates/secator-manager.yaml +0 -0
  32. {secator-0.11.1 → secator-0.12.0}/helm/templates/secator-worker.yaml +0 -0
  33. {secator-0.11.1 → secator-0.12.0}/helm/values.yaml +0 -0
  34. {secator-0.11.1 → secator-0.12.0}/scripts/download_cves.sh +0 -0
  35. {secator-0.11.1 → secator-0.12.0}/scripts/install.sh +0 -0
  36. {secator-0.11.1 → secator-0.12.0}/scripts/install_asciinema.sh +0 -0
  37. {secator-0.11.1 → secator-0.12.0}/scripts/install_go.sh +0 -0
  38. {secator-0.11.1 → secator-0.12.0}/scripts/install_ruby.sh +0 -0
  39. {secator-0.11.1 → secator-0.12.0}/scripts/msf/exploit_cve.rc +0 -0
  40. {secator-0.11.1 → secator-0.12.0}/scripts/msf/ftp_anonymous.rc +0 -0
  41. {secator-0.11.1 → secator-0.12.0}/scripts/msf/ftp_version.rc +0 -0
  42. {secator-0.11.1 → secator-0.12.0}/scripts/msf/ftp_vsftpd_234_backdoor.rc +0 -0
  43. {secator-0.11.1 → secator-0.12.0}/scripts/msf/redis.rc +0 -0
  44. {secator-0.11.1 → secator-0.12.0}/scripts/stories/STORY.md +0 -0
  45. {secator-0.11.1 → secator-0.12.0}/scripts/stories/aliases.sh +0 -0
  46. {secator-0.11.1 → secator-0.12.0}/scripts/stories/demo.sh +0 -0
  47. {secator-0.11.1 → secator-0.12.0}/scripts/stories/fmt.sh +0 -0
  48. {secator-0.11.1 → secator-0.12.0}/scripts/stories/input.sh +0 -0
  49. {secator-0.11.1 → secator-0.12.0}/scripts/stories/pipe.sh +0 -0
  50. {secator-0.11.1 → secator-0.12.0}/scripts/stories/short_demo.sh +0 -0
  51. {secator-0.11.1 → secator-0.12.0}/secator/.gitignore +0 -0
  52. {secator-0.11.1 → secator-0.12.0}/secator/__init__.py +0 -0
  53. {secator-0.11.1 → secator-0.12.0}/secator/celery.py +0 -0
  54. {secator-0.11.1 → secator-0.12.0}/secator/celery_signals.py +0 -0
  55. {secator-0.11.1 → secator-0.12.0}/secator/celery_utils.py +0 -0
  56. {secator-0.11.1 → secator-0.12.0}/secator/configs/__init__.py +0 -0
  57. {secator-0.11.1 → secator-0.12.0}/secator/configs/profiles/__init__.py +0 -0
  58. {secator-0.11.1 → secator-0.12.0}/secator/configs/profiles/aggressive.yaml +0 -0
  59. {secator-0.11.1 → secator-0.12.0}/secator/configs/profiles/default.yaml +0 -0
  60. {secator-0.11.1 → secator-0.12.0}/secator/configs/profiles/stealth.yaml +0 -0
  61. {secator-0.11.1 → secator-0.12.0}/secator/configs/scans/__init__.py +0 -0
  62. {secator-0.11.1 → secator-0.12.0}/secator/configs/scans/domain.yaml +0 -0
  63. {secator-0.11.1 → secator-0.12.0}/secator/configs/scans/host.yaml +0 -0
  64. {secator-0.11.1 → secator-0.12.0}/secator/configs/scans/network.yaml +0 -0
  65. {secator-0.11.1 → secator-0.12.0}/secator/configs/scans/subdomain.yaml +0 -0
  66. {secator-0.11.1 → secator-0.12.0}/secator/configs/scans/url.yaml +0 -0
  67. {secator-0.11.1 → secator-0.12.0}/secator/configs/workflows/__init__.py +0 -0
  68. {secator-0.11.1 → secator-0.12.0}/secator/configs/workflows/cidr_recon.yaml +0 -0
  69. {secator-0.11.1 → secator-0.12.0}/secator/configs/workflows/code_scan.yaml +0 -0
  70. {secator-0.11.1 → secator-0.12.0}/secator/configs/workflows/host_recon.yaml +0 -0
  71. {secator-0.11.1 → secator-0.12.0}/secator/configs/workflows/subdomain_recon.yaml +0 -0
  72. {secator-0.11.1 → secator-0.12.0}/secator/configs/workflows/url_bypass.yaml +0 -0
  73. {secator-0.11.1 → secator-0.12.0}/secator/configs/workflows/url_crawl.yaml +0 -0
  74. {secator-0.11.1 → secator-0.12.0}/secator/configs/workflows/url_dirsearch.yaml +0 -0
  75. {secator-0.11.1 → secator-0.12.0}/secator/configs/workflows/url_fuzz.yaml +0 -0
  76. {secator-0.11.1 → secator-0.12.0}/secator/configs/workflows/url_nuclei.yaml +0 -0
  77. {secator-0.11.1 → secator-0.12.0}/secator/configs/workflows/url_vuln.yaml +0 -0
  78. {secator-0.11.1 → secator-0.12.0}/secator/configs/workflows/user_hunt.yaml +0 -0
  79. {secator-0.11.1 → secator-0.12.0}/secator/configs/workflows/wordpress.yaml +0 -0
  80. {secator-0.11.1 → secator-0.12.0}/secator/definitions.py +0 -0
  81. {secator-0.11.1 → secator-0.12.0}/secator/exporters/__init__.py +0 -0
  82. {secator-0.11.1 → secator-0.12.0}/secator/exporters/_base.py +0 -0
  83. {secator-0.11.1 → secator-0.12.0}/secator/exporters/console.py +0 -0
  84. {secator-0.11.1 → secator-0.12.0}/secator/exporters/csv.py +0 -0
  85. {secator-0.11.1 → secator-0.12.0}/secator/exporters/gdrive.py +0 -0
  86. {secator-0.11.1 → secator-0.12.0}/secator/exporters/json.py +0 -0
  87. {secator-0.11.1 → secator-0.12.0}/secator/exporters/table.py +0 -0
  88. {secator-0.11.1 → secator-0.12.0}/secator/exporters/txt.py +0 -0
  89. {secator-0.11.1 → secator-0.12.0}/secator/hooks/__init__.py +0 -0
  90. {secator-0.11.1 → secator-0.12.0}/secator/hooks/gcs.py +0 -0
  91. {secator-0.11.1 → secator-0.12.0}/secator/hooks/mongodb.py +0 -0
  92. {secator-0.11.1 → secator-0.12.0}/secator/installer.py +0 -0
  93. {secator-0.11.1 → secator-0.12.0}/secator/output_types/__init__.py +0 -0
  94. {secator-0.11.1 → secator-0.12.0}/secator/output_types/_base.py +0 -0
  95. {secator-0.11.1 → secator-0.12.0}/secator/output_types/certificate.py +0 -0
  96. {secator-0.11.1 → secator-0.12.0}/secator/output_types/error.py +0 -0
  97. {secator-0.11.1 → secator-0.12.0}/secator/output_types/exploit.py +0 -0
  98. {secator-0.11.1 → secator-0.12.0}/secator/output_types/info.py +0 -0
  99. {secator-0.11.1 → secator-0.12.0}/secator/output_types/ip.py +0 -0
  100. {secator-0.11.1 → secator-0.12.0}/secator/output_types/port.py +0 -0
  101. {secator-0.11.1 → secator-0.12.0}/secator/output_types/progress.py +0 -0
  102. {secator-0.11.1 → secator-0.12.0}/secator/output_types/record.py +0 -0
  103. {secator-0.11.1 → secator-0.12.0}/secator/output_types/stat.py +0 -0
  104. {secator-0.11.1 → secator-0.12.0}/secator/output_types/state.py +0 -0
  105. {secator-0.11.1 → secator-0.12.0}/secator/output_types/subdomain.py +0 -0
  106. {secator-0.11.1 → secator-0.12.0}/secator/output_types/tag.py +0 -0
  107. {secator-0.11.1 → secator-0.12.0}/secator/output_types/target.py +0 -0
  108. {secator-0.11.1 → secator-0.12.0}/secator/output_types/url.py +0 -0
  109. {secator-0.11.1 → secator-0.12.0}/secator/output_types/user_account.py +0 -0
  110. {secator-0.11.1 → secator-0.12.0}/secator/output_types/vulnerability.py +0 -0
  111. {secator-0.11.1 → secator-0.12.0}/secator/output_types/warning.py +0 -0
  112. {secator-0.11.1 → secator-0.12.0}/secator/report.py +0 -0
  113. {secator-0.11.1 → secator-0.12.0}/secator/rich.py +0 -0
  114. {secator-0.11.1 → secator-0.12.0}/secator/runners/__init__.py +0 -0
  115. {secator-0.11.1 → secator-0.12.0}/secator/runners/_base.py +0 -0
  116. {secator-0.11.1 → secator-0.12.0}/secator/runners/_helpers.py +0 -0
  117. {secator-0.11.1 → secator-0.12.0}/secator/runners/celery.py +0 -0
  118. {secator-0.11.1 → secator-0.12.0}/secator/runners/scan.py +0 -0
  119. {secator-0.11.1 → secator-0.12.0}/secator/runners/task.py +0 -0
  120. {secator-0.11.1 → secator-0.12.0}/secator/runners/workflow.py +0 -0
  121. {secator-0.11.1 → secator-0.12.0}/secator/scans/__init__.py +0 -0
  122. {secator-0.11.1 → secator-0.12.0}/secator/serializers/__init__.py +0 -0
  123. {secator-0.11.1 → secator-0.12.0}/secator/serializers/dataclass.py +0 -0
  124. {secator-0.11.1 → secator-0.12.0}/secator/serializers/json.py +0 -0
  125. {secator-0.11.1 → secator-0.12.0}/secator/serializers/regex.py +0 -0
  126. {secator-0.11.1 → secator-0.12.0}/secator/tasks/__init__.py +0 -0
  127. {secator-0.11.1 → secator-0.12.0}/secator/tasks/_categories.py +0 -0
  128. {secator-0.11.1 → secator-0.12.0}/secator/tasks/bbot.py +0 -0
  129. {secator-0.11.1 → secator-0.12.0}/secator/tasks/bup.py +0 -0
  130. {secator-0.11.1 → secator-0.12.0}/secator/tasks/cariddi.py +0 -0
  131. {secator-0.11.1 → secator-0.12.0}/secator/tasks/dalfox.py +0 -0
  132. {secator-0.11.1 → secator-0.12.0}/secator/tasks/dirsearch.py +0 -0
  133. {secator-0.11.1 → secator-0.12.0}/secator/tasks/dnsx.py +0 -0
  134. {secator-0.11.1 → secator-0.12.0}/secator/tasks/dnsxbrute.py +0 -0
  135. {secator-0.11.1 → secator-0.12.0}/secator/tasks/feroxbuster.py +0 -0
  136. {secator-0.11.1 → secator-0.12.0}/secator/tasks/ffuf.py +0 -0
  137. {secator-0.11.1 → secator-0.12.0}/secator/tasks/fping.py +0 -0
  138. {secator-0.11.1 → secator-0.12.0}/secator/tasks/gau.py +0 -0
  139. {secator-0.11.1 → secator-0.12.0}/secator/tasks/gf.py +0 -0
  140. {secator-0.11.1 → secator-0.12.0}/secator/tasks/gitleaks.py +0 -0
  141. {secator-0.11.1 → secator-0.12.0}/secator/tasks/gospider.py +0 -0
  142. {secator-0.11.1 → secator-0.12.0}/secator/tasks/grype.py +0 -0
  143. {secator-0.11.1 → secator-0.12.0}/secator/tasks/h8mail.py +0 -0
  144. {secator-0.11.1 → secator-0.12.0}/secator/tasks/httpx.py +0 -0
  145. {secator-0.11.1 → secator-0.12.0}/secator/tasks/katana.py +0 -0
  146. {secator-0.11.1 → secator-0.12.0}/secator/tasks/maigret.py +0 -0
  147. {secator-0.11.1 → secator-0.12.0}/secator/tasks/mapcidr.py +0 -0
  148. {secator-0.11.1 → secator-0.12.0}/secator/tasks/msfconsole.py +0 -0
  149. {secator-0.11.1 → secator-0.12.0}/secator/tasks/naabu.py +0 -0
  150. {secator-0.11.1 → secator-0.12.0}/secator/tasks/nmap.py +0 -0
  151. {secator-0.11.1 → secator-0.12.0}/secator/tasks/nuclei.py +0 -0
  152. {secator-0.11.1 → secator-0.12.0}/secator/tasks/searchsploit.py +0 -0
  153. {secator-0.11.1 → secator-0.12.0}/secator/tasks/subfinder.py +0 -0
  154. {secator-0.11.1 → secator-0.12.0}/secator/tasks/testssl.py +0 -0
  155. {secator-0.11.1 → secator-0.12.0}/secator/tasks/trivy.py +0 -0
  156. {secator-0.11.1 → secator-0.12.0}/secator/tasks/wafw00f.py +0 -0
  157. {secator-0.11.1 → secator-0.12.0}/secator/tasks/wpprobe.py +0 -0
  158. {secator-0.11.1 → secator-0.12.0}/secator/tasks/wpscan.py +0 -0
  159. {secator-0.11.1 → secator-0.12.0}/secator/thread.py +0 -0
  160. {secator-0.11.1 → secator-0.12.0}/secator/utils.py +0 -0
  161. {secator-0.11.1 → secator-0.12.0}/secator/utils_test.py +0 -0
  162. {secator-0.11.1 → secator-0.12.0}/secator/workflows/__init__.py +0 -0
  163. {secator-0.11.1 → secator-0.12.0}/tests/__init__.py +0 -0
  164. {secator-0.11.1 → secator-0.12.0}/tests/fixtures/h8mail_breach.txt +0 -0
  165. {secator-0.11.1 → secator-0.12.0}/tests/fixtures/ls.py +0 -0
  166. {secator-0.11.1 → secator-0.12.0}/tests/fixtures/msfconsole_input.rc +0 -0
  167. {secator-0.11.1 → secator-0.12.0}/tests/fixtures/nmap_output.xml +0 -0
  168. {secator-0.11.1 → secator-0.12.0}/tests/integration/__init__.py +0 -0
  169. {secator-0.11.1 → secator-0.12.0}/tests/integration/inputs.py +0 -0
  170. {secator-0.11.1 → secator-0.12.0}/tests/integration/outputs.py +0 -0
  171. {secator-0.11.1 → secator-0.12.0}/tests/integration/setup.sh +0 -0
  172. {secator-0.11.1 → secator-0.12.0}/tests/integration/teardown.sh +0 -0
  173. {secator-0.11.1 → secator-0.12.0}/tests/integration/test_addons.py +0 -0
  174. {secator-0.11.1 → secator-0.12.0}/tests/integration/test_celery.py +0 -0
  175. {secator-0.11.1 → secator-0.12.0}/tests/integration/test_helpers.py +0 -0
  176. {secator-0.11.1 → secator-0.12.0}/tests/integration/test_scans.py +0 -0
  177. {secator-0.11.1 → secator-0.12.0}/tests/integration/test_tasks.py +0 -0
  178. {secator-0.11.1 → secator-0.12.0}/tests/integration/test_worker.py +0 -0
  179. {secator-0.11.1 → secator-0.12.0}/tests/integration/test_workflows.py +0 -0
  180. {secator-0.11.1 → secator-0.12.0}/tests/integration/wordlist.txt +0 -0
  181. {secator-0.11.1 → secator-0.12.0}/tests/integration/wordlist_dns.txt +0 -0
  182. {secator-0.11.1 → secator-0.12.0}/tests/integration/wordpress_toolbox/Dockerfile +0 -0
  183. {secator-0.11.1 → secator-0.12.0}/tests/integration/wordpress_toolbox/Makefile +0 -0
  184. {secator-0.11.1 → secator-0.12.0}/tests/performance/__init__.py +0 -0
  185. {secator-0.11.1 → secator-0.12.0}/tests/performance/loadtester.py +0 -0
  186. {secator-0.11.1 → secator-0.12.0}/tests/performance/test_worker.py +0 -0
  187. {secator-0.11.1 → secator-0.12.0}/tests/unit/__init__.py +0 -0
  188. {secator-0.11.1 → secator-0.12.0}/tests/unit/test_celery.py +0 -0
  189. {secator-0.11.1 → secator-0.12.0}/tests/unit/test_cli.py +0 -0
  190. {secator-0.11.1 → secator-0.12.0}/tests/unit/test_command.py +0 -0
  191. {secator-0.11.1 → secator-0.12.0}/tests/unit/test_config.py +0 -0
  192. {secator-0.11.1 → secator-0.12.0}/tests/unit/test_offline.py +0 -0
  193. {secator-0.11.1 → secator-0.12.0}/tests/unit/test_runners.py +0 -0
  194. {secator-0.11.1 → secator-0.12.0}/tests/unit/test_scans.py +0 -0
  195. {secator-0.11.1 → secator-0.12.0}/tests/unit/test_serializers.py +0 -0
  196. {secator-0.11.1 → secator-0.12.0}/tests/unit/test_tasks.py +0 -0
  197. {secator-0.11.1 → secator-0.12.0}/tests/unit/test_tasks_categories.py +0 -0
  198. {secator-0.11.1 → secator-0.12.0}/tests/unit/test_template.py +0 -0
  199. {secator-0.11.1 → secator-0.12.0}/tests/unit/test_utils.py +0 -0
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.12.0](https://github.com/freelabz/secator/compare/v0.11.1...v0.12.0) (2025-04-24)
4
+
5
+
6
+ ### Features
7
+
8
+ * add --show option to display yaml ([#601](https://github.com/freelabz/secator/issues/601)) ([8edffe9](https://github.com/freelabz/secator/commit/8edffe9f879bb7a99a7e5fead1a18dbf6da5d140))
9
+ * **arjun:** add --disable-redirects opts ([#598](https://github.com/freelabz/secator/issues/598)) ([17618c7](https://github.com/freelabz/secator/commit/17618c7ca647536207a96ce2c235ec5227db2cef))
10
+ * **workflows:** improve url params fuzz workflow ([#597](https://github.com/freelabz/secator/issues/597)) ([38fa1bc](https://github.com/freelabz/secator/commit/38fa1bcd76c9c6dbe0bc85c9c8c707ae642b9830))
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * better options overrides for CLI ([#596](https://github.com/freelabz/secator/issues/596)) ([74e256b](https://github.com/freelabz/secator/commit/74e256b434d36f1e16390f8d06571e726517f5ce))
16
+ * worker quiet option ([#602](https://github.com/freelabz/secator/issues/602)) ([9b2c084](https://github.com/freelabz/secator/commit/9b2c08458e3412a89ec39547a728a26885fe1162))
17
+
3
18
  ## [0.11.1](https://github.com/freelabz/secator/compare/v0.11.0...v0.11.1) (2025-04-23)
4
19
 
5
20
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: secator
3
- Version: 0.11.1
3
+ Version: 0.12.0
4
4
  Summary: The pentester's swiss knife.
5
5
  Project-URL: Homepage, https://github.com/freelabz/secator
6
6
  Project-URL: Issues, https://github.com/freelabz/secator/issues
@@ -4,7 +4,7 @@ build-backend = 'hatchling.build'
4
4
 
5
5
  [project]
6
6
  name = 'secator'
7
- version = "0.11.1"
7
+ version = "0.12.0"
8
8
  authors = [{ name = 'FreeLabz', email = 'sales@freelabz.com' }]
9
9
  readme = 'README.md'
10
10
  description = "The pentester's swiss knife."
@@ -119,7 +119,7 @@ for config in sorted(ALL_SCANS, key=lambda x: x['name']):
119
119
  @click.option('-r', '--reload', is_flag=True, help='Autoreload Celery on code changes.')
120
120
  @click.option('-Q', '--queue', type=str, default='', help='Listen to a specific queue.')
121
121
  @click.option('-P', '--pool', type=str, default='eventlet', help='Pool implementation.')
122
- @click.option('--quiet', is_flag=True, help='Quiet mode.')
122
+ @click.option('--quiet', is_flag=True, default=False, help='Quiet mode.')
123
123
  @click.option('--loglevel', type=str, default='INFO', help='Log level.')
124
124
  @click.option('--check', is_flag=True, help='Check if Celery worker is alive.')
125
125
  @click.option('--dev', is_flag=True, help='Start a worker in dev mode (celery multi).')
@@ -94,6 +94,7 @@ class Runners(StrictModel):
94
94
  skip_cve_low_confidence: bool = False
95
95
  remove_duplicates: bool = False
96
96
  show_chunk_progress: bool = False
97
+ show_command_output: bool = False
97
98
 
98
99
 
99
100
  class Security(StrictModel):
@@ -11,6 +11,8 @@ tasks:
11
11
  ffuf:
12
12
  description: Fuzz URL params
13
13
  wordlist: https://raw.githubusercontent.com/danielmiessler/SecLists/refs/heads/master/Discovery/Web-Content/burp-parameter-names.txt
14
+ auto_calibration: true
15
+ follow_redirect: true
14
16
  targets_:
15
17
  - type: url
16
18
  field: url
@@ -19,11 +19,11 @@ RUNNER_OPTS = {
19
19
  'print_stat': {'is_flag': True, 'short': 'stat', 'default': False, 'help': 'Print runtime statistics'},
20
20
  'print_format': {'default': '', 'short': 'fmt', 'help': 'Output formatting string'},
21
21
  'enable_profiler': {'is_flag': True, 'short': 'prof', 'default': False, 'help': 'Enable runner profiling'},
22
- 'show': {'is_flag': True, 'short': 'sh', 'default': False, 'help': 'Show command that will be run (tasks only)'},
23
22
  'no_process': {'is_flag': True, 'short': 'nps', 'default': False, 'help': 'Disable secator processing'},
24
23
  # 'filter': {'default': '', 'short': 'f', 'help': 'Results filter', 'short': 'of'}, # TODO add this
25
- 'quiet': {'is_flag': True, 'short': 'q', 'default': False, 'help': 'Enable quiet mode'},
24
+ 'quiet': {'is_flag': True, 'short': 'q', 'default': not CONFIG.runners.show_command_output, 'opposite': 'verbose', 'help': 'Enable quiet mode'}, # noqa: E501
26
25
  'dry_run': {'is_flag': True, 'short': 'dr', 'default': False, 'help': 'Enable dry run'},
26
+ 'show': {'is_flag': True, 'short': 'yml', 'default': False, 'help': 'Show runner yaml'},
27
27
  }
28
28
 
29
29
  RUNNER_GLOBAL_OPTS = {
@@ -163,35 +163,39 @@ def get_command_options(config):
163
163
  elif opt in RUNNER_GLOBAL_OPTS:
164
164
  prefix = 'Execution'
165
165
 
166
+ # Get opt value from YAML config
167
+ opt_conf_value = task_config_opts.get(opt)
168
+
166
169
  # Get opt conf
167
170
  conf = opt_conf.copy()
171
+ opt_is_flag = conf.get('is_flag', False)
172
+ opt_default = conf.get('default', False if opt_is_flag else None)
173
+ opt_is_required = conf.get('required', False)
168
174
  conf['show_default'] = True
169
175
  conf['prefix'] = prefix
170
- opt_default = conf.get('default', None)
171
- opt_is_flag = conf.get('is_flag', False)
172
- opt_value_in_config = task_config_opts.get(opt)
176
+ conf['default'] = opt_default
177
+ conf['reverse'] = False
173
178
 
174
- # Check if opt already defined in config
175
- if opt_value_in_config:
176
- if conf.get('required', False):
179
+ # Change CLI opt defaults if opt was overriden in YAML config
180
+ if opt_conf_value:
181
+ if opt_is_required:
177
182
  debug('OPT (skipped: opt is required and defined in config)', obj={'opt': opt}, sub=f'cli.{config.name}', verbose=True) # noqa: E501
178
183
  continue
179
184
  mapped_value = cls.opt_value_map.get(opt)
180
185
  if callable(mapped_value):
181
- opt_value_in_config = mapped_value(opt_value_in_config)
186
+ opt_conf_value = mapped_value(opt_conf_value)
182
187
  elif mapped_value:
183
- opt_value_in_config = mapped_value
184
- if opt_value_in_config != opt_default:
188
+ opt_conf_value = mapped_value
189
+
190
+ # Handle option defaults
191
+ if opt_conf_value != opt_default:
185
192
  if opt in opt_cache:
186
193
  continue
187
194
  if opt_is_flag:
188
- conf['reverse'] = True
189
- conf['default'] = not conf['default']
190
- # print(f'{opt}: change default to {opt_value_in_config}')
191
- conf['default'] = opt_value_in_config
195
+ conf['default'] = opt_default = opt_conf_value
192
196
 
193
- # If opt is a flag but the default is True, add opposite flag
194
- if opt_is_flag and opt_default is True:
197
+ # Add reverse flag
198
+ if opt_default is True:
195
199
  conf['reverse'] = True
196
200
 
197
201
  # Check if opt already processed before
@@ -205,7 +209,7 @@ def get_command_options(config):
205
209
  all_opts[opt] = conf
206
210
 
207
211
  # Debug
208
- debug_conf = OrderedDict({'opt': opt, 'config_val': opt_value_in_config or 'N/A', **conf.copy()})
212
+ debug_conf = OrderedDict({'opt': opt, 'config_val': opt_conf_value or 'N/A', **conf.copy()})
209
213
  debug('OPT', obj=debug_conf, sub=f'cli.{config.name}', verbose=True)
210
214
 
211
215
  return all_opts
@@ -236,11 +240,17 @@ def decorate_command_options(opts):
236
240
  conf.pop('process', None)
237
241
  conf.pop('requires_sudo', None)
238
242
  reverse = conf.pop('reverse', False)
243
+ opposite = conf.pop('opposite', None)
239
244
  long = f'--{opt_name}'
240
245
  short = f'-{short_opt}' if short_opt else f'-{opt_name}'
241
246
  if reverse:
242
- long += f'/--no-{opt_name}'
243
- short += f'/-n{short_opt}' if short else f'/-n{opt_name}'
247
+ if opposite:
248
+ long += f'/--{opposite}'
249
+ short += f'/-{opposite[0]}'
250
+ conf['help'] = conf['help'].replace(opt_name, f'{opt_name} / {opposite}')
251
+ else:
252
+ long += f'/--no-{opt_name}'
253
+ short += f'/-n{short_opt}' if short else f'/-n{opt_name}'
244
254
  f = click.option(long, short, **conf)(f)
245
255
  return f
246
256
  return decorator
@@ -321,9 +331,16 @@ def register_runner(cli_endpoint, config):
321
331
  worker = opts.pop('worker')
322
332
  ws = opts.pop('workspace')
323
333
  driver = opts.pop('driver', '')
334
+ quiet = opts['quiet']
335
+ dry_run = opts['dry_run']
324
336
  show = opts['show']
325
337
  context = {'workspace_name': ws}
326
338
 
339
+ # Show runner yaml
340
+ if show:
341
+ config.print()
342
+ sys.exit(0)
343
+
327
344
  # Remove options whose values are default values
328
345
  for k, v in options.items():
329
346
  opt_name = k.replace('-', '_')
@@ -364,7 +381,7 @@ def register_runner(cli_endpoint, config):
364
381
  hooks = deep_merge_dicts(*hooks)
365
382
 
366
383
  # Enable sync or not
367
- if sync or show:
384
+ if sync or dry_run:
368
385
  sync = True
369
386
  else:
370
387
  from secator.celery import is_celery_worker_alive
@@ -394,6 +411,7 @@ def register_runner(cli_endpoint, config):
394
411
  'piped_output': ctx.obj['piped_output'],
395
412
  'caller': 'cli',
396
413
  'sync': sync,
414
+ 'quiet': quiet
397
415
  })
398
416
 
399
417
  # Start runner
@@ -372,6 +372,7 @@ class Command(Runner):
372
372
 
373
373
  # Abort if dry run
374
374
  if self.dry_run:
375
+ self._print('')
375
376
  self.print_command()
376
377
  return
377
378
 
@@ -2,7 +2,8 @@ import os
2
2
  import yaml
3
3
 
4
4
  from secator.decorators import task
5
- from secator.definitions import (OUTPUT_PATH, RATE_LIMIT, THREADS, DELAY, TIMEOUT, METHOD, WORDLIST, HEADER, URL)
5
+ from secator.definitions import (OUTPUT_PATH, RATE_LIMIT, THREADS, DELAY, TIMEOUT, METHOD, WORDLIST,
6
+ HEADER, URL, FOLLOW_REDIRECT)
6
7
  from secator.output_types import Info, Url, Warning, Error
7
8
  from secator.runners import Command
8
9
  from secator.tasks._categories import OPTS
@@ -31,6 +32,7 @@ class arjun(Command):
31
32
  RATE_LIMIT: OPTS[RATE_LIMIT],
32
33
  METHOD: OPTS[METHOD],
33
34
  HEADER: OPTS[HEADER],
35
+ FOLLOW_REDIRECT: OPTS[FOLLOW_REDIRECT],
34
36
  }
35
37
  opt_key_map = {
36
38
  THREADS: 't',
@@ -44,6 +46,7 @@ class arjun(Command):
44
46
  'stable': '--stable',
45
47
  'passive': '--passive',
46
48
  'casing': '--casing',
49
+ 'follow_redirect': '--follow-redirect',
47
50
  }
48
51
  output_types = [Url]
49
52
  install_cmd = 'pipx install arjun && pipx upgrade arjun'
@@ -57,6 +60,11 @@ class arjun(Command):
57
60
 
58
61
  @staticmethod
59
62
  def on_cmd(self):
63
+ follow_redirect = self.get_opt_value(FOLLOW_REDIRECT)
64
+ self.cmd = self.cmd.replace(' --follow-redirect', '')
65
+ if not follow_redirect:
66
+ self.cmd += ' --disable-redirects'
67
+
60
68
  self.output_path = self.get_opt_value(OUTPUT_PATH)
61
69
  if not self.output_path:
62
70
  self.output_path = f'{self.reports_folder}/.outputs/{self.unique_name}.json'
@@ -30,6 +30,7 @@ class TemplateLoader(DotMap):
30
30
  config = input
31
31
  elif isinstance(input, Path) or Path(input).exists():
32
32
  config = self._load_from_path(input)
33
+ config['_path'] = str(input)
33
34
  elif isinstance(input, str):
34
35
  config = self._load(input)
35
36
  super().__init__(config, **kwargs)
@@ -57,6 +58,17 @@ class TemplateLoader(DotMap):
57
58
  """Property to access tasks easily."""
58
59
  return self._extract_tasks()
59
60
 
61
+ def print(self):
62
+ """Print config as highlighted yaml."""
63
+ config = self.toDict()
64
+ _path = config.pop('_path', None)
65
+ if _path:
66
+ console.print(f'[italic green]{_path}[/]\n')
67
+ yaml_str = yaml.dump(config, indent=4)
68
+ from rich.syntax import Syntax
69
+ yaml_highlight = Syntax(yaml_str, 'yaml', line_numbers=True)
70
+ console.print(yaml_highlight)
71
+
60
72
  def _collect_supported_opts(self):
61
73
  """Collect supported options from the tasks extracted from the config."""
62
74
  tasks = self._extract_tasks()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes