thuban 0.4.12 → 0.4.13

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 (184) hide show
  1. package/dist/cli.js +1 -1
  2. package/dist/package.json +1 -1
  3. package/dist/packages/crucible/rules/code-scanner-core.json +11 -0
  4. package/dist/packages/scanner/ghost-code-detector.js +1 -1
  5. package/package.json +1 -1
  6. package/dist/packages/crucible/seeds/python/seed-021 2.py +0 -37
  7. package/dist/packages/crucible/seeds/python/seed-022 2.py +0 -34
  8. package/dist/packages/crucible/seeds/python/seed-023 2.py +0 -37
  9. package/dist/packages/crucible/seeds/python/seed-024 2.py +0 -38
  10. package/dist/packages/crucible/seeds/python/seed-025 2.py +0 -40
  11. package/dist/packages/crucible/seeds/python/seed-026 2.py +0 -35
  12. package/dist/packages/crucible/seeds/python/seed-027 2.py +0 -35
  13. package/dist/packages/crucible/seeds/python/seed-028 2.py +0 -42
  14. package/dist/packages/crucible/seeds/python/seed-030 2.py +0 -37
  15. package/dist/packages/crucible/seeds/python/seed-031 2.py +0 -34
  16. package/dist/packages/crucible/seeds/python/seed-036 2.py +0 -33
  17. package/dist/packages/crucible/seeds/python/seed-037 2.py +0 -41
  18. package/dist/packages/crucible/seeds/python/seed-038 2.py +0 -33
  19. package/dist/packages/crucible/seeds/python/seed-039 2.py +0 -39
  20. package/dist/packages/crucible/seeds/python/seed-040 2.py +0 -39
  21. package/dist/packages/crucible/seeds/python/seed-041 2.py +0 -37
  22. package/dist/packages/crucible/seeds/python/seed-042 2.py +0 -38
  23. package/dist/packages/crucible/seeds/python/seed-043 2.py +0 -32
  24. package/dist/packages/crucible/seeds/python/seed-044 2.py +0 -38
  25. package/dist/packages/crucible/seeds/python/seed-045 2.py +0 -36
  26. package/dist/packages/crucible/seeds/python/seed-046 2.py +0 -33
  27. package/dist/packages/crucible/seeds/python/seed-047 2.py +0 -44
  28. package/dist/packages/crucible/seeds/python/seed-048 2.py +0 -35
  29. package/dist/packages/crucible/seeds/python/seed-049 2.py +0 -39
  30. package/dist/packages/crucible/seeds/python/seed-050 2.py +0 -39
  31. package/dist/packages/crucible/seeds/python/seed-051 2.py +0 -38
  32. package/dist/packages/crucible/seeds/python/seed-052 2.py +0 -41
  33. package/dist/packages/crucible/seeds/ruby/seed-001 2.rb +0 -15
  34. package/dist/packages/crucible/seeds/ruby/seed-002 2.rb +0 -22
  35. package/dist/packages/crucible/seeds/ruby/seed-003 2.rb +0 -25
  36. package/dist/packages/crucible/seeds/ruby/seed-004 2.rb +0 -17
  37. package/dist/packages/crucible/seeds/ruby/seed-005 2.rb +0 -21
  38. package/dist/packages/crucible/seeds/ruby/seed-006 2.rb +0 -17
  39. package/dist/packages/crucible/seeds/ruby/seed-007 2.rb +0 -16
  40. package/dist/packages/crucible/seeds/ruby/seed-008 2.rb +0 -18
  41. package/dist/packages/crucible/seeds/ruby/seed-009 2.rb +0 -20
  42. package/dist/packages/crucible/seeds/ruby/seed-010 2.rb +0 -24
  43. package/dist/packages/crucible/seeds/ruby/seed-011 2.rb +0 -21
  44. package/dist/packages/crucible/seeds/ruby/seed-012 2.rb +0 -22
  45. package/dist/packages/crucible/seeds/ruby/seed-013 2.rb +0 -21
  46. package/dist/packages/crucible/seeds/ruby/seed-014 2.rb +0 -16
  47. package/dist/packages/crucible/seeds/ruby/seed-015 2.rb +0 -18
  48. package/dist/packages/crucible/seeds/ruby/seed-016 2.rb +0 -17
  49. package/dist/packages/crucible/seeds/ruby/seed-017 2.rb +0 -25
  50. package/dist/packages/crucible/seeds/ruby/seed-018 2.rb +0 -23
  51. package/dist/packages/crucible/seeds/ruby/seed-019 2.rb +0 -20
  52. package/dist/packages/crucible/seeds/ruby/seed-020 2.rb +0 -17
  53. package/dist/packages/crucible/seeds/ruby/seed-021 2.rb +0 -20
  54. package/dist/packages/crucible/seeds/ruby/seed-022 2.rb +0 -21
  55. package/dist/packages/crucible/seeds/ruby/seed-023 2.rb +0 -19
  56. package/dist/packages/crucible/seeds/ruby/seed-024 2.rb +0 -17
  57. package/dist/packages/crucible/seeds/ruby/seed-025 2.rb +0 -17
  58. package/dist/packages/crucible/seeds/ruby/seed-026 2.rb +0 -18
  59. package/dist/packages/crucible/seeds/ruby/seed-027 2.rb +0 -21
  60. package/dist/packages/crucible/seeds/ruby/seed-028 2.rb +0 -22
  61. package/dist/packages/crucible/seeds/ruby/seed-029 2.rb +0 -19
  62. package/dist/packages/crucible/seeds/ruby/seed-030 2.rb +0 -20
  63. package/dist/packages/crucible/seeds/ruby/seed-031 2.rb +0 -17
  64. package/dist/packages/crucible/seeds/ruby/seed-032 2.rb +0 -22
  65. package/dist/packages/crucible/seeds/ruby/seed-033 2.rb +0 -18
  66. package/dist/packages/crucible/seeds/ruby/seed-034 2.rb +0 -19
  67. package/dist/packages/crucible/seeds/ruby/seed-035 2.rb +0 -19
  68. package/dist/packages/crucible/seeds/ruby/seed-036 2.rb +0 -18
  69. package/dist/packages/crucible/seeds/ruby/seed-037 2.rb +0 -21
  70. package/dist/packages/crucible/seeds/ruby/seed-038 2.rb +0 -24
  71. package/dist/packages/crucible/seeds/ruby/seed-039 2.rb +0 -24
  72. package/dist/packages/crucible/seeds/ruby/seed-040 2.rb +0 -22
  73. package/dist/packages/crucible/seeds/ruby/seed-041 2.rb +0 -23
  74. package/dist/packages/crucible/seeds/ruby/seed-042 2.rb +0 -25
  75. package/dist/packages/crucible/seeds/ruby/seed-043 2.rb +0 -23
  76. package/dist/packages/crucible/seeds/ruby/seed-044 2.rb +0 -16
  77. package/dist/packages/crucible/seeds/ruby/seed-045 2.rb +0 -22
  78. package/dist/packages/crucible/seeds/ruby/seed-046 2.rb +0 -27
  79. package/dist/packages/crucible/seeds/ruby/seed-047 2.rb +0 -26
  80. package/dist/packages/crucible/seeds/ruby/seed-048 2.rb +0 -24
  81. package/dist/packages/crucible/seeds/ruby/seed-049 2.rb +0 -20
  82. package/dist/packages/crucible/seeds/ruby/seed-050 2.rb +0 -27
  83. package/dist/packages/crucible/seeds/rust/seed-001 2.rs +0 -25
  84. package/dist/packages/crucible/seeds/rust/seed-002 2.rs +0 -20
  85. package/dist/packages/crucible/seeds/rust/seed-003 2.rs +0 -23
  86. package/dist/packages/crucible/seeds/rust/seed-004 2.rs +0 -21
  87. package/dist/packages/crucible/seeds/rust/seed-005 2.rs +0 -21
  88. package/dist/packages/crucible/seeds/rust/seed-006 2.rs +0 -24
  89. package/dist/packages/crucible/seeds/rust/seed-007 2.rs +0 -20
  90. package/dist/packages/crucible/seeds/rust/seed-008 2.rs +0 -19
  91. package/dist/packages/crucible/seeds/rust/seed-009 2.rs +0 -28
  92. package/dist/packages/crucible/seeds/rust/seed-010 2.rs +0 -28
  93. package/dist/packages/crucible/seeds/rust/seed-011 2.rs +0 -25
  94. package/dist/packages/crucible/seeds/rust/seed-012 2.rs +0 -31
  95. package/dist/packages/crucible/seeds/rust/seed-013 2.rs +0 -27
  96. package/dist/packages/crucible/seeds/rust/seed-014 2.rs +0 -30
  97. package/dist/packages/crucible/seeds/rust/seed-015 2.rs +0 -33
  98. package/dist/packages/crucible/seeds/rust/seed-016 2.rs +0 -22
  99. package/dist/packages/crucible/seeds/rust/seed-017 2.rs +0 -28
  100. package/dist/packages/crucible/seeds/rust/seed-018 2.rs +0 -21
  101. package/dist/packages/crucible/seeds/rust/seed-019 2.rs +0 -36
  102. package/dist/packages/crucible/seeds/rust/seed-020 2.rs +0 -27
  103. package/dist/packages/crucible/seeds/rust/seed-021 2.rs +0 -26
  104. package/dist/packages/crucible/seeds/rust/seed-022 2.rs +0 -23
  105. package/dist/packages/crucible/seeds/rust/seed-023 2.rs +0 -22
  106. package/dist/packages/crucible/seeds/rust/seed-024 2.rs +0 -24
  107. package/dist/packages/crucible/seeds/rust/seed-025 2.rs +0 -29
  108. package/dist/packages/crucible/seeds/rust/seed-026 2.rs +0 -23
  109. package/dist/packages/crucible/seeds/rust/seed-027 2.rs +0 -24
  110. package/dist/packages/crucible/seeds/rust/seed-028 2.rs +0 -25
  111. package/dist/packages/crucible/seeds/rust/seed-029 2.rs +0 -25
  112. package/dist/packages/crucible/seeds/rust/seed-030 2.rs +0 -30
  113. package/dist/packages/crucible/seeds/rust/seed-031 2.rs +0 -22
  114. package/dist/packages/crucible/seeds/rust/seed-032 2.rs +0 -25
  115. package/dist/packages/crucible/seeds/rust/seed-033 2.rs +0 -25
  116. package/dist/packages/crucible/seeds/rust/seed-034 2.rs +0 -20
  117. package/dist/packages/crucible/seeds/rust/seed-035 2.rs +0 -28
  118. package/dist/packages/crucible/seeds/rust/seed-036 2.rs +0 -26
  119. package/dist/packages/crucible/seeds/rust/seed-037 2.rs +0 -31
  120. package/dist/packages/crucible/seeds/rust/seed-038 2.rs +0 -25
  121. package/dist/packages/crucible/seeds/rust/seed-039 2.rs +0 -28
  122. package/dist/packages/crucible/seeds/rust/seed-040 2.rs +0 -27
  123. package/dist/packages/crucible/seeds/rust/seed-041 2.rs +0 -32
  124. package/dist/packages/crucible/seeds/rust/seed-042 2.rs +0 -27
  125. package/dist/packages/crucible/seeds/rust/seed-043 2.rs +0 -29
  126. package/dist/packages/crucible/seeds/rust/seed-044 2.rs +0 -25
  127. package/dist/packages/crucible/seeds/rust/seed-045 2.rs +0 -28
  128. package/dist/packages/crucible/seeds/rust/seed-046 2.rs +0 -25
  129. package/dist/packages/crucible/seeds/rust/seed-047 2.rs +0 -34
  130. package/dist/packages/crucible/seeds/rust/seed-048 2.rs +0 -21
  131. package/dist/packages/crucible/seeds/rust/seed-049 2.rs +0 -26
  132. package/dist/packages/crucible/seeds/rust/seed-050 2.rs +0 -23
  133. package/dist/packages/crucible/seeds/ts/seed-001 2.ts +0 -32
  134. package/dist/packages/crucible/seeds/ts/seed-002 2.ts +0 -34
  135. package/dist/packages/crucible/seeds/ts/seed-003 2.ts +0 -28
  136. package/dist/packages/crucible/seeds/ts/seed-004 2.ts +0 -34
  137. package/dist/packages/crucible/seeds/ts/seed-005 2.ts +0 -32
  138. package/dist/packages/crucible/seeds/ts/seed-006 2.ts +0 -31
  139. package/dist/packages/crucible/seeds/ts/seed-007 2.ts +0 -28
  140. package/dist/packages/crucible/seeds/ts/seed-008 2.ts +0 -40
  141. package/dist/packages/crucible/seeds/ts/seed-009 2.ts +0 -31
  142. package/dist/packages/crucible/seeds/ts/seed-010 2.ts +0 -33
  143. package/dist/packages/crucible/seeds/ts/seed-011 2.ts +0 -29
  144. package/dist/packages/crucible/seeds/ts/seed-012 2.ts +0 -34
  145. package/dist/packages/crucible/seeds/ts/seed-013 2.ts +0 -31
  146. package/dist/packages/crucible/seeds/ts/seed-014 2.ts +0 -36
  147. package/dist/packages/crucible/seeds/ts/seed-015 2.ts +0 -31
  148. package/dist/packages/crucible/seeds/ts/seed-016 2.ts +0 -37
  149. package/dist/packages/crucible/seeds/ts/seed-017 2.ts +0 -44
  150. package/dist/packages/crucible/seeds/ts/seed-018 2.ts +0 -33
  151. package/dist/packages/crucible/seeds/ts/seed-019 2.ts +0 -32
  152. package/dist/packages/crucible/seeds/ts/seed-020 2.ts +0 -33
  153. package/dist/packages/crucible/seeds/ts/seed-021 2.ts +0 -33
  154. package/dist/packages/crucible/seeds/ts/seed-022 2.ts +0 -34
  155. package/dist/packages/crucible/seeds/ts/seed-023 2.ts +0 -33
  156. package/dist/packages/crucible/seeds/ts/seed-024 2.ts +0 -35
  157. package/dist/packages/crucible/seeds/ts/seed-025 2.ts +0 -29
  158. package/dist/packages/crucible/seeds/ts/seed-026 2.ts +0 -36
  159. package/dist/packages/crucible/seeds/ts/seed-027 2.ts +0 -30
  160. package/dist/packages/crucible/seeds/ts/seed-028 2.ts +0 -32
  161. package/dist/packages/crucible/seeds/ts/seed-029 2.ts +0 -34
  162. package/dist/packages/crucible/seeds/ts/seed-030 2.ts +0 -37
  163. package/dist/packages/crucible/seeds/ts/seed-031 2.ts +0 -31
  164. package/dist/packages/crucible/seeds/ts/seed-032 2.ts +0 -32
  165. package/dist/packages/crucible/seeds/ts/seed-033 2.ts +0 -32
  166. package/dist/packages/crucible/seeds/ts/seed-034 2.ts +0 -34
  167. package/dist/packages/crucible/seeds/ts/seed-035 2.ts +0 -29
  168. package/dist/packages/crucible/seeds/ts/seed-036 2.ts +0 -34
  169. package/dist/packages/crucible/seeds/ts/seed-037 2.ts +0 -33
  170. package/dist/packages/crucible/seeds/ts/seed-038 2.ts +0 -29
  171. package/dist/packages/crucible/seeds/ts/seed-039 2.ts +0 -35
  172. package/dist/packages/crucible/seeds/ts/seed-040 2.ts +0 -31
  173. package/dist/packages/crucible/seeds/ts/seed-041 2.ts +0 -29
  174. package/dist/packages/crucible/seeds/ts/seed-042 2.ts +0 -33
  175. package/dist/packages/crucible/seeds/ts/seed-043 2.ts +0 -32
  176. package/dist/packages/crucible/seeds/ts/seed-044 2.ts +0 -36
  177. package/dist/packages/crucible/seeds/ts/seed-045 2.ts +0 -39
  178. package/dist/packages/crucible/seeds/ts/seed-046 2.ts +0 -41
  179. package/dist/packages/crucible/seeds/ts/seed-047 2.ts +0 -33
  180. package/dist/packages/crucible/seeds/ts/seed-048 2.ts +0 -33
  181. package/dist/packages/crucible/seeds/ts/seed-049 2.ts +0 -34
  182. package/dist/packages/crucible/seeds/ts/seed-050 2.ts +0 -41
  183. package/dist/packages/crucible/seeds/ts/seed-051 2.ts +0 -34
  184. package/dist/packages/crucible/seeds/ts/seed-052 2.ts +0 -36
@@ -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
@@ -1,24 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: yaml_deserialization
3
- # severity: critical
4
- # language: ruby
5
- # expected: YAML.load with user-controlled input — allows arbitrary object instantiation
6
-
7
- class ConfigController < ApplicationController
8
- def import
9
- config_data = params[:config]
10
- config = YAML.load(config_data)
11
- apply_config(config)
12
- render json: { applied: true }
13
- end
14
-
15
- def load_template(template_string)
16
- YAML.load(template_string)
17
- end
18
-
19
- private
20
-
21
- def apply_config(cfg)
22
- cfg.each { |k, v| Rails.application.config.send("#{k}=", v) rescue nil }
23
- end
24
- end
@@ -1,20 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: yaml_deserialization
3
- # severity: critical
4
- # language: ruby
5
- # expected: YAML.load on file contents from user-supplied path — RCE via Psych gadget
6
-
7
- def load_config_file(config_name)
8
- path = "/etc/app/configs/#{config_name}.yml"
9
- content = File.read(path)
10
- YAML.load(content)
11
- end
12
-
13
- def parse_pipeline(pipeline_definition)
14
- YAML.load(pipeline_definition)
15
- end
16
-
17
- def deserialize_job(job_yaml)
18
- job = YAML.load(job_yaml)
19
- job.merge(loaded_at: Time.now)
20
- end
@@ -1,27 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: yaml_deserialization
3
- # severity: critical
4
- # language: ruby
5
- # expected: YAML.load used in API endpoint — remote code execution via crafted payload
6
-
7
- require 'sinatra'
8
- require 'yaml'
9
-
10
- post '/api/import' do
11
- content_type :json
12
- raw_body = request.body.read
13
- data = YAML.load(raw_body)
14
- process_import(data)
15
- { imported: data.keys.count }.to_json
16
- end
17
-
18
- post '/api/config/update' do
19
- yaml_config = params[:yaml]
20
- config = YAML.load(yaml_config)
21
- config.each { |k, v| CONFIG[k] = v }
22
- { updated: true }.to_json
23
- end
24
-
25
- def process_import(data)
26
- data.each { |k, v| puts "#{k}: #{v}" }
27
- end
@@ -1,25 +0,0 @@
1
- // [CRUCIBLE-SEED]
2
- // category: hardcoded_secret
3
- // severity: critical
4
- // language: rust
5
- // expected: Hardcoded AWS access key and secret in string literals
6
-
7
- use aws_sdk_s3::Client;
8
-
9
- const AWS_ACCESS_KEY_ID: &str = "AKIAIOSFODNN7EXAMPLE1";
10
- const AWS_SECRET_ACCESS_KEY: &str = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY";
11
- const AWS_REGION: &str = "us-east-1";
12
- const S3_BUCKET: &str = "my-production-bucket";
13
-
14
- pub async fn create_s3_client() -> Client {
15
- std::env::set_var("AWS_ACCESS_KEY_ID", AWS_ACCESS_KEY_ID);
16
- std::env::set_var("AWS_SECRET_ACCESS_KEY", AWS_SECRET_ACCESS_KEY);
17
- std::env::set_var("AWS_DEFAULT_REGION", AWS_REGION);
18
- let config = aws_config::load_from_env().await;
19
- Client::new(&config)
20
- }
21
-
22
- pub fn get_bucket() -> &'static str {
23
- println!("Using bucket: {} with key: {}", S3_BUCKET, AWS_ACCESS_KEY_ID);
24
- S3_BUCKET
25
- }
@@ -1,20 +0,0 @@
1
- // [CRUCIBLE-SEED]
2
- // category: hardcoded_secret
3
- // severity: critical
4
- // language: rust
5
- // expected: Hardcoded database password in connection string literal
6
-
7
- use sqlx::PgPool;
8
-
9
- const DB_URL: &str = "postgresql://appuser:Sup3rS3cr3tP@ssw0rd!@prod-db.example.com:5432/appdb";
10
- const REDIS_URL: &str = "redis://:myR3d1sS3cret@redis.prod.example.com:6379/0";
11
- const MONGO_URL: &str = "mongodb://admin:M0ng0P@ssw0rd@mongo.example.com:27017/proddb";
12
-
13
- pub async fn connect_db() -> PgPool {
14
- PgPool::connect(DB_URL).await.expect("Failed to connect to DB")
15
- }
16
-
17
- pub fn get_db_url() -> &'static str {
18
- eprintln!("Connecting to: {}", DB_URL);
19
- DB_URL
20
- }
@@ -1,23 +0,0 @@
1
- // [CRUCIBLE-SEED]
2
- // category: hardcoded_secret
3
- // severity: critical
4
- // language: rust
5
- // expected: Hardcoded JWT secret key used to sign tokens
6
-
7
- use hmac::{Hmac, Mac};
8
- use sha2::Sha256;
9
-
10
- const JWT_SECRET: &str = "mySuperSecretJWTSigningKey_2024_doNotCommit";
11
- const JWT_EXPIRY_HOURS: u64 = 24;
12
- const ADMIN_API_KEY: &str = "admin_sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
13
-
14
- pub fn sign_token(payload: &str) -> Vec<u8> {
15
- let mut mac = Hmac::<Sha256>::new_from_slice(JWT_SECRET.as_bytes())
16
- .expect("HMAC key error");
17
- mac.update(payload.as_bytes());
18
- mac.finalize().into_bytes().to_vec()
19
- }
20
-
21
- pub fn verify_admin(key: &str) -> bool {
22
- key == ADMIN_API_KEY
23
- }
@@ -1,21 +0,0 @@
1
- // [CRUCIBLE-SEED]
2
- // category: hardcoded_secret
3
- // severity: critical
4
- // language: rust
5
- // expected: Hardcoded Stripe and payment processor API keys
6
-
7
- const STRIPE_SECRET_KEY: &str = "sk_live_51HxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghij";
8
- const STRIPE_WEBHOOK_SECRET: &str = "whsec_abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJ";
9
- const PAYPAL_CLIENT_ID: &str = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVv";
10
- const PAYPAL_CLIENT_SECRET: &str = "EeLlKkJjIiHhGgFfEeDdCcBbAa0123456789xyzabcdef";
11
-
12
- pub fn get_stripe_headers() -> Vec<(&'static str, String)> {
13
- vec![
14
- ("Authorization", format!("Bearer {}", STRIPE_SECRET_KEY)),
15
- ("Stripe-Version", "2023-10-16".to_string()),
16
- ]
17
- }
18
-
19
- pub fn validate_webhook(sig: &str) -> bool {
20
- sig.starts_with(&STRIPE_WEBHOOK_SECRET[..10])
21
- }
@@ -1,21 +0,0 @@
1
- // [CRUCIBLE-SEED]
2
- // category: hardcoded_secret
3
- // severity: high
4
- // language: rust
5
- // expected: Hardcoded GitHub and GitLab personal access tokens
6
-
7
- const GITHUB_TOKEN: &str = "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
8
- const GITLAB_TOKEN: &str = "glpat-xxxxxxxxxxxxxxxxxxxxxxxxxxxx";
9
- const GITHUB_WEBHOOK_SECRET: &str = "github_webhook_secret_super_secret_value_here";
10
-
11
- pub fn clone_repo(repo_url: &str) -> String {
12
- format!(
13
- "https://{}@github.com/{}",
14
- GITHUB_TOKEN, repo_url
15
- )
16
- }
17
-
18
- pub async fn create_github_issue(owner: &str, repo: &str, title: &str) {
19
- let url = format!("https://api.github.com/repos/{}/{}/issues", owner, repo);
20
- println!("POST {} with token: {}", url, &GITHUB_TOKEN[..10]);
21
- }
@@ -1,24 +0,0 @@
1
- // [CRUCIBLE-SEED]
2
- // category: hardcoded_secret
3
- // severity: critical
4
- // language: rust
5
- // expected: Hardcoded encryption key and IV in const literals
6
-
7
- use aes::Aes256;
8
- use cbc::cipher::KeyIvInit;
9
-
10
- const ENCRYPTION_KEY: &[u8] = b"0123456789abcdef0123456789abcdef";
11
- const ENCRYPTION_IV: &[u8] = b"abcdef0123456789";
12
- const HMAC_KEY: &str = "super-secret-hmac-key-do-not-share";
13
-
14
- pub fn create_cipher() -> cbc::Encryptor<Aes256> {
15
- cbc::Encryptor::<Aes256>::new(
16
- ENCRYPTION_KEY.into(),
17
- ENCRYPTION_IV.into(),
18
- )
19
- }
20
-
21
- pub fn get_hmac_key() -> &'static [u8] {
22
- println!("HMAC key length: {}", HMAC_KEY.len());
23
- HMAC_KEY.as_bytes()
24
- }
@@ -1,20 +0,0 @@
1
- // [CRUCIBLE-SEED]
2
- // category: hardcoded_secret
3
- // severity: high
4
- // language: rust
5
- // expected: Hardcoded SMTP credentials and email service API key
6
-
7
- const SMTP_HOST: &str = "smtp.sendgrid.net";
8
- const SMTP_PORT: u16 = 587;
9
- const SMTP_USERNAME: &str = "apikey";
10
- const SMTP_PASSWORD: &str = "SG.xxxxxxxxxxxxxxxxxxxxxxxxxxxx.yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy";
11
- const FROM_EMAIL: &str = "noreply@example.com";
12
-
13
- pub fn build_smtp_transport() -> String {
14
- format!("{}://{}:{}@{}:{}", "smtp", SMTP_USERNAME, SMTP_PASSWORD, SMTP_HOST, SMTP_PORT)
15
- }
16
-
17
- pub fn get_smtp_config() -> (String, String) {
18
- println!("SMTP config loaded for: {}", SMTP_HOST);
19
- (SMTP_USERNAME.to_string(), SMTP_PASSWORD.to_string())
20
- }
@@ -1,19 +0,0 @@
1
- // [CRUCIBLE-SEED]
2
- // category: hardcoded_secret
3
- // severity: critical
4
- // language: rust
5
- // expected: Hardcoded Slack webhook URL and bot token
6
-
7
- const SLACK_BOT_TOKEN: &str = "xoxb-1234567890-1234567890123-abcdefghijklmnopqrstuvwx";
8
- const SLACK_SIGNING_SECRET: &str = "abcdef0123456789abcdef0123456789";
9
- const SLACK_WEBHOOK_URL: &str = "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX";
10
-
11
- pub async fn send_slack_message(channel: &str, text: &str) {
12
- println!("Sending to {} via token: {}...", channel, &SLACK_BOT_TOKEN[..15]);
13
- let client = reqwest::Client::new();
14
- let _ = client
15
- .post(SLACK_WEBHOOK_URL)
16
- .json(&serde_json::json!({"text": text}))
17
- .send()
18
- .await;
19
- }
@@ -1,28 +0,0 @@
1
- // [CRUCIBLE-SEED]
2
- // category: unsafe_block
3
- // severity: critical
4
- // language: rust
5
- // expected: Raw pointer dereference in unsafe block without bounds checking
6
-
7
- pub fn read_from_raw_ptr(ptr: *const u8, offset: usize) -> u8 {
8
- unsafe {
9
- *ptr.add(offset)
10
- }
11
- }
12
-
13
- pub fn write_to_raw_ptr(ptr: *mut u8, offset: usize, value: u8) {
14
- unsafe {
15
- *ptr.add(offset) = value;
16
- }
17
- }
18
-
19
- pub fn slice_from_raw(ptr: *const u8, len: usize) -> &'static [u8] {
20
- unsafe {
21
- std::slice::from_raw_parts(ptr, len)
22
- }
23
- }
24
-
25
- pub fn null_ptr_deref_risk() -> u8 {
26
- let ptr: *const u8 = 0x0 as *const u8;
27
- unsafe { *ptr }
28
- }
@@ -1,28 +0,0 @@
1
- // [CRUCIBLE-SEED]
2
- // category: unsafe_block
3
- // severity: critical
4
- // language: rust
5
- // expected: std::mem::transmute misuse — reinterpret arbitrary bytes as typed reference
6
-
7
- use std::mem;
8
-
9
- pub fn transmute_bytes_to_struct<T>(bytes: &[u8]) -> &T {
10
- unsafe {
11
- mem::transmute(bytes.as_ptr())
12
- }
13
- }
14
-
15
- pub fn reinterpret_as<S, D>(src: &S) -> &D {
16
- unsafe { mem::transmute(src) }
17
- }
18
-
19
- pub fn bytes_to_u64(bytes: &[u8]) -> u64 {
20
- unsafe {
21
- let arr: [u8; 8] = *(bytes.as_ptr() as *const [u8; 8]);
22
- mem::transmute(arr)
23
- }
24
- }
25
-
26
- pub fn lifetime_extend<'a, 'b, T>(r: &'a T) -> &'b T {
27
- unsafe { mem::transmute(r) }
28
- }
@@ -1,25 +0,0 @@
1
- // [CRUCIBLE-SEED]
2
- // category: unsafe_block
3
- // severity: critical
4
- // language: rust
5
- // expected: Unsafe foreign function interface call without input validation
6
-
7
- extern "C" {
8
- fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8;
9
- fn strlen(s: *const u8) -> usize;
10
- fn strcpy(dest: *mut u8, src: *const u8) -> *mut u8;
11
- }
12
-
13
- pub fn raw_memcpy(src: &[u8], dest: &mut Vec<u8>, n: usize) {
14
- unsafe {
15
- memcpy(dest.as_mut_ptr(), src.as_ptr(), n);
16
- }
17
- }
18
-
19
- pub fn get_c_strlen(s: *const u8) -> usize {
20
- unsafe { strlen(s) }
21
- }
22
-
23
- pub fn unsafe_string_copy(src: *const u8, dest: *mut u8) {
24
- unsafe { strcpy(dest, src); }
25
- }
@@ -1,31 +0,0 @@
1
- // [CRUCIBLE-SEED]
2
- // category: unsafe_block
3
- // severity: high
4
- // language: rust
5
- // expected: Vec::set_len called without initializing memory — UB
6
-
7
- pub fn create_uninitialized_vec(size: usize) -> Vec<u8> {
8
- let mut v = Vec::with_capacity(size);
9
- unsafe {
10
- v.set_len(size);
11
- }
12
- v
13
- }
14
-
15
- pub fn extend_vec_unsafely(v: &mut Vec<u8>, extra: usize) {
16
- let new_len = v.len() + extra;
17
- if v.capacity() < new_len {
18
- v.reserve(extra);
19
- }
20
- unsafe {
21
- v.set_len(new_len);
22
- }
23
- }
24
-
25
- pub fn read_uninitialized() -> u32 {
26
- let x: u32;
27
- unsafe {
28
- x = std::mem::MaybeUninit::uninit().assume_init();
29
- }
30
- x
31
- }
@@ -1,27 +0,0 @@
1
- // [CRUCIBLE-SEED]
2
- // category: unsafe_block
3
- // severity: critical
4
- // language: rust
5
- // expected: Mutable aliasing via raw pointers — violates Rust's aliasing rules
6
-
7
- pub fn create_aliased_refs(data: &mut Vec<i32>) -> (*mut i32, *mut i32) {
8
- let ptr1 = data.as_mut_ptr();
9
- let ptr2 = data.as_mut_ptr();
10
- (ptr1, ptr2)
11
- }
12
-
13
- pub fn alias_write(v: &mut Vec<u8>) {
14
- unsafe {
15
- let p1 = v.as_mut_ptr();
16
- let p2 = v.as_mut_ptr();
17
- *p1 = 1;
18
- *p2 = 2;
19
- }
20
- }
21
-
22
- pub fn double_free_risk(ptr: *mut u8, len: usize) {
23
- unsafe {
24
- let _v1 = Vec::from_raw_parts(ptr, len, len);
25
- let _v2 = Vec::from_raw_parts(ptr, len, len);
26
- }
27
- }
@@ -1,30 +0,0 @@
1
- // [CRUCIBLE-SEED]
2
- // category: unsafe_block
3
- // severity: high
4
- // language: rust
5
- // expected: Use of unsafe to bypass borrow checker — potential use-after-free
6
-
7
- use std::collections::HashMap;
8
-
9
- pub struct Cache {
10
- data: HashMap<String, String>,
11
- }
12
-
13
- impl Cache {
14
- pub fn get_or_insert(&mut self, key: &str, value: String) -> &str {
15
- if !self.data.contains_key(key) {
16
- self.data.insert(key.to_string(), value);
17
- }
18
- unsafe {
19
- let s: *const String = self.data.get(key).unwrap();
20
- &*s
21
- }
22
- }
23
-
24
- pub fn dangling_ref(&mut self) -> &str {
25
- let s = String::from("temporary");
26
- let ptr = s.as_str() as *const str;
27
- drop(s);
28
- unsafe { &*ptr }
29
- }
30
- }
@@ -1,33 +0,0 @@
1
- // [CRUCIBLE-SEED]
2
- // category: unsafe_block
3
- // severity: critical
4
- // language: rust
5
- // expected: Send/Sync implemented for non-thread-safe type via unsafe impl
6
-
7
- use std::cell::Cell;
8
- use std::rc::Rc;
9
-
10
- pub struct SharedCounter {
11
- value: Cell<i64>,
12
- data: Rc<Vec<u8>>,
13
- }
14
-
15
- unsafe impl Send for SharedCounter {}
16
- unsafe impl Sync for SharedCounter {}
17
-
18
- impl SharedCounter {
19
- pub fn new() -> Self {
20
- SharedCounter {
21
- value: Cell::new(0),
22
- data: Rc::new(vec![]),
23
- }
24
- }
25
-
26
- pub fn increment(&self) {
27
- self.value.set(self.value.get() + 1);
28
- }
29
-
30
- pub fn get(&self) -> i64 {
31
- self.value.get()
32
- }
33
- }