class Pakyow::Security::CSRF::VerifySameOrigin

Protects against Cross-Site Forgery Requests (CSRF). www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet

Allows requests if the origin or referer matches the request uri, or is whitelisted through the config.origin.whitelist config option. The request is not allowed if values for both origin and referer are missing.

Public Class Methods

new(*) click to toggle source
Calls superclass method Pakyow::Security::Base::new
# File lib/pakyow/security/csrf/verify_same_origin.rb, line 19
def initialize(*)
  super

  @whitelisted_origins = @config[:origin_whitelist].to_a.map { |origin|
    parse_uri(origin)
  }.compact
end

Public Instance Methods

allowed?(connection) click to toggle source
# File lib/pakyow/security/csrf/verify_same_origin.rb, line 27
def allowed?(connection)
  origin_uris(connection).yield_self { |origins|
    !origins.empty? && origins.all? { |origin|
      whitelisted_origin?(origin) || matching_origin?(origin, connection)
    }
  }
end

Private Instance Methods

matching_origin?(origin, connection) click to toggle source
# File lib/pakyow/security/csrf/verify_same_origin.rb, line 67
def matching_origin?(origin, connection)
  uris_match?(origin, parse_uri("#{connection.scheme}://#{connection.authority}"))
end
origin_uris(connection) click to toggle source
# File lib/pakyow/security/csrf/verify_same_origin.rb, line 37
def origin_uris(connection)
  origins = []

  if connection.request_header?("origin")
    origins.concat(connection.request_header("origin"))
  end

  if connection.request_header?("referer")
    origins << connection.request_header("referer")
  end

  origins.map! { |value| parse_uri(value) }
end
parse_uri(value) click to toggle source
# File lib/pakyow/security/csrf/verify_same_origin.rb, line 51
def parse_uri(value)
  URI.parse(value.to_s)
rescue URI::InvalidURIError
  nil
end
uris_match?(uri1, uri2) click to toggle source
# File lib/pakyow/security/csrf/verify_same_origin.rb, line 57
def uris_match?(uri1, uri2)
  uri1.scheme == uri2.scheme && uri1.host == uri2.host && uri1.port == uri2.port
end
whitelisted_origin?(origin) click to toggle source
# File lib/pakyow/security/csrf/verify_same_origin.rb, line 61
def whitelisted_origin?(origin)
  @whitelisted_origins.any? { |whitelisted|
    uris_match?(whitelisted, origin)
  }
end