thuban 0.4.0 → 0.4.2

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 (209) hide show
  1. package/dist/package.json +63 -0
  2. package/dist/packages/crucible/rules/code-scanner-core.json +129 -0
  3. package/dist/packages/crucible/rules/command-injection.json +411 -0
  4. package/dist/packages/crucible/rules/crypto-misuse.json +35 -0
  5. package/dist/packages/crucible/rules/deserialization.json +152 -0
  6. package/dist/packages/crucible/rules/env-injection.json +46 -0
  7. package/dist/packages/crucible/rules/eval-abuse.json +104 -0
  8. package/dist/packages/crucible/rules/file-upload.json +46 -0
  9. package/dist/packages/crucible/rules/hallucination.json +22 -0
  10. package/dist/packages/crucible/rules/hardcoded-secret.json +397 -0
  11. package/dist/packages/crucible/rules/hardcoded-url.json +13 -0
  12. package/dist/packages/crucible/rules/insecure-crypto.json +302 -0
  13. package/dist/packages/crucible/rules/integer-overflow.json +35 -0
  14. package/dist/packages/crucible/rules/log-injection.json +33 -0
  15. package/dist/packages/crucible/rules/mass-assignment.json +112 -0
  16. package/dist/packages/crucible/rules/open-redirect.json +196 -0
  17. package/dist/packages/crucible/rules/path-traversal.json +422 -0
  18. package/dist/packages/crucible/rules/prototype-pollution.json +22 -0
  19. package/dist/packages/crucible/rules/sql-injection.json +597 -0
  20. package/dist/packages/crucible/rules/ssrf.json +557 -0
  21. package/dist/packages/crucible/rules/timing-attack.json +55 -0
  22. package/dist/packages/crucible/rules/unsafe-block.json +24 -0
  23. package/dist/packages/crucible/rules/xss.json +641 -0
  24. package/dist/packages/crucible/rules/xxe.json +66 -0
  25. package/dist/packages/crucible/rules/yaml-deserialization.json +22 -0
  26. package/dist/packages/crucible/rules/yaml-injection.json +22 -0
  27. package/dist/packages/scanner/executive-report.js +1 -1
  28. package/dist/packages/scanner/hallucination-detector.js +1 -1
  29. package/dist/packages/scanner/secret-scanner.js +1 -1
  30. package/package.json +7 -4
  31. package/dist/packages/crucible/seeds/python/seed-021 3.py +0 -37
  32. package/dist/packages/crucible/seeds/python/seed-022 3.py +0 -34
  33. package/dist/packages/crucible/seeds/python/seed-023 3.py +0 -37
  34. package/dist/packages/crucible/seeds/python/seed-024 3.py +0 -38
  35. package/dist/packages/crucible/seeds/python/seed-025 3.py +0 -40
  36. package/dist/packages/crucible/seeds/python/seed-026 3.py +0 -35
  37. package/dist/packages/crucible/seeds/python/seed-027 3.py +0 -35
  38. package/dist/packages/crucible/seeds/python/seed-028 3.py +0 -42
  39. package/dist/packages/crucible/seeds/python/seed-030 3.py +0 -37
  40. package/dist/packages/crucible/seeds/python/seed-031 3.py +0 -34
  41. package/dist/packages/crucible/seeds/python/seed-036 3.py +0 -33
  42. package/dist/packages/crucible/seeds/python/seed-037 3.py +0 -41
  43. package/dist/packages/crucible/seeds/python/seed-038 3.py +0 -33
  44. package/dist/packages/crucible/seeds/python/seed-039 3.py +0 -39
  45. package/dist/packages/crucible/seeds/python/seed-040 3.py +0 -39
  46. package/dist/packages/crucible/seeds/python/seed-041 3.py +0 -37
  47. package/dist/packages/crucible/seeds/python/seed-042 3.py +0 -38
  48. package/dist/packages/crucible/seeds/python/seed-043 3.py +0 -32
  49. package/dist/packages/crucible/seeds/python/seed-044 3.py +0 -38
  50. package/dist/packages/crucible/seeds/python/seed-045 3.py +0 -36
  51. package/dist/packages/crucible/seeds/python/seed-046 3.py +0 -33
  52. package/dist/packages/crucible/seeds/python/seed-047 3.py +0 -44
  53. package/dist/packages/crucible/seeds/python/seed-048 3.py +0 -35
  54. package/dist/packages/crucible/seeds/python/seed-049 3.py +0 -39
  55. package/dist/packages/crucible/seeds/python/seed-050 3.py +0 -39
  56. package/dist/packages/crucible/seeds/python/seed-051 3.py +0 -38
  57. package/dist/packages/crucible/seeds/python/seed-052 3.py +0 -41
  58. package/dist/packages/crucible/seeds/ruby/seed-001 3.rb +0 -15
  59. package/dist/packages/crucible/seeds/ruby/seed-002 3.rb +0 -22
  60. package/dist/packages/crucible/seeds/ruby/seed-003 3.rb +0 -25
  61. package/dist/packages/crucible/seeds/ruby/seed-004 3.rb +0 -17
  62. package/dist/packages/crucible/seeds/ruby/seed-005 3.rb +0 -21
  63. package/dist/packages/crucible/seeds/ruby/seed-006 3.rb +0 -17
  64. package/dist/packages/crucible/seeds/ruby/seed-007 3.rb +0 -16
  65. package/dist/packages/crucible/seeds/ruby/seed-008 3.rb +0 -18
  66. package/dist/packages/crucible/seeds/ruby/seed-009 3.rb +0 -20
  67. package/dist/packages/crucible/seeds/ruby/seed-010 3.rb +0 -24
  68. package/dist/packages/crucible/seeds/ruby/seed-011 3.rb +0 -21
  69. package/dist/packages/crucible/seeds/ruby/seed-012 3.rb +0 -22
  70. package/dist/packages/crucible/seeds/ruby/seed-013 3.rb +0 -21
  71. package/dist/packages/crucible/seeds/ruby/seed-014 3.rb +0 -16
  72. package/dist/packages/crucible/seeds/ruby/seed-015 3.rb +0 -18
  73. package/dist/packages/crucible/seeds/ruby/seed-016 3.rb +0 -17
  74. package/dist/packages/crucible/seeds/ruby/seed-017 3.rb +0 -25
  75. package/dist/packages/crucible/seeds/ruby/seed-018 3.rb +0 -23
  76. package/dist/packages/crucible/seeds/ruby/seed-019 3.rb +0 -20
  77. package/dist/packages/crucible/seeds/ruby/seed-020 3.rb +0 -17
  78. package/dist/packages/crucible/seeds/ruby/seed-021 3.rb +0 -20
  79. package/dist/packages/crucible/seeds/ruby/seed-022 3.rb +0 -21
  80. package/dist/packages/crucible/seeds/ruby/seed-023 3.rb +0 -19
  81. package/dist/packages/crucible/seeds/ruby/seed-024 3.rb +0 -17
  82. package/dist/packages/crucible/seeds/ruby/seed-025 3.rb +0 -17
  83. package/dist/packages/crucible/seeds/ruby/seed-026 3.rb +0 -18
  84. package/dist/packages/crucible/seeds/ruby/seed-027 3.rb +0 -21
  85. package/dist/packages/crucible/seeds/ruby/seed-028 3.rb +0 -22
  86. package/dist/packages/crucible/seeds/ruby/seed-029 3.rb +0 -19
  87. package/dist/packages/crucible/seeds/ruby/seed-030 3.rb +0 -20
  88. package/dist/packages/crucible/seeds/ruby/seed-031 3.rb +0 -17
  89. package/dist/packages/crucible/seeds/ruby/seed-032 3.rb +0 -22
  90. package/dist/packages/crucible/seeds/ruby/seed-033 3.rb +0 -18
  91. package/dist/packages/crucible/seeds/ruby/seed-034 3.rb +0 -19
  92. package/dist/packages/crucible/seeds/ruby/seed-035 3.rb +0 -19
  93. package/dist/packages/crucible/seeds/ruby/seed-036 3.rb +0 -18
  94. package/dist/packages/crucible/seeds/ruby/seed-037 3.rb +0 -21
  95. package/dist/packages/crucible/seeds/ruby/seed-038 3.rb +0 -24
  96. package/dist/packages/crucible/seeds/ruby/seed-039 3.rb +0 -24
  97. package/dist/packages/crucible/seeds/ruby/seed-040 3.rb +0 -22
  98. package/dist/packages/crucible/seeds/ruby/seed-041 3.rb +0 -23
  99. package/dist/packages/crucible/seeds/ruby/seed-042 3.rb +0 -25
  100. package/dist/packages/crucible/seeds/ruby/seed-043 3.rb +0 -23
  101. package/dist/packages/crucible/seeds/ruby/seed-044 3.rb +0 -16
  102. package/dist/packages/crucible/seeds/ruby/seed-045 3.rb +0 -22
  103. package/dist/packages/crucible/seeds/ruby/seed-046 3.rb +0 -27
  104. package/dist/packages/crucible/seeds/ruby/seed-047 3.rb +0 -26
  105. package/dist/packages/crucible/seeds/ruby/seed-048 3.rb +0 -24
  106. package/dist/packages/crucible/seeds/ruby/seed-049 3.rb +0 -20
  107. package/dist/packages/crucible/seeds/ruby/seed-050 3.rb +0 -27
  108. package/dist/packages/crucible/seeds/rust/seed-001 3.rs +0 -25
  109. package/dist/packages/crucible/seeds/rust/seed-002 3.rs +0 -20
  110. package/dist/packages/crucible/seeds/rust/seed-003 3.rs +0 -23
  111. package/dist/packages/crucible/seeds/rust/seed-004 3.rs +0 -21
  112. package/dist/packages/crucible/seeds/rust/seed-005 3.rs +0 -21
  113. package/dist/packages/crucible/seeds/rust/seed-006 3.rs +0 -24
  114. package/dist/packages/crucible/seeds/rust/seed-007 3.rs +0 -20
  115. package/dist/packages/crucible/seeds/rust/seed-008 3.rs +0 -19
  116. package/dist/packages/crucible/seeds/rust/seed-009 3.rs +0 -28
  117. package/dist/packages/crucible/seeds/rust/seed-010 3.rs +0 -28
  118. package/dist/packages/crucible/seeds/rust/seed-011 3.rs +0 -25
  119. package/dist/packages/crucible/seeds/rust/seed-012 3.rs +0 -31
  120. package/dist/packages/crucible/seeds/rust/seed-013 3.rs +0 -27
  121. package/dist/packages/crucible/seeds/rust/seed-014 3.rs +0 -30
  122. package/dist/packages/crucible/seeds/rust/seed-015 3.rs +0 -33
  123. package/dist/packages/crucible/seeds/rust/seed-016 3.rs +0 -22
  124. package/dist/packages/crucible/seeds/rust/seed-017 3.rs +0 -28
  125. package/dist/packages/crucible/seeds/rust/seed-018 3.rs +0 -21
  126. package/dist/packages/crucible/seeds/rust/seed-019 3.rs +0 -36
  127. package/dist/packages/crucible/seeds/rust/seed-020 3.rs +0 -27
  128. package/dist/packages/crucible/seeds/rust/seed-021 3.rs +0 -26
  129. package/dist/packages/crucible/seeds/rust/seed-022 3.rs +0 -23
  130. package/dist/packages/crucible/seeds/rust/seed-023 3.rs +0 -22
  131. package/dist/packages/crucible/seeds/rust/seed-024 3.rs +0 -24
  132. package/dist/packages/crucible/seeds/rust/seed-025 3.rs +0 -29
  133. package/dist/packages/crucible/seeds/rust/seed-026 3.rs +0 -23
  134. package/dist/packages/crucible/seeds/rust/seed-027 3.rs +0 -24
  135. package/dist/packages/crucible/seeds/rust/seed-028 3.rs +0 -25
  136. package/dist/packages/crucible/seeds/rust/seed-029 3.rs +0 -25
  137. package/dist/packages/crucible/seeds/rust/seed-030 3.rs +0 -30
  138. package/dist/packages/crucible/seeds/rust/seed-031 3.rs +0 -22
  139. package/dist/packages/crucible/seeds/rust/seed-032 3.rs +0 -25
  140. package/dist/packages/crucible/seeds/rust/seed-033 3.rs +0 -25
  141. package/dist/packages/crucible/seeds/rust/seed-034 3.rs +0 -20
  142. package/dist/packages/crucible/seeds/rust/seed-035 3.rs +0 -28
  143. package/dist/packages/crucible/seeds/rust/seed-036 3.rs +0 -26
  144. package/dist/packages/crucible/seeds/rust/seed-037 3.rs +0 -31
  145. package/dist/packages/crucible/seeds/rust/seed-038 3.rs +0 -25
  146. package/dist/packages/crucible/seeds/rust/seed-039 3.rs +0 -28
  147. package/dist/packages/crucible/seeds/rust/seed-040 3.rs +0 -27
  148. package/dist/packages/crucible/seeds/rust/seed-041 3.rs +0 -32
  149. package/dist/packages/crucible/seeds/rust/seed-042 3.rs +0 -27
  150. package/dist/packages/crucible/seeds/rust/seed-043 3.rs +0 -29
  151. package/dist/packages/crucible/seeds/rust/seed-044 3.rs +0 -25
  152. package/dist/packages/crucible/seeds/rust/seed-045 3.rs +0 -28
  153. package/dist/packages/crucible/seeds/rust/seed-046 3.rs +0 -25
  154. package/dist/packages/crucible/seeds/rust/seed-047 3.rs +0 -34
  155. package/dist/packages/crucible/seeds/rust/seed-048 3.rs +0 -21
  156. package/dist/packages/crucible/seeds/rust/seed-049 3.rs +0 -26
  157. package/dist/packages/crucible/seeds/rust/seed-050 3.rs +0 -23
  158. package/dist/packages/crucible/seeds/ts/seed-001 3.ts +0 -32
  159. package/dist/packages/crucible/seeds/ts/seed-002 3.ts +0 -34
  160. package/dist/packages/crucible/seeds/ts/seed-003 3.ts +0 -28
  161. package/dist/packages/crucible/seeds/ts/seed-004 3.ts +0 -34
  162. package/dist/packages/crucible/seeds/ts/seed-005 3.ts +0 -32
  163. package/dist/packages/crucible/seeds/ts/seed-006 3.ts +0 -31
  164. package/dist/packages/crucible/seeds/ts/seed-007 3.ts +0 -28
  165. package/dist/packages/crucible/seeds/ts/seed-008 3.ts +0 -40
  166. package/dist/packages/crucible/seeds/ts/seed-009 3.ts +0 -31
  167. package/dist/packages/crucible/seeds/ts/seed-010 3.ts +0 -33
  168. package/dist/packages/crucible/seeds/ts/seed-011 3.ts +0 -29
  169. package/dist/packages/crucible/seeds/ts/seed-012 3.ts +0 -34
  170. package/dist/packages/crucible/seeds/ts/seed-013 3.ts +0 -31
  171. package/dist/packages/crucible/seeds/ts/seed-014 3.ts +0 -36
  172. package/dist/packages/crucible/seeds/ts/seed-015 3.ts +0 -31
  173. package/dist/packages/crucible/seeds/ts/seed-016 3.ts +0 -37
  174. package/dist/packages/crucible/seeds/ts/seed-017 3.ts +0 -44
  175. package/dist/packages/crucible/seeds/ts/seed-018 3.ts +0 -33
  176. package/dist/packages/crucible/seeds/ts/seed-019 3.ts +0 -32
  177. package/dist/packages/crucible/seeds/ts/seed-020 3.ts +0 -33
  178. package/dist/packages/crucible/seeds/ts/seed-021 3.ts +0 -33
  179. package/dist/packages/crucible/seeds/ts/seed-022 3.ts +0 -34
  180. package/dist/packages/crucible/seeds/ts/seed-023 3.ts +0 -33
  181. package/dist/packages/crucible/seeds/ts/seed-024 3.ts +0 -35
  182. package/dist/packages/crucible/seeds/ts/seed-025 3.ts +0 -29
  183. package/dist/packages/crucible/seeds/ts/seed-026 3.ts +0 -36
  184. package/dist/packages/crucible/seeds/ts/seed-027 3.ts +0 -30
  185. package/dist/packages/crucible/seeds/ts/seed-028 3.ts +0 -32
  186. package/dist/packages/crucible/seeds/ts/seed-029 3.ts +0 -34
  187. package/dist/packages/crucible/seeds/ts/seed-030 3.ts +0 -37
  188. package/dist/packages/crucible/seeds/ts/seed-031 3.ts +0 -31
  189. package/dist/packages/crucible/seeds/ts/seed-032 3.ts +0 -32
  190. package/dist/packages/crucible/seeds/ts/seed-033 3.ts +0 -32
  191. package/dist/packages/crucible/seeds/ts/seed-034 3.ts +0 -34
  192. package/dist/packages/crucible/seeds/ts/seed-035 3.ts +0 -29
  193. package/dist/packages/crucible/seeds/ts/seed-036 3.ts +0 -34
  194. package/dist/packages/crucible/seeds/ts/seed-037 3.ts +0 -33
  195. package/dist/packages/crucible/seeds/ts/seed-038 3.ts +0 -29
  196. package/dist/packages/crucible/seeds/ts/seed-039 3.ts +0 -35
  197. package/dist/packages/crucible/seeds/ts/seed-040 3.ts +0 -31
  198. package/dist/packages/crucible/seeds/ts/seed-041 3.ts +0 -29
  199. package/dist/packages/crucible/seeds/ts/seed-042 3.ts +0 -33
  200. package/dist/packages/crucible/seeds/ts/seed-043 3.ts +0 -32
  201. package/dist/packages/crucible/seeds/ts/seed-044 3.ts +0 -36
  202. package/dist/packages/crucible/seeds/ts/seed-045 3.ts +0 -39
  203. package/dist/packages/crucible/seeds/ts/seed-046 3.ts +0 -41
  204. package/dist/packages/crucible/seeds/ts/seed-047 3.ts +0 -33
  205. package/dist/packages/crucible/seeds/ts/seed-048 3.ts +0 -33
  206. package/dist/packages/crucible/seeds/ts/seed-049 3.ts +0 -34
  207. package/dist/packages/crucible/seeds/ts/seed-050 3.ts +0 -41
  208. package/dist/packages/crucible/seeds/ts/seed-051 3.ts +0 -34
  209. package/dist/packages/crucible/seeds/ts/seed-052 3.ts +0 -36
@@ -1,23 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: xss
3
- # severity: high
4
- # language: ruby
5
- # expected: Sinatra response body includes user param without escaping
6
-
7
- require 'sinatra'
8
-
9
- get '/greet' do
10
- name = params[:name]
11
- query = params[:q]
12
- "<html><body><h1>Hello, #{name}!</h1><p>Results for: #{query}</p></body></html>"
13
- end
14
-
15
- get '/error' do
16
- msg = params[:message]
17
- "<div class='error'>#{msg}</div>"
18
- end
19
-
20
- post '/comment' do
21
- comment = params[:comment]
22
- "<p>Your comment: #{comment}</p>"
23
- end
@@ -1,20 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: xss
3
- # severity: medium
4
- # language: ruby
5
- # expected: User content embedded in JSON output that is then eval()d client-side
6
-
7
- class ApiController < ApplicationController
8
- def user_data
9
- user = User.find(params[:id])
10
- bio = params[:bio] || user.bio
11
- @json = { name: user.name, bio: bio, role: params[:role] }
12
- render json: @json
13
- end
14
-
15
- def config
16
- callback = params[:callback]
17
- data = { status: 'ok', user: current_user&.name }
18
- render plain: "#{callback}(#{data.to_json})"
19
- end
20
- end
@@ -1,17 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: xss
3
- # severity: high
4
- # language: ruby
5
- # expected: content_tag or link_to with unescaped user attribute
6
-
7
- def build_link(url, label, css_class)
8
- "<a href='#{url}' class='#{css_class}'>#{label}</a>"
9
- end
10
-
11
- def build_input(name, value, placeholder)
12
- "<input name='#{name}' value='#{value}' placeholder='#{placeholder}'>"
13
- end
14
-
15
- def build_script_tag(variable_name, data)
16
- "<script>var #{variable_name} = #{data.to_json};</script>"
17
- end
@@ -1,20 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: xss
3
- # severity: high
4
- # language: ruby
5
- # expected: ActionMailer HTML email built with unescaped user content
6
-
7
- class NotificationMailer < ApplicationMailer
8
- def welcome_email(user, custom_message)
9
- @user = user
10
- @message = custom_message
11
- @subject = params[:subject] || "Welcome!"
12
-
13
- mail(
14
- to: @user.email,
15
- subject: @subject
16
- ) do |format|
17
- format.html { render html: "<h1>#{@user.name}</h1><p>#{@message}</p>".html_safe }
18
- end
19
- end
20
- end
@@ -1,21 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: xss
3
- # severity: medium
4
- # language: ruby
5
- # expected: ERB template rendered with user string directly substituted
6
-
7
- require 'erb'
8
-
9
- def render_template(template_string, user_data)
10
- ERB.new(template_string).result(binding)
11
- end
12
-
13
- def personalize_email(user_name, promo_code)
14
- template = "Hello <%= user_name %>, your promo code is: <%= promo_code %>"
15
- ERB.new(template).result(binding)
16
- end
17
-
18
- def build_page(title, body, footer)
19
- tmpl = "<html><head><title><%= title %></title></head><body><%= body %><footer><%= footer %></footer></body></html>"
20
- ERB.new(tmpl).result(binding)
21
- end
@@ -1,19 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: command_injection
3
- # severity: critical
4
- # language: ruby
5
- # expected: Backtick operator with user-supplied input — command injection
6
-
7
- class SystemController < ApplicationController
8
- def ping
9
- host = params[:host]
10
- result = `ping -c 4 #{host}`
11
- render plain: result
12
- end
13
-
14
- def dns_lookup
15
- domain = params[:domain]
16
- output = `nslookup #{domain}`
17
- render plain: output
18
- end
19
- end
@@ -1,17 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: command_injection
3
- # severity: critical
4
- # language: ruby
5
- # expected: system() with user-controlled arguments — command injection
6
-
7
- def convert_image(src, dest, width, height)
8
- system("convert #{src} -resize #{width}x#{height} #{dest}")
9
- end
10
-
11
- def compress_archive(dir_path, output_name)
12
- system("tar -czf /tmp/#{output_name} #{dir_path}")
13
- end
14
-
15
- def run_script(script_name, args)
16
- system("/opt/scripts/#{script_name} #{args}")
17
- end
@@ -1,17 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: command_injection
3
- # severity: critical
4
- # language: ruby
5
- # expected: exec() with user-controlled command — replaces process, no return
6
-
7
- def execute_task(command)
8
- exec(command)
9
- end
10
-
11
- def run_user_script(script_path, user_arg)
12
- exec("ruby #{script_path} #{user_arg}")
13
- end
14
-
15
- def start_service(service_name, config_file)
16
- exec("#{service_name} --config #{config_file}")
17
- end
@@ -1,18 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: command_injection
3
- # severity: critical
4
- # language: ruby
5
- # expected: Open3.capture2 with shell string — user input in format string
6
-
7
- require 'open3'
8
-
9
- def run_ffmpeg(input_file, output_file, codec)
10
- cmd = "ffmpeg -i '#{input_file}' -c:v #{codec} '#{output_file}'"
11
- stdout, stderr, status = Open3.capture2(cmd)
12
- { output: stdout, error: stderr, success: status.success? }
13
- end
14
-
15
- def grep_logs(pattern, log_file)
16
- stdout, _ = Open3.capture2("grep -n '#{pattern}' /var/log/#{log_file}")
17
- stdout
18
- end
@@ -1,21 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: command_injection
3
- # severity: critical
4
- # language: ruby
5
- # expected: IO.popen with user-controlled shell string
6
-
7
- def tail_log(log_name, lines)
8
- IO.popen("tail -n #{lines} /var/log/#{log_name}") do |f|
9
- f.read
10
- end
11
- end
12
-
13
- def search_file(filename, keyword)
14
- IO.popen("grep '#{keyword}' /data/#{filename}") do |io|
15
- io.read
16
- end
17
- end
18
-
19
- def pipe_command(cmd)
20
- IO.popen(cmd) { |f| f.read }
21
- end
@@ -1,22 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: command_injection
3
- # severity: high
4
- # language: ruby
5
- # expected: Kernel.system called with interpolated hostname for network diagnostics
6
-
7
- class DiagnosticsController < ApplicationController
8
- def check_connectivity
9
- host = params[:host]
10
- port = params[:port]
11
- timeout = params[:timeout] || '5'
12
-
13
- result = `nc -zv -w #{timeout} #{host} #{port} 2>&1`
14
- render json: { output: result, host: host, port: port }
15
- end
16
-
17
- def whois_lookup
18
- domain = params[:domain]
19
- output = `whois #{domain}`
20
- render plain: output
21
- end
22
- end
@@ -1,19 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: path_traversal
3
- # severity: critical
4
- # language: ruby
5
- # expected: File.read with unvalidated user-supplied path
6
-
7
- class FilesController < ApplicationController
8
- def show
9
- filename = params[:filename]
10
- content = File.read("/var/app/uploads/#{filename}")
11
- render plain: content
12
- end
13
-
14
- def download
15
- path = params[:path]
16
- data = File.read(path)
17
- send_data data, filename: File.basename(path)
18
- end
19
- end
@@ -1,20 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: path_traversal
3
- # severity: critical
4
- # language: ruby
5
- # expected: send_file with user-controlled path — arbitrary file download
6
-
7
- class DownloadsController < ApplicationController
8
- def get_file
9
- filename = params[:file]
10
- base_dir = Rails.root.join('public', 'downloads')
11
- file_path = File.join(base_dir, filename)
12
- send_file file_path
13
- end
14
-
15
- def export
16
- name = params[:name]
17
- path = "/var/reports/#{name}"
18
- send_file path, type: 'application/octet-stream'
19
- end
20
- end
@@ -1,17 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: path_traversal
3
- # severity: critical
4
- # language: ruby
5
- # expected: Zip extraction writes files using entry name without sanitization — zip slip
6
-
7
- require 'zip'
8
-
9
- def extract_zip(zip_path, dest_dir)
10
- Zip::File.open(zip_path) do |zip|
11
- zip.each do |entry|
12
- output_path = File.join(dest_dir, entry.name)
13
- FileUtils.mkdir_p(File.dirname(output_path))
14
- entry.extract(output_path) { true }
15
- end
16
- end
17
- end
@@ -1,22 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: path_traversal
3
- # severity: high
4
- # language: ruby
5
- # expected: File.write to user-controlled destination path
6
-
7
- def save_export(filename, data)
8
- path = "/var/app/exports/#{filename}"
9
- File.write(path, data)
10
- path
11
- end
12
-
13
- def cache_response(cache_key, content)
14
- cache_path = "/tmp/cache/#{cache_key}"
15
- FileUtils.mkdir_p(File.dirname(cache_path))
16
- File.write(cache_path, content)
17
- end
18
-
19
- def write_template(template_name, subdir, content)
20
- full_path = "/app/templates/#{subdir}/#{template_name}"
21
- File.write(full_path, content)
22
- end
@@ -1,18 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: path_traversal
3
- # severity: critical
4
- # language: ruby
5
- # expected: Dir.glob and File.open with user-controlled subdirectory
6
-
7
- def list_files(base_dir, subdir)
8
- Dir.glob("#{base_dir}/#{subdir}/*").map { |f| File.basename(f) }
9
- end
10
-
11
- def read_config(config_name)
12
- File.open("/etc/app/configs/#{config_name}") { |f| f.read }
13
- end
14
-
15
- def load_plugin(plugin_id)
16
- manifest = File.read("./plugins/#{plugin_id}/manifest.json")
17
- JSON.parse(manifest)
18
- end
@@ -1,19 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: mass_assignment
3
- # severity: high
4
- # language: ruby
5
- # expected: params.permit(:all) or ActionController::Parameters without strong params
6
-
7
- class UsersController < ApplicationController
8
- def update
9
- @user = User.find(params[:id])
10
- @user.update(params[:user])
11
- redirect_to @user
12
- end
13
-
14
- def create
15
- @user = User.new(params[:user].permit!)
16
- @user.save
17
- render json: @user
18
- end
19
- end
@@ -1,19 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: mass_assignment
3
- # severity: high
4
- # language: ruby
5
- # expected: ActiveRecord.new(params) without strong parameters — mass assignment
6
-
7
- class ProfilesController < ApplicationController
8
- def update
9
- profile = Profile.find(params[:id])
10
- profile.update_attributes(params[:profile])
11
- render json: profile
12
- end
13
-
14
- def create
15
- profile = Profile.new(params)
16
- profile.save!
17
- render json: profile, status: :created
18
- end
19
- end
@@ -1,18 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: mass_assignment
3
- # severity: critical
4
- # language: ruby
5
- # expected: attr_accessible :all or missing attr_protected — mass assignment in model
6
-
7
- class User < ActiveRecord::Base
8
- # No attr_protected or attr_accessible defined
9
- # Allows setting admin, role, confirmed fields via mass assignment
10
-
11
- def self.create_from_params(params)
12
- create(params)
13
- end
14
-
15
- def self.register(registration_params)
16
- new(registration_params).tap(&:save)
17
- end
18
- end
@@ -1,21 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: mass_assignment
3
- # severity: high
4
- # language: ruby
5
- # expected: slice(:all) or no-arg permit! allowing all user-supplied attributes
6
-
7
- class OrdersController < ApplicationController
8
- def create
9
- permitted = params.require(:order).permit!
10
- @order = Order.create(permitted)
11
- render json: @order
12
- end
13
-
14
- def bulk_update
15
- params[:records].each do |record_params|
16
- item = Item.find(record_params[:id])
17
- item.update(record_params.except(:id))
18
- end
19
- render json: { updated: params[:records].count }
20
- end
21
- end
@@ -1,24 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: mass_assignment
3
- # severity: high
4
- # language: ruby
5
- # expected: Mongoid or other ODM with unfiltered hash assignment
6
-
7
- require 'mongoid'
8
-
9
- class Document
10
- include Mongoid::Document
11
-
12
- field :title, type: String
13
- field :content, type: String
14
- field :admin, type: Boolean, default: false
15
- field :role, type: String, default: 'user'
16
-
17
- def self.create_from_hash(attrs)
18
- create!(attrs)
19
- end
20
-
21
- def update_from_request(request_params)
22
- update_attributes!(request_params)
23
- end
24
- end
@@ -1,24 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: ssrf
3
- # severity: critical
4
- # language: ruby
5
- # expected: Net::HTTP.get_response with user-controlled URL — SSRF
6
-
7
- require 'net/http'
8
- require 'uri'
9
-
10
- class ProxyController < ApplicationController
11
- def fetch
12
- url = params[:url]
13
- uri = URI.parse(url)
14
- response = Net::HTTP.get_response(uri)
15
- render plain: response.body
16
- end
17
-
18
- def check_endpoint
19
- target = params[:endpoint]
20
- uri = URI(target)
21
- res = Net::HTTP.get_response(uri)
22
- render json: { status: res.code, body: res.body[0..200] }
23
- end
24
- end
@@ -1,22 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: ssrf
3
- # severity: critical
4
- # language: ruby
5
- # expected: HTTParty.get with user-supplied URL — SSRF to internal services
6
-
7
- require 'httparty'
8
-
9
- class WebhookController < ApplicationController
10
- def trigger
11
- callback_url = params[:callback]
12
- payload = { event: 'triggered', timestamp: Time.now.to_i }
13
- HTTParty.post(callback_url, body: payload.to_json, headers: { 'Content-Type' => 'application/json' })
14
- render json: { triggered: true }
15
- end
16
-
17
- def preview_url
18
- url = params[:url]
19
- resp = HTTParty.get(url, timeout: 5)
20
- render plain: resp.body
21
- end
22
- end
@@ -1,23 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: ssrf
3
- # severity: critical
4
- # language: ruby
5
- # expected: Faraday connection built from user-controlled base URL
6
-
7
- require 'faraday'
8
-
9
- class ImportController < ApplicationController
10
- def import_feed
11
- source_url = params[:feed_url]
12
- conn = Faraday.new(url: source_url)
13
- response = conn.get('/')
14
- data = JSON.parse(response.body)
15
- render json: { imported: data.size }
16
- end
17
-
18
- def fetch_avatar
19
- avatar_url = params[:avatar_url]
20
- response = Faraday.get(avatar_url)
21
- send_data response.body, type: 'image/jpeg'
22
- end
23
- end
@@ -1,25 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: ssrf
3
- # severity: high
4
- # language: ruby
5
- # expected: open-uri used to fetch user-supplied URL — SSRF including file:// scheme
6
-
7
- require 'open-uri'
8
-
9
- def fetch_remote_resource(url)
10
- URI.open(url).read
11
- end
12
-
13
- def download_image(image_url)
14
- URI.open(image_url) do |f|
15
- File.write('/tmp/downloaded_image', f.read)
16
- end
17
- end
18
-
19
- class ResourceController < ApplicationController
20
- def import
21
- resource_url = params[:url]
22
- content = URI.open(resource_url).read
23
- render plain: content
24
- end
25
- end
@@ -1,23 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: ssrf
3
- # severity: critical
4
- # language: ruby
5
- # expected: RestClient.get with user-supplied URL — SSRF
6
-
7
- require 'rest-client'
8
-
9
- class ProxyService
10
- def self.relay(target_url, headers = {})
11
- RestClient.get(target_url, headers)
12
- rescue RestClient::Exception => e
13
- e.response
14
- end
15
-
16
- def self.post_webhook(url, payload)
17
- RestClient.post(url, payload.to_json, content_type: :json)
18
- end
19
-
20
- def self.check_health(host)
21
- RestClient.get("http://#{host}/health")
22
- end
23
- end
@@ -1,16 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: open_redirect
3
- # severity: high
4
- # language: ruby
5
- # expected: redirect_to params[:url] without validation — open redirect
6
-
7
- class SessionsController < ApplicationController
8
- def create
9
- if authenticated?
10
- redirect_to params[:url] || root_path
11
- else
12
- flash[:error] = 'Invalid credentials'
13
- render :new
14
- end
15
- end
16
- end
@@ -1,22 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: open_redirect
3
- # severity: high
4
- # language: ruby
5
- # expected: redirect_to with 'next' or 'return_to' parameter — open redirect after login
6
-
7
- class AuthController < ApplicationController
8
- def callback
9
- next_url = params[:next] || params[:return_to] || dashboard_path
10
- redirect_to next_url
11
- end
12
-
13
- def logout
14
- sign_out current_user
15
- redirect_to params[:redirect]
16
- end
17
-
18
- def sso_redirect
19
- target = request.params['RelayState'] || root_url
20
- redirect_to target, allow_other_host: true
21
- end
22
- end
@@ -1,27 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: open_redirect
3
- # severity: medium
4
- # language: ruby
5
- # expected: Regex-based redirect validation bypassable with CRLF or subdomain trick
6
-
7
- class RedirectController < ApplicationController
8
- SAFE_DOMAIN = 'example.com'
9
-
10
- def go
11
- target = params[:to]
12
- if target =~ /example\.com/
13
- redirect_to target, allow_other_host: true
14
- else
15
- redirect_to root_path
16
- end
17
- end
18
-
19
- def external
20
- url = params[:url]
21
- trusted = ['example.com', 'partner.com']
22
- host = URI.parse(url).host rescue ''
23
- if trusted.include?(host)
24
- redirect_to url, allow_other_host: true
25
- end
26
- end
27
- end
@@ -1,26 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: open_redirect
3
- # severity: high
4
- # language: ruby
5
- # expected: send_file or redirect after download with user-controlled path
6
-
7
- class DownloadsController < ApplicationController
8
- def complete
9
- file = params[:file]
10
- callback = params[:callback_url]
11
- send_file Rails.root.join('public', 'downloads', file)
12
- redirect_to callback
13
- end
14
-
15
- def track_and_redirect
16
- destination = params[:destination]
17
- track_click(destination)
18
- redirect_to destination, allow_other_host: true
19
- end
20
-
21
- private
22
-
23
- def track_click(url)
24
- ClickLog.create(url: url, user_id: current_user&.id)
25
- end
26
- end