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,20 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: sql_injection
3
- # severity: critical
4
- # language: ruby
5
- # expected: SQL injection via string interpolation in ActiveRecord where()
6
-
7
- class UserController < ApplicationController
8
- def search
9
- username = params[:username]
10
- @users = User.where("username = '#{username}'")
11
- render json: @users
12
- end
13
-
14
- def filter
15
- role = params[:role]
16
- since = params[:since]
17
- @records = User.where("role = '#{role}' AND created_at >= '#{since}'")
18
- render json: @records
19
- end
20
- end
@@ -1,24 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: sql_injection
3
- # severity: critical
4
- # language: ruby
5
- # expected: ActiveRecord find_by_sql with string interpolation
6
-
7
- class ReportController < ApplicationController
8
- def show
9
- user_id = params[:user_id]
10
- type = params[:type]
11
- @data = Report.find_by_sql(
12
- "SELECT * FROM reports WHERE user_id = #{user_id} AND type = '#{type}'"
13
- )
14
- render json: @data
15
- end
16
-
17
- def custom_query
18
- condition = params[:condition]
19
- @results = ActiveRecord::Base.connection.execute(
20
- "SELECT * FROM events WHERE #{condition}"
21
- )
22
- render json: @results.to_a
23
- end
24
- end
@@ -1,21 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: sql_injection
3
- # severity: critical
4
- # language: ruby
5
- # expected: ORDER BY clause built from user-supplied column name without whitelist
6
-
7
- class ProductsController < ApplicationController
8
- def index
9
- sort_col = params[:sort_by]
10
- sort_dir = params[:direction]
11
- @products = Product.where("active = true").order("#{sort_col} #{sort_dir}")
12
- render json: @products
13
- end
14
-
15
- def search
16
- term = params[:q]
17
- category = params[:category]
18
- @items = Product.where("name LIKE '%#{term}%' AND category = '#{category}'")
19
- render json: @items
20
- end
21
- end
@@ -1,22 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: sql_injection
3
- # severity: critical
4
- # language: ruby
5
- # expected: Raw SQL executed via connection.execute with user input
6
-
7
- def run_analytics(dimension, filter_expr)
8
- sql = "SELECT #{dimension}, COUNT(*) FROM events WHERE #{filter_expr} GROUP BY #{dimension}"
9
- ActiveRecord::Base.connection.execute(sql)
10
- end
11
-
12
- def delete_records(table, condition)
13
- ActiveRecord::Base.connection.execute(
14
- "DELETE FROM #{table} WHERE #{condition}"
15
- )
16
- end
17
-
18
- def update_field(table, field, value, id)
19
- ActiveRecord::Base.connection.execute(
20
- "UPDATE #{table} SET #{field} = '#{value}' WHERE id = #{id}"
21
- )
22
- end
@@ -1,21 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: sql_injection
3
- # severity: critical
4
- # language: ruby
5
- # expected: Sequel dataset filter with string interpolation
6
-
7
- require 'sequel'
8
-
9
- DB = Sequel.connect('sqlite://db/production.sqlite3')
10
-
11
- def find_user(username, password)
12
- DB[:users].where("username = '#{username}' AND password = '#{password}'").first
13
- end
14
-
15
- def get_orders(status, user_id)
16
- DB[:orders].where("status = '#{status}' AND user_id = #{user_id}").all
17
- end
18
-
19
- def search_items(keyword)
20
- DB[:items].where("name LIKE '%#{keyword}%' OR description LIKE '%#{keyword}%'").all
21
- end
@@ -1,16 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: sql_injection
3
- # severity: high
4
- # language: ruby
5
- # expected: ActiveRecord group/having clause with unparameterized user input
6
-
7
- class AnalyticsController < ApplicationController
8
- def aggregate
9
- group_by = params[:group_by]
10
- having = params[:having]
11
- @data = Order.group(group_by)
12
- .having("COUNT(*) #{having}")
13
- .select("#{group_by}, COUNT(*) as total")
14
- render json: @data
15
- end
16
- end
@@ -1,18 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: sql_injection
3
- # severity: critical
4
- # language: ruby
5
- # expected: pg gem exec_params replaced with exec — user string in raw SQL
6
-
7
- require 'pg'
8
-
9
- conn = PG.connect(dbname: 'production')
10
-
11
- def login(conn, username, password)
12
- result = conn.exec("SELECT * FROM users WHERE username = '#{username}' AND password_hash = '#{password}'")
13
- result.first
14
- end
15
-
16
- def get_profile(conn, user_id)
17
- conn.exec("SELECT * FROM profiles WHERE user_id = #{user_id}").first
18
- end
@@ -1,17 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: xss
3
- # severity: high
4
- # language: ruby
5
- # expected: render html: with user content — unescaped XSS
6
-
7
- class CommentsController < ApplicationController
8
- def show
9
- @comment = Comment.find(params[:id])
10
- render html: @comment.body.html_safe
11
- end
12
-
13
- def preview
14
- content = params[:content]
15
- render html: content.html_safe
16
- end
17
- end
@@ -1,25 +0,0 @@
1
- # [CRUCIBLE-SEED]
2
- # category: xss
3
- # severity: high
4
- # language: ruby
5
- # expected: raw() helper used with user-controlled content in ERB template
6
-
7
- # In a Rails view (equivalent Ruby)
8
- class ArticlesController < ApplicationController
9
- helper_method :render_article
10
-
11
- def show
12
- @article = Article.find(params[:id])
13
- @title = params[:title] || @article.title
14
- @body = @article.body
15
- end
16
- end
17
-
18
- # Equivalent ERB logic (Ruby):
19
- def render_article_html(title, body, author_bio)
20
- "<h1>#{raw(title)}</h1><div>#{raw(body)}</div><footer>#{raw(author_bio)}</footer>"
21
- end
22
-
23
- def raw(str)
24
- str.to_s
25
- end
@@ -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