rack-protection 2.0.0.rc1 → 2.0.0.rc2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rack-protection might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/License +4 -1
- data/lib/rack/protection/content_security_policy.rb +80 -0
- data/lib/rack/protection/cookie_tossing.rb +75 -0
- data/lib/rack/protection/json_csrf.rb +10 -4
- data/lib/rack/protection/strict_transport.rb +39 -0
- data/lib/rack/protection/version.rb +1 -1
- data/rack-protection.gemspec +5 -67
- metadata +9 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ba263455e21ef3a57c282270022ca1a02c4e9f0
|
4
|
+
data.tar.gz: 7e297009a1ff3f7e42a9a11a69ad1a6c58de5ba5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 58c7dc2603726a22a19a910f15858bb7cf52496e43ce9cc3b306ff01bba37771b08a05c9ed1a874f9e4294d6f6ebc73c2c0671f60fc31f9203bfc8a24b83a3bd
|
7
|
+
data.tar.gz: c2a99e1e29b37012ab43a4dba44381645fc7018901f509494c49a0b06ec70ffd9268f2e34a8bd0015104221e5db85bd4ea25b22ff2d7e5ae810d8c4148425bb2
|
data/License
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2011-2017 Konstantin Haase
|
4
|
+
Copyright (c) 2015-2017 Zachary Scott
|
2
5
|
|
3
6
|
Permission is hereby granted, free of charge, to any person obtaining
|
4
7
|
a copy of this software and associated documentation files (the
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'rack/protection'
|
3
|
+
|
4
|
+
module Rack
|
5
|
+
module Protection
|
6
|
+
##
|
7
|
+
# Prevented attack:: XSS and others
|
8
|
+
# Supported browsers:: Firefox 23+, Safari 7+, Chrome 25+, Opera 15+
|
9
|
+
#
|
10
|
+
# Description:: Content Security Policy, a mechanism web applications
|
11
|
+
# can use to mitigate a broad class of content injection
|
12
|
+
# vulnerabilities, such as cross-site scripting (XSS).
|
13
|
+
# Content Security Policy is a declarative policy that lets
|
14
|
+
# the authors (or server administrators) of a web application
|
15
|
+
# inform the client about the sources from which the
|
16
|
+
# application expects to load resources.
|
17
|
+
#
|
18
|
+
# More info:: W3C CSP Level 1 : https://www.w3.org/TR/CSP1/ (deprecated)
|
19
|
+
# W3C CSP Level 2 : https://www.w3.org/TR/CSP2/ (current)
|
20
|
+
# W3C CSP Level 3 : https://www.w3.org/TR/CSP3/ (draft)
|
21
|
+
# https://developer.mozilla.org/en-US/docs/Web/Security/CSP
|
22
|
+
# http://caniuse.com/#search=ContentSecurityPolicy
|
23
|
+
# http://content-security-policy.com/
|
24
|
+
# https://securityheaders.io
|
25
|
+
# https://scotthelme.co.uk/csp-cheat-sheet/
|
26
|
+
# http://www.html5rocks.com/en/tutorials/security/content-security-policy/
|
27
|
+
#
|
28
|
+
# Sets the 'Content-Security-Policy[-Report-Only]' header.
|
29
|
+
#
|
30
|
+
# Options: ContentSecurityPolicy configuration is a complex topic with
|
31
|
+
# several levels of support that has evolved over time.
|
32
|
+
# See the W3C documentation and the links in the more info
|
33
|
+
# section for CSP usage examples and best practices. The
|
34
|
+
# CSP3 directives in the 'NO_ARG_DIRECTIVES' constant need to be
|
35
|
+
# presented in the options hash with a boolean 'true' in order
|
36
|
+
# to be used in a policy.
|
37
|
+
#
|
38
|
+
class ContentSecurityPolicy < Base
|
39
|
+
default_options default_src: :none, script_src: "'self'",
|
40
|
+
img_src: "'self'", style_src: "'self'",
|
41
|
+
connect_src: "'self'", report_only: false
|
42
|
+
|
43
|
+
DIRECTIVES = %i(base_uri child_src connect_src default_src
|
44
|
+
font_src form_action frame_ancestors frame_src
|
45
|
+
img_src manifest_src media_src object_src
|
46
|
+
plugin_types referrer reflected_xss report_to
|
47
|
+
report_uri require_sri_for sandbox script_src
|
48
|
+
style_src worker_src).freeze
|
49
|
+
|
50
|
+
NO_ARG_DIRECTIVES = %i(block_all_mixed_content disown_opener
|
51
|
+
upgrade_insecure_requests).freeze
|
52
|
+
|
53
|
+
def csp_policy
|
54
|
+
directives = []
|
55
|
+
|
56
|
+
DIRECTIVES.each do |d|
|
57
|
+
if options.key?(d)
|
58
|
+
directives << "#{d.to_s.sub(/_/, '-')} #{options[d]}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Set these key values to boolean 'true' to include in policy
|
63
|
+
NO_ARG_DIRECTIVES.each do |d|
|
64
|
+
if options.key?(d) && options[d].is_a?(TrueClass)
|
65
|
+
directives << d.to_s.sub(/_/, '-')
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
directives.compact.sort.join('; ')
|
70
|
+
end
|
71
|
+
|
72
|
+
def call(env)
|
73
|
+
status, headers, body = @app.call(env)
|
74
|
+
header = options[:report_only] ? 'Content-Security-Policy-Report-Only' : 'Content-Security-Policy'
|
75
|
+
headers[header] ||= csp_policy if html? headers
|
76
|
+
[status, headers, body]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'rack/protection'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
module Rack
|
5
|
+
module Protection
|
6
|
+
##
|
7
|
+
# Prevented attack:: Cookie Tossing
|
8
|
+
# Supported browsers:: all
|
9
|
+
# More infos:: https://github.com/blog/1466-yummy-cookies-across-domains
|
10
|
+
#
|
11
|
+
# Does not accept HTTP requests if the HTTP_COOKIE header contains more than one
|
12
|
+
# session cookie. This does not protect against a cookie overflow attack.
|
13
|
+
#
|
14
|
+
# Options:
|
15
|
+
#
|
16
|
+
# session_key:: The name of the session cookie (default: 'rack.session')
|
17
|
+
class CookieTossing < Base
|
18
|
+
default_reaction :deny
|
19
|
+
|
20
|
+
def call(env)
|
21
|
+
status, headers, body = super
|
22
|
+
response = Rack::Response.new(body, status, headers)
|
23
|
+
request = Rack::Request.new(env)
|
24
|
+
remove_bad_cookies(request, response)
|
25
|
+
response.finish
|
26
|
+
end
|
27
|
+
|
28
|
+
def accepts?(env)
|
29
|
+
cookie_header = env['HTTP_COOKIE']
|
30
|
+
cookies = Rack::Utils.parse_query(cookie_header, ';,') { |s| s }
|
31
|
+
cookies.each do |k, v|
|
32
|
+
if k == session_key && Array(v).size > 1
|
33
|
+
bad_cookies << k
|
34
|
+
elsif k != session_key && Rack::Utils.unescape(k) == session_key
|
35
|
+
bad_cookies << k
|
36
|
+
end
|
37
|
+
end
|
38
|
+
bad_cookies.empty?
|
39
|
+
end
|
40
|
+
|
41
|
+
def remove_bad_cookies(request, response)
|
42
|
+
return if bad_cookies.empty?
|
43
|
+
paths = cookie_paths(request.path)
|
44
|
+
bad_cookies.each do |name|
|
45
|
+
paths.each { |path| response.set_cookie name, empty_cookie(request.host, path) }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def redirect(env)
|
50
|
+
request = Request.new(env)
|
51
|
+
warn env, "attack prevented by #{self.class}"
|
52
|
+
[302, {'Content-Type' => 'text/html', 'Location' => request.path}, []]
|
53
|
+
end
|
54
|
+
|
55
|
+
def bad_cookies
|
56
|
+
@bad_cookies ||= []
|
57
|
+
end
|
58
|
+
|
59
|
+
def cookie_paths(path)
|
60
|
+
path = '/' if path.to_s.empty?
|
61
|
+
paths = []
|
62
|
+
Pathname.new(path).descend { |p| paths << p.to_s }
|
63
|
+
paths
|
64
|
+
end
|
65
|
+
|
66
|
+
def empty_cookie(host, path)
|
67
|
+
{:value => '', :domain => host, :path => path, :expires => Time.at(0)}
|
68
|
+
end
|
69
|
+
|
70
|
+
def session_key
|
71
|
+
@session_key ||= options[:session_key]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -5,15 +5,20 @@ module Rack
|
|
5
5
|
##
|
6
6
|
# Prevented attack:: CSRF
|
7
7
|
# Supported browsers:: all
|
8
|
-
# More infos:: http://flask.pocoo.org/docs/security/#json-security
|
8
|
+
# More infos:: http://flask.pocoo.org/docs/0.10/security/#json-security
|
9
|
+
# http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx
|
9
10
|
#
|
10
|
-
# JSON GET APIs are vulnerable to being embedded as JavaScript
|
11
|
+
# JSON GET APIs are vulnerable to being embedded as JavaScript when the
|
11
12
|
# Array prototype has been patched to track data. Checks the referrer
|
12
13
|
# even on GET requests if the content type is JSON.
|
13
14
|
#
|
14
|
-
#
|
15
|
-
# documentation for more.
|
15
|
+
# If request includes Origin HTTP header, defers to HttpOrigin to determine
|
16
|
+
# if the request is safe. Please refer to the documentation for more info.
|
17
|
+
#
|
18
|
+
# The `:allow_if` option can be set to a proc to use custom allow/deny logic.
|
16
19
|
class JsonCsrf < Base
|
20
|
+
default_options :allow_if => nil
|
21
|
+
|
17
22
|
alias react deny
|
18
23
|
|
19
24
|
def call(env)
|
@@ -31,6 +36,7 @@ module Rack
|
|
31
36
|
|
32
37
|
def has_vector?(request, headers)
|
33
38
|
return false if request.xhr?
|
39
|
+
return false if options[:allow_if] && options[:allow_if].call(request.env)
|
34
40
|
return false unless headers['Content-Type'].to_s.split(';', 2).first =~ /^\s*application\/json\s*$/
|
35
41
|
origin(request.env).nil? and referrer(request.env) != request.host
|
36
42
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rack/protection'
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
module Protection
|
5
|
+
##
|
6
|
+
# Prevented attack:: Protects against against protocol downgrade attacks and cookie hijacking.
|
7
|
+
# Supported browsers:: all
|
8
|
+
# More infos:: https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
|
9
|
+
#
|
10
|
+
# browser will prevent any communications from being sent over HTTP
|
11
|
+
# to the specified domain and will instead send all communications over HTTPS.
|
12
|
+
# It also prevents HTTPS click through prompts on browsers.
|
13
|
+
#
|
14
|
+
# Options:
|
15
|
+
#
|
16
|
+
# max_age:: How long future requests to the domain should go over HTTPS; specified in seconds
|
17
|
+
# include_subdomains:: If all present and future subdomains will be HTTPS
|
18
|
+
# preload:: Allow this domain to be included in browsers HSTS preload list. See https://hstspreload.appspot.com/
|
19
|
+
|
20
|
+
class StrictTransport < Base
|
21
|
+
default_options :max_age => 31_536_000, :include_subdomains => false, :preload => false
|
22
|
+
|
23
|
+
def strict_transport
|
24
|
+
@strict_transport ||= begin
|
25
|
+
strict_transport = 'max-age=' + options[:max_age].to_s
|
26
|
+
strict_transport += '; includeSubDomains' if options[:include_subdomains]
|
27
|
+
strict_transport += '; preload' if options[:preload]
|
28
|
+
strict_transport.to_str
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def call(env)
|
33
|
+
status, headers, body = @app.call(env)
|
34
|
+
headers['Strict-Transport-Security'] ||= strict_transport
|
35
|
+
[status, headers, body]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/rack-protection.gemspec
CHANGED
@@ -6,79 +6,17 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.name = "rack-protection"
|
7
7
|
s.version = Rack::Protection::VERSION
|
8
8
|
s.description = "Protect against typical web attacks, works with all Rack apps, including Rails."
|
9
|
-
s.homepage = "http://github.com/sinatra/rack-protection"
|
9
|
+
s.homepage = "http://github.com/sinatra/sinatra/tree/master/rack-protection"
|
10
10
|
s.summary = s.description
|
11
11
|
s.license = 'MIT'
|
12
|
-
|
13
|
-
|
14
|
-
s.
|
15
|
-
"Konstantin Haase",
|
16
|
-
"Maurizio De Santis",
|
17
|
-
"Alex Rodionov",
|
18
|
-
"Jason Staten",
|
19
|
-
"Patrick Ellis",
|
20
|
-
"ITO Nobuaki",
|
21
|
-
"Jeff Welling",
|
22
|
-
"Matteo Centenaro",
|
23
|
-
"Akzhan Abdulin",
|
24
|
-
"Alan deLevie",
|
25
|
-
"Bj\u{f8}rge N\u{e6}ss",
|
26
|
-
"Chris Heald",
|
27
|
-
"Chris Mytton",
|
28
|
-
"Corey Ward",
|
29
|
-
"Dario Cravero",
|
30
|
-
"David Kellum",
|
31
|
-
"Egor Homakov",
|
32
|
-
"Florian Gilcher",
|
33
|
-
"Fojas",
|
34
|
-
"Igor Bochkariov",
|
35
|
-
"Josef Stribny",
|
36
|
-
"Katrina Owen",
|
37
|
-
"Mael Clerambault",
|
38
|
-
"Martin Mauch",
|
39
|
-
"Renne Nissinen",
|
40
|
-
"SAKAI, Kazuaki",
|
41
|
-
"Stanislav Savulchik",
|
42
|
-
"Steve Agalloco",
|
43
|
-
"TOBY",
|
44
|
-
"Thais Camilo and Konstantin Haase",
|
45
|
-
"Vipul A M",
|
46
|
-
"Zachary Scott",
|
47
|
-
"ashley williams",
|
48
|
-
"brookemckim"
|
49
|
-
]
|
50
|
-
|
51
|
-
# generated from git shortlog -sne
|
52
|
-
s.email = [
|
53
|
-
"mail@zzak.io",
|
54
|
-
"konstantin.haase@gmail.com"
|
55
|
-
]
|
56
|
-
|
57
|
-
# generated from git ls-files
|
58
|
-
s.files = [
|
12
|
+
s.authors = ["https://github.com/sinatra/sinatra/graphs/contributors"]
|
13
|
+
s.email = "sinatrarb@googlegroups.com"
|
14
|
+
s.files = Dir["lib/**/*.rb"] + [
|
59
15
|
"License",
|
60
16
|
"README.md",
|
61
17
|
"Rakefile",
|
62
18
|
"Gemfile",
|
63
|
-
"rack-protection.gemspec"
|
64
|
-
"lib/rack",
|
65
|
-
"lib/rack/protection",
|
66
|
-
"lib/rack/protection/escaped_params.rb",
|
67
|
-
"lib/rack/protection/remote_referrer.rb",
|
68
|
-
"lib/rack/protection/ip_spoofing.rb",
|
69
|
-
"lib/rack/protection/base.rb",
|
70
|
-
"lib/rack/protection/session_hijacking.rb",
|
71
|
-
"lib/rack/protection/authenticity_token.rb",
|
72
|
-
"lib/rack/protection/version.rb",
|
73
|
-
"lib/rack/protection/path_traversal.rb",
|
74
|
-
"lib/rack/protection/form_token.rb",
|
75
|
-
"lib/rack/protection/json_csrf.rb",
|
76
|
-
"lib/rack/protection/http_origin.rb",
|
77
|
-
"lib/rack/protection/frame_options.rb",
|
78
|
-
"lib/rack/protection/xss_header.rb",
|
79
|
-
"lib/rack/protection/remote_token.rb",
|
80
|
-
"lib/rack/protection.rb",
|
81
|
-
"lib/rack-protection.rb"
|
19
|
+
"rack-protection.gemspec"
|
82
20
|
]
|
83
21
|
|
84
22
|
# dependencies
|
metadata
CHANGED
@@ -1,47 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-protection
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.rc2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
8
|
-
- Maurizio De Santis
|
9
|
-
- Alex Rodionov
|
10
|
-
- Jason Staten
|
11
|
-
- Patrick Ellis
|
12
|
-
- ITO Nobuaki
|
13
|
-
- Jeff Welling
|
14
|
-
- Matteo Centenaro
|
15
|
-
- Akzhan Abdulin
|
16
|
-
- Alan deLevie
|
17
|
-
- Bjørge Næss
|
18
|
-
- Chris Heald
|
19
|
-
- Chris Mytton
|
20
|
-
- Corey Ward
|
21
|
-
- Dario Cravero
|
22
|
-
- David Kellum
|
23
|
-
- Egor Homakov
|
24
|
-
- Florian Gilcher
|
25
|
-
- Fojas
|
26
|
-
- Igor Bochkariov
|
27
|
-
- Josef Stribny
|
28
|
-
- Katrina Owen
|
29
|
-
- Mael Clerambault
|
30
|
-
- Martin Mauch
|
31
|
-
- Renne Nissinen
|
32
|
-
- SAKAI, Kazuaki
|
33
|
-
- Stanislav Savulchik
|
34
|
-
- Steve Agalloco
|
35
|
-
- TOBY
|
36
|
-
- Thais Camilo and Konstantin Haase
|
37
|
-
- Vipul A M
|
38
|
-
- Zachary Scott
|
39
|
-
- ashley williams
|
40
|
-
- brookemckim
|
7
|
+
- https://github.com/sinatra/sinatra/graphs/contributors
|
41
8
|
autorequire:
|
42
9
|
bindir: bin
|
43
10
|
cert_chain: []
|
44
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-19 00:00:00.000000000 Z
|
45
12
|
dependencies:
|
46
13
|
- !ruby/object:Gem::Dependency
|
47
14
|
name: rack
|
@@ -87,9 +54,7 @@ dependencies:
|
|
87
54
|
version: 3.0.0
|
88
55
|
description: Protect against typical web attacks, works with all Rack apps, including
|
89
56
|
Rails.
|
90
|
-
email:
|
91
|
-
- mail@zzak.io
|
92
|
-
- konstantin.haase@gmail.com
|
57
|
+
email: sinatrarb@googlegroups.com
|
93
58
|
executables: []
|
94
59
|
extensions: []
|
95
60
|
extra_rdoc_files: []
|
@@ -102,6 +67,8 @@ files:
|
|
102
67
|
- lib/rack/protection.rb
|
103
68
|
- lib/rack/protection/authenticity_token.rb
|
104
69
|
- lib/rack/protection/base.rb
|
70
|
+
- lib/rack/protection/content_security_policy.rb
|
71
|
+
- lib/rack/protection/cookie_tossing.rb
|
105
72
|
- lib/rack/protection/escaped_params.rb
|
106
73
|
- lib/rack/protection/form_token.rb
|
107
74
|
- lib/rack/protection/frame_options.rb
|
@@ -112,10 +79,11 @@ files:
|
|
112
79
|
- lib/rack/protection/remote_referrer.rb
|
113
80
|
- lib/rack/protection/remote_token.rb
|
114
81
|
- lib/rack/protection/session_hijacking.rb
|
82
|
+
- lib/rack/protection/strict_transport.rb
|
115
83
|
- lib/rack/protection/version.rb
|
116
84
|
- lib/rack/protection/xss_header.rb
|
117
85
|
- rack-protection.gemspec
|
118
|
-
homepage: http://github.com/sinatra/rack-protection
|
86
|
+
homepage: http://github.com/sinatra/sinatra/tree/master/rack-protection
|
119
87
|
licenses:
|
120
88
|
- MIT
|
121
89
|
metadata: {}
|
@@ -135,7 +103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
135
103
|
version: 1.3.1
|
136
104
|
requirements: []
|
137
105
|
rubyforge_project:
|
138
|
-
rubygems_version: 2.
|
106
|
+
rubygems_version: 2.6.8
|
139
107
|
signing_key:
|
140
108
|
specification_version: 4
|
141
109
|
summary: Protect against typical web attacks, works with all Rack apps, including
|