Class: Otto::Security::Middleware::ValidationMiddleware

Inherits:
Object
  • Object
show all
Includes:
ValidationHelpers
Defined in:
lib/otto/security/middleware/validation_middleware.rb

Overview

ValidationMiddleware provides input validation and sanitization for web requests Uses Loofah for HTML/XSS sanitization and Facets for filename sanitization

Constant Summary collapse

INVALID_CHARACTERS =

Character validation patterns

/[\x00-\x1f\x7f-\xff]/n
NULL_BYTE =
/\0/
SQL_INJECTION_PATTERNS =

HTML/XSS sanitization is handled by Loofah library for better security coverage

[
  /('|(\\')|(;)|(\\)|(--)|(%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

Methods included from ValidationHelpers

#sanitize_filename, #validate_input

Constructor Details

#initialize(app, config = nil) ⇒ ValidationMiddleware

Returns a new instance of ValidationMiddleware.



27
28
29
30
# File 'lib/otto/security/middleware/validation_middleware.rb', line 27

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

Instance Method Details

#call(env) ⇒ Object



32
33
34
35
36
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
67
68
69
70
71
72
73
74
# File 'lib/otto/security/middleware/validation_middleware.rb', line 32

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

  request = Otto::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 => e
      # Handle Rack's built-in query parsing limits
      raise Otto::Security::ValidationError, "Parameter structure too complex: #{e.message}"
    end

    # Validate headers
    validate_headers(request)

    @app.call(env)
  rescue Otto::Security::ValidationError => e
    # Log validation failure
    Otto.structured_log(:warn, "Input validation failed",
      Otto::LoggingHelpers.request_context(env).merge(
        error: e.message
      )
    )
    validation_error_response(e.message)
  rescue Otto::Security::RequestTooLargeError => e
    # Log request size violation
    Otto.structured_log(:warn, "Request too large",
      Otto::LoggingHelpers.request_context(env).merge(
        error: e.message,
        content_length: request.env['CONTENT_LENGTH']
      )
    )
    request_too_large_response(e.message)
  end
end