breach-mitigation-rails 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 +21 -11
- data/lib/breach_mitigation/length_hiding.rb +2 -5
- data/lib/breach_mitigation/masking_secrets.rb +21 -9
- data/lib/breach_mitigation/version.rb +1 -1
- metadata +2 -2
data/README.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# breach-mitigation-rails
|
2
2
|
|
3
|
-
Makes Rails applications less susceptible to the BREACH /
|
4
|
-
attacks. See [breachattack.com](http://breachattack.com/) for
|
3
|
+
Makes Rails 3 and 4 applications less susceptible to the BREACH /
|
4
|
+
CRIME attacks. See [breachattack.com](http://breachattack.com/) for
|
5
|
+
details.
|
5
6
|
|
6
7
|
## How it works
|
7
8
|
|
@@ -21,6 +22,12 @@ prevent plaintext recovery, but it can slow the attack and it's
|
|
21
22
|
relatively inexpensive to implement. Unlike the CSRF token masking,
|
22
23
|
length hiding protects the entire page body from recovery.
|
23
24
|
|
25
|
+
In addition to these mitigations, you should check out Twitter's
|
26
|
+
[secure_headers](https://github.com/twitter/secureheaders) gem.
|
27
|
+
Setting the X-Frame-Options header can make it harder for an attacker
|
28
|
+
to carry out this attack (by making it impossible to put your site in
|
29
|
+
an iframe).
|
30
|
+
|
24
31
|
## Warning!
|
25
32
|
|
26
33
|
BREACH and CRIME are **complicated and wide-ranging attacks**, and this
|
@@ -39,20 +46,23 @@ And then execute:
|
|
39
46
|
|
40
47
|
$ bundle
|
41
48
|
|
42
|
-
|
49
|
+
For most Rails apps, that should be enough, but read on for the gory
|
50
|
+
details...
|
43
51
|
|
44
52
|
## Gotchas
|
45
53
|
|
46
|
-
length
|
47
|
-
|
48
|
-
|
49
|
-
|
54
|
+
* The length-hiding middleware adds random text (in the form of an HTML
|
55
|
+
comment) to every page you serve. This can break HTTP caching / ETags for
|
56
|
+
public pages since they are no longer identical on each request.
|
57
|
+
* The length-hiding middleware adds up to 2k of text to each page you
|
58
|
+
serve, which means more bandwidth consumed and potentially slower
|
59
|
+
performance.
|
60
|
+
* If you have overridden the verified_request? method in your
|
61
|
+
application (likely in ApplicationController) you may need to update
|
62
|
+
it to be compatible with the secret masking code. See
|
63
|
+
`lib/breach_mitigation/railtie.rb` for an example.
|
50
64
|
|
51
65
|
## Contributing
|
52
66
|
|
53
67
|
Pull requests are welcome, either to enhance the existing mitigation
|
54
68
|
strategies or to add new ways to mitigate against the attack.
|
55
|
-
|
56
|
-
## License
|
57
|
-
|
58
|
-
MIT - see LICENSE.txt
|
@@ -38,11 +38,8 @@ module BreachMitigation
|
|
38
38
|
# The length of the padding should be strongly random, but the
|
39
39
|
# data itself doesn't need to be strongly random; it just needs
|
40
40
|
# to be resistant to compression
|
41
|
-
length = SecureRandom.random_number(
|
42
|
-
|
43
|
-
# TODO make this faster
|
44
|
-
junk = ''
|
45
|
-
length.times { junk << ALPHABET.sample }
|
41
|
+
length = SecureRandom.random_number(MAX_LENGTH)
|
42
|
+
junk = ALPHABET.sample(length).join
|
46
43
|
|
47
44
|
"\n<!-- This is a random-length HTML comment: #{junk} -->"
|
48
45
|
end
|
@@ -21,15 +21,27 @@ module BreachMitigation
|
|
21
21
|
|
22
22
|
masked_token = Base64.strict_decode64(encoded_masked_token)
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
#
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
24
|
+
# See if it's actually a masked token or not. In order to
|
25
|
+
# deploy this code, we should be able to handle any unmasked
|
26
|
+
# tokens that we've issued without error.
|
27
|
+
|
28
|
+
if masked_token.length == AUTHENTICITY_TOKEN_LENGTH
|
29
|
+
# This is actually an unmasked token
|
30
|
+
Rails.logger.warn "WARNING: the client is using an unmasked authenticity token. This is expected if you have just upgraded to masked tokens, but if these messages continue long after the upgrade, then something fishy is going on."
|
31
|
+
masked_token == real_csrf_token(session)
|
32
|
+
|
33
|
+
elsif masked_token.length == AUTHENTICITY_TOKEN_LENGTH * 2
|
34
|
+
# Split the token into the one-time pad and the encrypted
|
35
|
+
# value and decrypt it
|
36
|
+
one_time_pad = masked_token[0...AUTHENTICITY_TOKEN_LENGTH]
|
37
|
+
encrypted_csrf_token = masked_token[AUTHENTICITY_TOKEN_LENGTH..-1]
|
38
|
+
csrf_token = xor_byte_strings(one_time_pad, encrypted_csrf_token)
|
39
|
+
|
40
|
+
csrf_token == real_csrf_token(session)
|
41
|
+
|
42
|
+
else
|
43
|
+
false # Token is malformed
|
44
|
+
end
|
33
45
|
end
|
34
46
|
|
35
47
|
private
|
metadata
CHANGED
@@ -2,14 +2,14 @@
|
|
2
2
|
name: breach-mitigation-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Bradley Buda
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-08-
|
12
|
+
date: 2013-08-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
version_requirements: !ruby/object:Gem::Requirement
|