Class: Scryer::Rules::ActiveStorageMissingContentTypeValidationRule

Inherits:
Scryer::Rule
  • Object
show all
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

#file, #sexp, #source

Instance Method Summary collapse

Methods inherited from Scryer::Rule

inherited, #initialize

Constructor Details

This class inherits a constructor from Scryer::Rule

Instance Method Details

#scanObject



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)

    each_attachment(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