rack-protection 2.0.0.rc1 → 2.0.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
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
|