rack-padlock 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +41 -16
- data/lib/rack/padlock/padlock.js +42 -0
- data/lib/rack/padlock/phantomjs.rb +24 -0
- data/lib/rack/padlock/selenium.rb +18 -0
- data/lib/rack/padlock/server.rb +104 -0
- data/lib/rack/padlock/string_util.rb +16 -0
- data/lib/rack/padlock/version.rb +1 -1
- data/lib/rack/padlock.rb +50 -9
- data/lib/tasks/rack-padlock.rake +30 -8
- data/test/rack_padlock_test.rb +1 -1
- data/test/string_util_test.rb +18 -0
- data/test/test_helper.rb +3 -3
- metadata +32 -14
data/README.md
CHANGED
@@ -1,36 +1,61 @@
|
|
1
|
-
rack-padlock
|
2
|
-
=======
|
1
|
+
# rack-padlock
|
3
2
|
|
4
|
-
A toolkit for
|
3
|
+
A toolkit for rack applications that ensures _ALL_ content on a page is secure. The browser padlock is pretty important for commercial web applications. Modern sites rely on so many third party services: analytics, video players, social media widgets. With all these moving parts it's easy to end up with a broken padlock. Rack-Padlock will increase the visibility of padlock problems to your development team, and it's dead easy to use.
|
5
4
|
|
6
|
-
|
5
|
+
## Prerequisites
|
7
6
|
|
8
|
-
|
9
|
-
2. The application must have a browser based integration test suite. I recommend capybara.
|
10
|
-
3. Your integration tests must use HTTPS
|
7
|
+
All you need to have a rack based application! (Rails, Sinatra, Camping, etc...)
|
11
8
|
|
12
9
|
## Setup
|
13
10
|
|
14
11
|
Add rack-padlock gem to your test group
|
15
12
|
|
16
|
-
```
|
13
|
+
```ruby
|
17
14
|
group :test do
|
18
15
|
gem 'rack-padlock'
|
19
16
|
end
|
20
17
|
```
|
21
18
|
|
22
|
-
Add rack-padlock
|
19
|
+
Add rack-padlock rake tasks to your app
|
23
20
|
|
24
|
-
```
|
25
|
-
|
26
|
-
|
21
|
+
```ruby
|
22
|
+
require 'rack/padlock'
|
23
|
+
load 'tasks/rack-padlock.rake'
|
24
|
+
```
|
25
|
+
|
26
|
+
Specify what url's you want to test somewhere in your Rakefile
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
Rack::Padlock.padlock_uris = ["/secure", "/insecure"]
|
30
|
+
```
|
31
|
+
|
32
|
+
If your application isn't a Rails app, then you need to add an environment rake task to your Rakefile like this
|
33
|
+
```ruby
|
34
|
+
desc "setup application environment"
|
35
|
+
task :environment do
|
36
|
+
require 'your rack application'
|
37
|
+
Rack::Padlock.application = YourRackApplication
|
38
|
+
Rack::Padlock.padlock_uris = ["/secure", "/insecure"]
|
27
39
|
end
|
28
40
|
```
|
41
|
+
## Running Tests
|
42
|
+
|
43
|
+
Once you've set things up simply run
|
44
|
+
|
45
|
+
```bash
|
46
|
+
rake padlock
|
47
|
+
```
|
48
|
+
|
49
|
+
This will run the padlock tests. If any of your integration tests mix secure and insecure content, the padlock test will fail.
|
50
|
+
|
51
|
+
## Example rack application
|
52
|
+
|
53
|
+
Have a look at a simple sinatra application that demonstrates rack-padlock at https://github.com/joshuacronemeyer/rack-padlock-example-app
|
29
54
|
|
30
|
-
|
55
|
+
## How it works
|
31
56
|
|
32
|
-
|
33
|
-
=======
|
57
|
+
Rack-Padlock starts your Rack app up with an SSL enabled webrick server. It puts a custom middleware in front of your application that implements a CSP policy. That policy requires the browser to notify us of any non SSL activity. The custom middleware intercepts these notifications and logs them. At the end of the run the rack-padlock test will either succeed or fail based on the presence of any policy violations.
|
34
58
|
|
59
|
+
## References
|
35
60
|
|
36
|
-
|
61
|
+
1. http://www.w3.org/TR/CSP/
|
@@ -0,0 +1,42 @@
|
|
1
|
+
var startTime = Date.now();
|
2
|
+
var timeOut = 10000;
|
3
|
+
console.log('Padlock: JS client starting!');
|
4
|
+
var page = require('webpage').create(),
|
5
|
+
system = require('system'),
|
6
|
+
t, address;
|
7
|
+
|
8
|
+
if (system.args.length === 1) {
|
9
|
+
console.log('ERROR: You need to pass phantomjs some URLs to visit!');
|
10
|
+
phantom.exit();
|
11
|
+
}
|
12
|
+
|
13
|
+
var pagesToVisit = system.args.slice(1);
|
14
|
+
var numberOfPagesToVisit = pagesToVisit.length;
|
15
|
+
var numberOfPagesVisited = 0;
|
16
|
+
|
17
|
+
var visitPages = function(pages){
|
18
|
+
if(pages.length == 0){return;}
|
19
|
+
var thePage = pages.pop();
|
20
|
+
console.log("Opening " + thePage);
|
21
|
+
page.open(thePage, function (status) {
|
22
|
+
if (status !== 'success') {
|
23
|
+
console.log('FAIL to load the address: ' + thePage);
|
24
|
+
} else {
|
25
|
+
console.log('visited: ' + thePage );
|
26
|
+
}
|
27
|
+
numberOfPagesVisited++;
|
28
|
+
visitPages(pages);
|
29
|
+
});
|
30
|
+
};
|
31
|
+
|
32
|
+
var exitWhenDone = function(){
|
33
|
+
var executionTime = Date.now() - startTime;
|
34
|
+
if (numberOfPagesVisited == numberOfPagesToVisit || executionTime > timeOut) {
|
35
|
+
phantom.exit();
|
36
|
+
} else{
|
37
|
+
setTimeout(exitWhenDone,500);
|
38
|
+
}
|
39
|
+
};
|
40
|
+
|
41
|
+
visitPages(pagesToVisit);
|
42
|
+
exitWhenDone();
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Rack
|
2
|
+
class Padlock
|
3
|
+
class Phantomjs
|
4
|
+
KILL_TIMEOUT = 20 # seconds
|
5
|
+
attr_reader :pid, :binary
|
6
|
+
|
7
|
+
def initialize(addresses, binary=nil)
|
8
|
+
@binary = binary || 'phantomjs'
|
9
|
+
@addresses = addresses
|
10
|
+
@pid = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def command
|
14
|
+
js_path = ::File.expand_path('../padlock.js', __FILE__)
|
15
|
+
"#{@binary} --ignore-ssl-errors=yes #{js_path} #{@addresses.join(' ')}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def start
|
19
|
+
puts "Starting up phantomjs\n"
|
20
|
+
Timeout.timeout(KILL_TIMEOUT) { system(command) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "selenium-webdriver"
|
2
|
+
module Rack
|
3
|
+
class Padlock
|
4
|
+
class Selenium
|
5
|
+
def initialize(addresses)
|
6
|
+
@addresses = addresses
|
7
|
+
end
|
8
|
+
|
9
|
+
def start
|
10
|
+
puts "Starting up selenium webdriver\n"
|
11
|
+
@driver = ::Selenium::WebDriver.for :firefox
|
12
|
+
@driver.manage.timeouts.implicit_wait = 30
|
13
|
+
@addresses.each{|address| @driver.get(address)}
|
14
|
+
@driver.quit
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
require 'rack'
|
3
|
+
module Rack
|
4
|
+
class Padlock
|
5
|
+
|
6
|
+
class Server
|
7
|
+
PORT = 9988
|
8
|
+
attr_reader :app
|
9
|
+
|
10
|
+
def initialize(app)
|
11
|
+
@app = app
|
12
|
+
@middleware = Rack::Padlock.new(@app)
|
13
|
+
@server_thread = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def boot
|
17
|
+
@server_thread = Thread.new do
|
18
|
+
webserver = Rack::Padlock::Webrick.run(@middleware, PORT)
|
19
|
+
end
|
20
|
+
|
21
|
+
Timeout.timeout(60) { @server_thread.join(0.1) until responsive? }
|
22
|
+
rescue Timeout::Error
|
23
|
+
raise "Rack application timed out during boot"
|
24
|
+
else
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def responsive?
|
29
|
+
return false if @server_thread && @server_thread.join(0)
|
30
|
+
|
31
|
+
require "net/https"
|
32
|
+
require 'uri'
|
33
|
+
uri = URI.parse("#{base_uri}/padlock_middleware/poke")
|
34
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
35
|
+
http.use_ssl = true
|
36
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
37
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
38
|
+
response = http.request(request)
|
39
|
+
|
40
|
+
return response.is_a?(Net::HTTPSuccess) || response.is_a?(Net::HTTPRedirection)
|
41
|
+
rescue Errno::ECONNREFUSED, Errno::EBADF
|
42
|
+
return false
|
43
|
+
end
|
44
|
+
|
45
|
+
def base_uri
|
46
|
+
"https://localhost:#{PORT}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Webrick
|
51
|
+
def self.run(app, port)
|
52
|
+
puts "Starting up SSL webrick\n"
|
53
|
+
require 'rack/handler/webrick'
|
54
|
+
require 'webrick/https'
|
55
|
+
require 'openssl'
|
56
|
+
webrick_options = {
|
57
|
+
:Port => (port),
|
58
|
+
:AccessLog => [],
|
59
|
+
:Logger => WEBrick::Log::new(nil, 0),
|
60
|
+
:SSLEnable => true,
|
61
|
+
:SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE,
|
62
|
+
:SSLPrivateKey => OpenSSL::PKey::RSA.new(KEY),
|
63
|
+
:SSLCertificate => OpenSSL::X509::Certificate.new(CRT),
|
64
|
+
:SSLCertName => [["CN", WEBrick::Utils::getservername]]
|
65
|
+
}
|
66
|
+
webrick_options.merge({:Logger => WEBrick::Log::new($stdout, WEBrick::Log::DEBUG)}) if Rack::Padlock.debug?
|
67
|
+
Rack::Handler::WEBrick.run(app, webrick_options)
|
68
|
+
end
|
69
|
+
|
70
|
+
KEY=<<EOF
|
71
|
+
-----BEGIN RSA PRIVATE KEY-----
|
72
|
+
MIICXQIBAAKBgQDayqjBWENExonuc2RPbegDb7O2r5vw+iVl0MBF9sQAmuu3vuoN
|
73
|
+
UCeNgF2CFvMpFQFsQ8hm+qnnDQFU66+lEXfR5bfRd8whOIS7ysD5nDzr8wKhqX9s
|
74
|
+
964zhVInvfEinmggyxz6BdkWTXsMblS1Z0JjsomFrhQkIkw82r5t7Hc4iQIDAQAB
|
75
|
+
AoGBALAo4i0iQq86Z84s7IQjit5RbtJVnGovDjNnG5h5ciDGm6nLNqnXcrE0vJVE
|
76
|
+
oy3dstKX1OBNTMUyrHLSfQ6b/OrvKw6dg7ndyFK+XO4zLFB5B0sCE5Bp05Ycjlj1
|
77
|
+
8IAuu9k2e3ozDjf1tNpD80OTa8S3y4+4yxeN5QYbAd2eh+7tAkEA8WbVz8Cjaf9w
|
78
|
+
y53k5L9Rv7GP54CI2f7LAsla6TUqQsgjvKTOqalGm4O/7N62nj/JAyWWQl72d4GQ
|
79
|
+
xL2ZZyhCxwJBAOgFy5b0yNP/QywzEtpwP3JBrOIdYqV/oXxE0rCzJkWC94xm2J1p
|
80
|
+
0198fNjgueAy4YnuMjR6nTGjBVCdU82fWi8CQB93t0ForCSiHrL8Nx02b1Kcs9SK
|
81
|
+
pcw88XvAgbBKtOKVskrh9Oqa3VBiYT9gXM/OIsbdPHQUau5zHkr3KCsRTXsCQQCT
|
82
|
+
bStBjeQVoDpkWUd/eJc32DcrrZRCqGhJd8mP8SU+QctdcPPugZGHOKhzfcddh7b7
|
83
|
+
V1ibM9Wx9m2oHW9kVf6NAkA1q90FzKwrpFmyzwKCe7wWhPd3GlN4qXvwdEW4kk1b
|
84
|
+
KTjyjrIXRt5UObL+ywhdkES8h2+rUFw5hXfyzIpafjyZ
|
85
|
+
-----END RSA PRIVATE KEY-----
|
86
|
+
EOF
|
87
|
+
CRT=<<EOF
|
88
|
+
-----BEGIN CERTIFICATE-----
|
89
|
+
MIIB8TCCAVoCCQCD/Pvld7jzMDANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGEwJV
|
90
|
+
UzELMAkGA1UECAwCQ0ExCzAJBgNVBAcMAlNGMRMwEQYDVQQKDApDb2xsZWdlc2V0
|
91
|
+
MCAXDTEzMDIwNzE5MzM1M1oYDzMwMTIwNjEwMTkzMzUzWjA8MQswCQYDVQQGEwJV
|
92
|
+
UzELMAkGA1UECAwCQ0ExCzAJBgNVBAcMAlNGMRMwEQYDVQQKDApDb2xsZWdlc2V0
|
93
|
+
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDayqjBWENExonuc2RPbegDb7O2
|
94
|
+
r5vw+iVl0MBF9sQAmuu3vuoNUCeNgF2CFvMpFQFsQ8hm+qnnDQFU66+lEXfR5bfR
|
95
|
+
d8whOIS7ysD5nDzr8wKhqX9s964zhVInvfEinmggyxz6BdkWTXsMblS1Z0JjsomF
|
96
|
+
rhQkIkw82r5t7Hc4iQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACbe+qTXarpzRtRx
|
97
|
+
+v3AQhN/nMMKHvDwIhfiDlJva0DcRvWi9FDyyQVO8NA5YgcfMPI0iN1opEfOSrfG
|
98
|
+
mtyWupIL5lpn4EzW9r/0jOhjwA2NDN/BVYiFe4ovsPvJCOWti1bs7xMz7bSaFiNr
|
99
|
+
fi5nkNjLgLQmZHUj9/soMSfRGbP1
|
100
|
+
-----END CERTIFICATE-----
|
101
|
+
EOF
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Rack
|
2
|
+
class Padlock
|
3
|
+
class StringUtil
|
4
|
+
def elide(string, max)
|
5
|
+
length = string.length
|
6
|
+
return string unless length > max
|
7
|
+
return string if max <= 0
|
8
|
+
amount_to_preserve_on_the_left = (max/2.0).ceil
|
9
|
+
amount_to_preserve_on_the_right = max - amount_to_preserve_on_the_left
|
10
|
+
left = string[0..(amount_to_preserve_on_the_left-1)]
|
11
|
+
right = string[-amount_to_preserve_on_the_right..-1]
|
12
|
+
"#{left}...#{right}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/rack/padlock/version.rb
CHANGED
data/lib/rack/padlock.rb
CHANGED
@@ -1,40 +1,81 @@
|
|
1
1
|
module Rack
|
2
2
|
class Padlock
|
3
|
+
@@application = nil
|
4
|
+
@@padlock_uris = nil
|
5
|
+
@@debug = false
|
6
|
+
@@logfile = "tmp/padlock.log"
|
7
|
+
|
3
8
|
POST_BODY = 'rack.input'.freeze
|
4
9
|
|
5
|
-
def initialize(app
|
6
|
-
default_options = {
|
7
|
-
:log_file => "tmp/padlock.log"
|
8
|
-
}
|
10
|
+
def initialize(app)
|
9
11
|
@app = app
|
10
|
-
@options = default_options.merge(options)
|
11
12
|
end
|
12
13
|
|
13
14
|
def call(env)
|
15
|
+
return poke_response if poke?(env)
|
14
16
|
return capture_violation(env) if csp_policy_violation?(env)
|
15
17
|
status, headers, body = @app.call(env)
|
16
18
|
headers.merge!(csp_headers(env))
|
17
19
|
[status, headers, body]
|
18
20
|
end
|
19
|
-
|
21
|
+
|
22
|
+
def self.application=(app)
|
23
|
+
@@application = app
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.application
|
27
|
+
@@application
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.padlock_uris=(uri_list)
|
31
|
+
@@padlock_uris = uri_list
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.padlock_uris(base_uri)
|
35
|
+
@@padlock_uris.map {|path| "#{base_uri}#{path}" } if @@padlock_uris
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.debug=(flag)
|
39
|
+
@@debug = flag
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.debug?
|
43
|
+
@@debug
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.logfile=(log)
|
47
|
+
@@logfile = log
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.logfile
|
51
|
+
@@logfile
|
52
|
+
end
|
20
53
|
private
|
21
54
|
|
22
55
|
def capture_violation(env)
|
23
56
|
violation = env[POST_BODY].read
|
24
|
-
PadlockFile.write(
|
25
|
-
[200, {}, []]
|
57
|
+
PadlockFile.write(Padlock.logfile, violation)
|
58
|
+
[200, {"Content-Length"=>"0"}, []]
|
26
59
|
end
|
27
60
|
|
61
|
+
def poke_response
|
62
|
+
[200, {}, []]
|
63
|
+
end
|
64
|
+
|
28
65
|
def csp_policy_violation?(env)
|
29
66
|
env['PATH_INFO'] =~ /padlock_middleware\/report$/
|
30
67
|
end
|
31
68
|
|
69
|
+
def poke?(env)
|
70
|
+
env['PATH_INFO'] =~ /padlock_middleware\/poke$/
|
71
|
+
end
|
72
|
+
|
32
73
|
def csp_headers(env)
|
33
74
|
host = env["HTTP_HOST"]
|
34
75
|
report_uri = "#{host}/padlock_middleware/report"
|
35
76
|
csp_header_names = %w(Content-Security-Policy-Report-Only X-Content-Security-Policy-Report-Only X-WebKit-CSP-Report-Only)
|
36
77
|
csp_headers = {}
|
37
|
-
csp_header_names.each{|name| csp_headers[name] = "default-src https: 'unsafe-inline' 'unsafe-eval'; report-uri
|
78
|
+
csp_header_names.each{|name| csp_headers[name] = "default-src https: 'unsafe-inline' 'unsafe-eval'; report-uri https://#{report_uri}"}
|
38
79
|
csp_headers
|
39
80
|
end
|
40
81
|
|
data/lib/tasks/rack-padlock.rake
CHANGED
@@ -1,15 +1,37 @@
|
|
1
1
|
require 'rainbow'
|
2
|
-
|
2
|
+
require 'rack/padlock'
|
3
|
+
require 'rack/padlock/server'
|
4
|
+
require 'rack/padlock/selenium'
|
5
|
+
require 'rack/padlock/string_util'
|
3
6
|
|
4
7
|
desc "Test for padlock"
|
5
|
-
task :padlock_test => [:
|
6
|
-
|
7
|
-
|
8
|
+
task :padlock_test => [:environment] do
|
9
|
+
rails_app = Rails.application if defined?(Rails)
|
10
|
+
app = Rack::Padlock.application || rails_app
|
11
|
+
puts "Padlock Test: checking #{app} for insecure content.".foreground(:green)
|
12
|
+
server = Rack::Padlock::Server.new(app)
|
13
|
+
server.boot
|
14
|
+
uris = Rack::Padlock.padlock_uris(server.base_uri) || [server.base_uri]
|
15
|
+
client = Rack::Padlock::Selenium.new(uris)
|
16
|
+
client.start
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Test for padlock"
|
20
|
+
task :padlock => [:padlock_clean, :padlock_test, :padlock_check]
|
21
|
+
|
22
|
+
desc "Clean padlock logs"
|
23
|
+
task :padlock_check do
|
24
|
+
contents = File.open(Rack::Padlock.logfile, 'r') { |f| f.readlines }
|
25
|
+
if File.size? Rack::Padlock.logfile
|
8
26
|
puts "Padlock test failure: Insecure content is being loaded on the page.".foreground(:red)
|
9
27
|
contents.each do |line|
|
10
|
-
|
11
|
-
|
12
|
-
|
28
|
+
what_match = line.match(/blocked-uri":"([^"]+)/)
|
29
|
+
why_match = line.match(/violated-directive":"([^"]+)/)
|
30
|
+
next unless what_match && why_match
|
31
|
+
blocked_uri = what_match[1].foreground(:yellow)
|
32
|
+
violated_directive = why_match[1].foreground(:magenta)
|
33
|
+
util = Rack::Padlock::StringUtil.new
|
34
|
+
puts "Request for #{util.elide(blocked_uri, 200)} has violated directive #{util.elide(violated_directive, 200)}"
|
13
35
|
end
|
14
36
|
exit 1
|
15
37
|
else
|
@@ -19,5 +41,5 @@ end
|
|
19
41
|
|
20
42
|
desc "Clean padlock logs"
|
21
43
|
task :padlock_clean do
|
22
|
-
File.truncate('tmp/padlock.log', 0) if File.exist?(
|
44
|
+
File.truncate('tmp/padlock.log', 0) if File.exist?(Rack::Padlock.logfile)
|
23
45
|
end
|
data/test/rack_padlock_test.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class StringUtilTest < MiniTest::Unit::TestCase
|
4
|
+
|
5
|
+
describe "elide" do
|
6
|
+
before do
|
7
|
+
@util = Rack::Padlock::StringUtil.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should add ellipsis and shorten words" do
|
11
|
+
@util.elide("hootinanny", 4).must_equal "ho...ny"
|
12
|
+
@util.elide("hootinanny", 10).must_equal "hootinanny"
|
13
|
+
@util.elide("hootinanny", 11).must_equal "hootinanny"
|
14
|
+
@util.elide("hootinanny", 9).must_equal "hooti...anny"
|
15
|
+
@util.elide("hootinanny", 0).must_equal "hootinanny"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -2,13 +2,13 @@ require 'minitest/autorun'
|
|
2
2
|
require 'rack/mock'
|
3
3
|
require 'rack/test'
|
4
4
|
require 'rack/padlock'
|
5
|
-
|
5
|
+
require 'rack/padlock/string_util'
|
6
6
|
class MiniTest::Unit::TestCase
|
7
7
|
include Rack::Test::Methods
|
8
8
|
|
9
9
|
def app; Rack::Lint.new(@app); end
|
10
10
|
|
11
|
-
def mock_app
|
11
|
+
def mock_app
|
12
12
|
main_app = lambda { |env|
|
13
13
|
request = Rack::Request.new(env)
|
14
14
|
headers = {'Content-Type' => "text/html"}
|
@@ -16,7 +16,7 @@ class MiniTest::Unit::TestCase
|
|
16
16
|
}
|
17
17
|
|
18
18
|
builder = Rack::Builder.new
|
19
|
-
builder.use Rack::Padlock
|
19
|
+
builder.use Rack::Padlock
|
20
20
|
builder.run main_app
|
21
21
|
@app = builder.to_app
|
22
22
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-padlock
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-02-
|
12
|
+
date: 2013-02-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
16
|
-
requirement: &
|
16
|
+
requirement: &70095896651180 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70095896651180
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rainbow
|
27
|
-
requirement: &
|
27
|
+
requirement: &70095900907220 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,21 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70095900907220
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: selenium-webdriver
|
38
|
+
requirement: &70095900905920 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70095900905920
|
36
47
|
- !ruby/object:Gem::Dependency
|
37
48
|
name: bundler
|
38
|
-
requirement: &
|
49
|
+
requirement: &70095900904820 !ruby/object:Gem::Requirement
|
39
50
|
none: false
|
40
51
|
requirements:
|
41
52
|
- - ! '>='
|
@@ -43,10 +54,10 @@ dependencies:
|
|
43
54
|
version: '0'
|
44
55
|
type: :development
|
45
56
|
prerelease: false
|
46
|
-
version_requirements: *
|
57
|
+
version_requirements: *70095900904820
|
47
58
|
- !ruby/object:Gem::Dependency
|
48
59
|
name: rake
|
49
|
-
requirement: &
|
60
|
+
requirement: &70095900903940 !ruby/object:Gem::Requirement
|
50
61
|
none: false
|
51
62
|
requirements:
|
52
63
|
- - ! '>='
|
@@ -54,10 +65,10 @@ dependencies:
|
|
54
65
|
version: '0'
|
55
66
|
type: :development
|
56
67
|
prerelease: false
|
57
|
-
version_requirements: *
|
68
|
+
version_requirements: *70095900903940
|
58
69
|
- !ruby/object:Gem::Dependency
|
59
70
|
name: minitest
|
60
|
-
requirement: &
|
71
|
+
requirement: &70095900903060 !ruby/object:Gem::Requirement
|
61
72
|
none: false
|
62
73
|
requirements:
|
63
74
|
- - ! '>='
|
@@ -65,10 +76,10 @@ dependencies:
|
|
65
76
|
version: '0'
|
66
77
|
type: :development
|
67
78
|
prerelease: false
|
68
|
-
version_requirements: *
|
79
|
+
version_requirements: *70095900903060
|
69
80
|
- !ruby/object:Gem::Dependency
|
70
81
|
name: rack-test
|
71
|
-
requirement: &
|
82
|
+
requirement: &70095900902260 !ruby/object:Gem::Requirement
|
72
83
|
none: false
|
73
84
|
requirements:
|
74
85
|
- - ! '>='
|
@@ -76,7 +87,7 @@ dependencies:
|
|
76
87
|
version: '0'
|
77
88
|
type: :development
|
78
89
|
prerelease: false
|
79
|
-
version_requirements: *
|
90
|
+
version_requirements: *70095900902260
|
80
91
|
description: A Gem for testing web applications don't generate mixed secure/insecure
|
81
92
|
traffic. Keep that browser padlock locked!
|
82
93
|
email: joshuacronemeyer@gmail.com
|
@@ -84,12 +95,18 @@ executables: []
|
|
84
95
|
extensions: []
|
85
96
|
extra_rdoc_files: []
|
86
97
|
files:
|
98
|
+
- lib/rack/padlock/padlock.js
|
99
|
+
- lib/rack/padlock/phantomjs.rb
|
100
|
+
- lib/rack/padlock/selenium.rb
|
101
|
+
- lib/rack/padlock/server.rb
|
102
|
+
- lib/rack/padlock/string_util.rb
|
87
103
|
- lib/rack/padlock/version.rb
|
88
104
|
- lib/rack/padlock.rb
|
89
105
|
- lib/rack-padlock.rb
|
90
106
|
- lib/tasks/rack-padlock.rake
|
91
107
|
- README.md
|
92
108
|
- test/rack_padlock_test.rb
|
109
|
+
- test/string_util_test.rb
|
93
110
|
- test/test_helper.rb
|
94
111
|
homepage: https://github.com/joshuacronemeyer/rack-padlock
|
95
112
|
licenses: []
|
@@ -117,4 +134,5 @@ specification_version: 3
|
|
117
134
|
summary: A Toolkit for writing tests that ensure all traffic on a page is secure.
|
118
135
|
test_files:
|
119
136
|
- test/rack_padlock_test.rb
|
137
|
+
- test/string_util_test.rb
|
120
138
|
- test/test_helper.rb
|