Class: Scryer::Rules::ActiveStorageMissingContentTypeValidationRule
- Inherits:
-
Scryer::Rule
- Object
- Scryer::Rule
- Scryer::Rules::ActiveStorageMissingContentTypeValidationRule
- Defined in:
- lib/scryer/rules/active_storage_missing_content_type_validation_rule.rb
Overview
Flags has_one_attached/has_many_attached :name with no
validates :name, content_type: [...] anywhere in the same class —
without a content-type allowlist, a user can upload anything (an SVG
or HTML file that executes script when served, an executable, ...),
not just the file type the feature was built for.
Constant Summary collapse
- ATTACHMENT_METHODS =
%w[has_one_attached has_many_attached].freeze
Instance Attribute Summary
Attributes inherited from Scryer::Rule
Instance Method Summary collapse
Methods inherited from Scryer::Rule
Constructor Details
This class inherits a constructor from Scryer::Rule
Instance Method Details
#scan ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/scryer/rules/active_storage_missing_content_type_validation_rule.rb', line 16 def scan findings = [] Ast.each_node(sexp) do |node| next unless Ast.tagged?(node, :class) body = node[3] validated_names = each_content_type_validated_names(body) (body).each do |call_node, name| next if validated_names.include?(name) line = Ast.line_of(call_node) findings << finding( line: line, message: "`:#{name}` is attached via Active Storage with no `content_type:` " \ "validation anywhere in this class — any file type can be uploaded, " \ "including ones that execute in a browser if ever served back (e.g. SVG, " \ "HTML) or aren't safe to store at all.", suggested_fix: "Add an explicit allowlist: `validates :#{name}, content_type: " \ "['image/png', 'image/jpeg']` (whatever types this feature actually " \ "needs) so anything else is rejected at upload time." ) end end findings end |