Class: Otto::Security::ValidationMiddleware

Inherits:
Object
  • Object
show all
Defined in:
lib/otto/security/validator.rb

Overview

ValidationMiddleware provides input validation and sanitization for web requests

Constant Summary collapse

INVALID_CHARACTERS =

Character validation patterns

/[\x00-\x1f\x7f-\xff]/n
NULL_BYTE =
/\0/
DANGEROUS_PATTERNS =
[
  /<script[^>]*>/i,           # Script tags
  /javascript:/i,             # JavaScript protocol
  /data:.*base64/i,           # Data URLs with base64
  /on\w+\s*=/i,               # Event handlers
  /expression\s*\(/i,         # CSS expressions
  /url\s*\(/i,                # CSS url() functions
  NULL_BYTE,                  # Null bytes
  INVALID_CHARACTERS,         # Control characters and extended ASCII
].freeze
SQL_INJECTION_PATTERNS =
[
  /('|(\\')|(;)|(\\)|(--)|(%27)|(%3B)|(%3D))/i,
  /(union|select|insert|update|delete|drop|create|alter|exec|execute)/i,
  /(or|and)\s+\w+\s*=\s*\w+/i,
  /\d+\s*(=|>|<|>=|<=|<>|!=)\s*\d+/i,
].freeze

Instance Method Summary collapse

Constructor Details

#initialize(app, config = nil) ⇒ ValidationMiddleware

Returns a new instance of ValidationMiddleware.



32
33
34
35
# File 'lib/otto/security/validator.rb', line 32

def initialize(app, config = nil)
  @app    = app
  @config = config || Otto::Security::Config.new
end

Instance Method Details

#call(env) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/otto/security/validator.rb', line 37

def call(env)
  return @app.call(env) unless @config.input_validation

  request = Rack::Request.new(env)

  begin
    # Validate request size
    validate_request_size(request)

    # Validate content type
    validate_content_type(request)

    # Validate and sanitize parameters
    begin
      validate_parameters(request) if request.params
    rescue Rack::QueryParser::QueryLimitError => ex
      # Handle Rack's built-in query parsing limits
      raise Otto::Security::ValidationError, "Parameter structure too complex: #{ex.message}"
    end

    # Validate headers
    validate_headers(request)

    @app.call(env)
  rescue Otto::Security::ValidationError => ex
    validation_error_response(ex.message)
  rescue Otto::Security::RequestTooLargeError => ex
    request_too_large_response(ex.message)
  end
end