devise_sqreener 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c8483e2152547f35ade4e0b7b592e87851a15804
4
- data.tar.gz: 42ed8c93d34c07d2009831782306a5a4fa45a512
3
+ metadata.gz: fd8c549f4b58bc36ce9472751ee058c68c380770
4
+ data.tar.gz: e10015a600e3ccf712f6f6da8e8e4ad6fbe76f4a
5
5
  SHA512:
6
- metadata.gz: 39e855247d68eff1ec23d0ddb00cd00821baaa702986aa79050a954234c3db48adb0646903ca1df155c71534f9d58c84a67578524a36f7263a4dc99f5db07f40
7
- data.tar.gz: d5453a6319134d598a4bf50894aa20c32225f321ffad5d36b7da67ef47b42bf8a6b31eeb65c6f1e873c5216d6446d7d63c10458f87f4350919ed0b4b6005695b
6
+ metadata.gz: f6979035b284d536e6aa2f92625dbd64d7095f6517f73d754b34ea7d443cace06130fa73345275a1f4ba149ceb35c730b627ceea609b29aeac445932145010d8
7
+ data.tar.gz: cc2cf0503cc100fca46049a3ac7837dfcc16e6e8e104402dd93278c47d9c58b2352a8e71caebee9252a22efda9909b7599d5edc8bece946af7c1b34ba49efd3e
data/CODE_OF_CONDUCT.md CHANGED
@@ -1,4 +1,4 @@
1
- # Sqreen open source code of conduct
1
+ # Sqreen Open Source Code of Conduct
2
2
 
3
3
 
4
4
  ## Introduction
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2017 Sqreen
3
+ Copyright (c) 2017 Société Sqreen
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,10 +1,19 @@
1
1
  # devise\_sqreener
2
2
 
3
- Add Sqreen API integration to Devise. Whenever a new user sign up or sign in its IP address and email addressed will be sqreened with security metadata. This plugin also provides the ability to block the said sign in/up using simple rules. Blocking people with disposable email, using TOR or geographically has never been easier.
3
+ Not everyone who signs up for your app wants to use your service. Wouldn’t it be nice if there was an easy way to automatically block abusers? This project adds the ability to block or flag potentially malicious users of your Rails app to the Devise user authentication module.
4
+
5
+ Whenever a new user signs up or signs in, their IP address and email address are compared against Sqreen's extensive database of bad apples; you get back a chunk of actionable metadata on those addresses that can be used to set user policies. You can, for example:
6
+
7
+ * Block users with a history of malicious abuse from signing up
8
+ * Prevent users from signing in over TOR.
9
+ * Discover whether someone is logging in from two distinct geographic locations at the same time.
10
+ * Flag users signing up with disposable email addresses.
11
+
12
+ Such fun!
4
13
 
5
14
  ## Installation
6
15
 
7
- Add this line to your application Gemfile:
16
+ Of course, the best way to install is with RubyGems! Add this line to your application's Gemfile:
8
17
 
9
18
  ```ruby
10
19
  gem 'devise_sqreener'
@@ -15,106 +24,128 @@ and then execute
15
24
  $ bundle
16
25
  ```
17
26
 
18
- ## Automatic Installation
27
+ to download the latest version and install it.
19
28
 
20
- First if you want IP addresses to be sqreened (as it were) ensure your model use Devise `:trackable`.
29
+ ## Install devise_sqreener
21
30
 
22
- Add devise\_sqreener to any or you Devise models using the following generator:
31
+ Let's assume your user model is called `User`.
32
+
33
+ First we should note that `devise_sqreened` relies on the Devise `:trackable` strategy for tracking IP addresses. By default, `:trackable` is enabled, but if your use model doesn't include `:trackable`, and you want to enable the IP address filtering features, then you'll need to re-enable `:trackable`. Doing that is a bit beyond the scope of this tutorial, unfortunately. Anyway, the default Devise User model looks something like this, for reference purposes.
34
+
35
+ ```ruby
36
+ class User < ActiveRecord::Base
37
+ # Include default devise modules. Others available are:
38
+ # :confirmable, :lockable, :timeoutable and :omniauthable
39
+ devise :database_authenticatable, :registerable,
40
+ :recoverable, :rememberable, :trackable, :validatable
41
+ end
42
+ ```
43
+ OK, so that out of the way, let's add `devise\_sqreener` to the `User` model using the following generator:
23
44
 
24
45
  ```bash
25
- $ rails generate devise_sqreener MODEL
46
+ $ rails generate devise_sqreener User
26
47
  ```
27
48
 
28
- Replace `MODEL` with the class name you want to add devise\_sqreener. This will add the `:sqreenable` flag to your model's Devise modules. The generator will also create a migration file. Currently only ActiveRecord is supported. Then run:
49
+ This will add the `:sqreenable` flag to your `User` model, and some new fields in the User table of your database. The generator will also create a migration file. Currently only ActiveRecord is supported.
50
+
51
+ Let's get that migration knocked out, then? Run:
29
52
 
30
53
  ```bash
31
54
  $ rails db:migrate
32
55
  ```
33
56
 
34
- For the automatic sqreening to work you need to provide [your API token](https://my.sqreen.io) into you devise configuration (in `config/initializers/devise.rb`):
57
+ ## Get your API token
58
+
59
+ For the automatic sqreening to work you need to provide [your Sqreen API token](https://my.sqreen.io) in your Devise configuration, `config/initializers/devise.rb`. You might need to create an account on Sqreen—and once you do you can choose between the 14-day free trial for the full product; if you just want to get straight to the API, however, create a new API Sandbox instead. The API Sandboxes are free forever, albeit rate-limited and with a limited number of requests per month. That will do for our purposes nicely.
60
+
61
+ Anyway, we're not going to advocate for just leaving service credentials in your code, did you? Ha, of course not. No, we're going to pass it in as an environment variable. So add the following *_verbatim_* to the bottom of your Devise configuration.
62
+
35
63
  ```ruby
36
64
  Devise.setup do |config|
37
65
  #...
38
- config.sqreen_api_token="TOKEN"
66
+ config.sqreen_api_token=ENV["SQREEN_API_TOKEN"] # <- DO NOT PUT YOUR API TOKEN HERE!
39
67
  #...
40
68
  end
41
69
  ```
42
70
 
43
- ## Manual Installation
44
-
45
- First if you want IP addresses to be sqreened (as it were) ensure your model use Devise `:trackable`.
46
-
47
- Add `:sqreenable` to the devise call in your model:
71
+ And pass it in to your app's runtime environment with something like
48
72
 
49
- ```ruby
50
- class User < ActiveRecord
51
- devise :database_authenticable, :confirmable, :sqreenable
52
- end
53
73
  ```
54
- Add the necessary fields to your Devise model migration:
55
-
56
- ```ruby
57
- class DeviseSqreenerAddToUser < ActiveRecord::Migration
58
- def change
59
- add_column :user, :sqreened_email, :text
60
- # only if you use devise's :trackable
61
- add_column :user, :current_sqreened_sign_in_ip, :text
62
- # only if you use devise's :trackable
63
- add_column :user, :last_sqreened_sign_in_ip, :text
64
- end
65
- end
74
+ export SQREEN_API_TOKEN="PASTE_YOUR_TOKEN_HERE"
66
75
  ```
67
- Then run:
68
76
 
69
- ```bash
70
- $ rails db:migrate
71
- ```
77
+ There are lots of ways to get environment variables into your Rails app, of course—you should follow the practices used for your particular app if they aren't set in this way.
72
78
 
73
- For the automatic sqreening to work you need to provide [your API token](https://my.sqreen.io) into you devise configuration (in `config/initializers/devise.rb`):
74
- ```ruby
75
- Devise.setup do |config|
76
- #...
77
- config.sqreen_api_token="TOKEN"
78
- #...
79
- end
80
- ```
81
79
 
82
- ## Usage
80
+ ## Looking at security metadata
83
81
 
84
- Signups and Signins are automatically sqreened whenever needed. [Sqreened metada](https://www.sqreen.io/developers.html) are automatically added to your model as serialized fields.
82
+ Sign-ups and sign-ins are automatically sqreened whenever needed. [Sqreened metada](https://www.sqreen.io/developers.html) are automatically added to your model as serialized fields.
85
83
  ![Activeadmin Screenshor](/doc/activeadmin.png)
86
84
 
87
- ## Blocking signups or signins
85
+ ## Configuring your user Sqreening policy
86
+
87
+ Policies are implemented as predicates in your Devise configuration, `config/initializers/devise.rb`. There are two predicates, one for signing up and one for signing in. The predicates can do really anything you like, including firing off notifications, or flagging the user in some way. But the most important thing is deciding whether to block the user from completing the sign-up or sign-in action.
88
+
89
+ The arguments to the predicates are:
90
+ * `email`: Current email sqreened metadata (a Hash or nil)
91
+ * `ip`: Current ip address sqreened metadata (a Hash or nil)
92
+ * `user`: The current instance of your MODEL class trying to sign in/up.
88
93
 
89
- Blocking sign up or sign in is as easy as adding a predicate in your devise configuration.
94
+ The return value should be a boolean. If your predicate returns `true`, the action will be blocked. If your predicate returns `false`, the action will not be blocked.
95
+
96
+ The `email` hash passed to the predicate has the following structure:
97
+
98
+ * `email`: string The email address queried.
99
+ * `risk_score`: number The assessed risk that this email address is being used by a malevolent actor. Values range from 0 to 100. Anything greater than 80 is really bad and should be dropped; anything greater than about 40 is worth flagging and keeping an eye on.
100
+ * `is_email_harmful`: boolean Does the email address itself pose a direct security risk? E.g., does the email address contain embedded JavaScript?
101
+ * `is_known_attacker`: boolean Was this email address used as part of a security attack?
102
+ * `high_risk_security_events_count`: number The number of high-risk security events (e.g. SQL injection attacks) involving this email address.
103
+ * `security_events_count`: number The number of all security events (both high-risk and low-risk) involving this email address.
104
+ * `is_disposable`: boolean Does this email's domain belong to a known vendor of disposable, temporary, or anonymized email addresses?
105
+ * `is_email_malformed`: boolean Is the email malformed according to RFC 5322?
106
+
107
+ The `ip` hash passed to the predicate has the following structure:
108
+
109
+ * `ip`: string The IP address queried.
110
+ * `ip_version`: number The version of the IP address queried. Either 4 or 6.
111
+ * `risk_score`: number The assessed risk that this IP address is being used by a malevolent actor. Values range from 0 to 100. Anything greater than 80 is really bad and should be dropped; anything greater than about 40 is worth flagging and keeping an eye on.
112
+ * `is_known_attacker`: boolean Was this IP address used as part of a security attack?
113
+ * `high_risk_security_events_count`: number The number of high-risk security events (e.g. SQL injection attacks) originating from this IP address.
114
+ * `security_events_count`: number The number of all security events (both high-risk and low-risk) originating from this IP address.
115
+ * `ip_geo`: object The geographical location associated with this IP address.
116
+ * `ip_geo.latitude` number The latitude of the location.
117
+ * `ip_geo.longitude `number The longitude of the location.
118
+ * `ip_geo.country_code` string The ISO ALPHA-3 Code for the country that this location exists within.
119
+ * `is_datacenter`: boolean Does this IP address belong to a known datacenter, such as AWS or Google Cloud?
120
+ * `is_vpn`: boolean Does this IP address belong to a known VPN?
121
+ * `is_proxy`: boolean Does this IP address belong to a known proxy server?
122
+ * `is_tor`: boolean Is this IP address a known Tor exit point?
123
+
124
+ Let's suppose that we want to block all sign-ups and sign-ins over TOR:
90
125
 
91
126
  ```ruby
92
127
  Devise.setup do |config|
93
128
  #...
94
129
  # Block signing in from TOR
95
130
  config.sqreen_block_sign_in = -> (email, ip, user) {ip && ip["is_tor"] }
96
- # Block signing up with a disposable email address
97
- config.sqreen_block_sign_up = -> (email, ip, user) {email && email["is_disposable"] }
131
+ # Block signing up from TOR
132
+ config.sqreen_block_sign_up = -> (email, ip, user) {ip && ip["is_tor"] }
98
133
  #...
99
134
  end
100
135
  ```
101
136
 
102
- The arguments always are:
103
- * `email`: Current email sqreened metadata (a Hash or nil)
104
- * `ip`: Current ip address sqreened metadata (a Hash or nil)
105
- * `user`: The current instance of your MODEL class trying to sign in/up.
106
-
107
- ## Contributing to devise\_sqreener
108
-
109
- * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
110
- * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
111
- * Fork the project.
112
- * Start a feature/bugfix branch.
113
- * Commit and push until you are happy with your contribution.
114
- * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
115
- * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
137
+ Or perhaps you just want to look at Sqreen's pre-calculated risk score for the email address to make this determination:
138
+ ```ruby
139
+ Devise.setup do |config|
140
+ #...
141
+ # Block signing up with a risky email address
142
+ config.sqreen_block_sign_up = -> (email, ip, user) {email && email["risk_score"] > 70 }
143
+ #...
144
+ end
145
+ ```
116
146
 
117
- ## Copyright
147
+ The possibilities are...well, let's be honest, they're not exactly endless, but there is a great deal of flexibility in crafting these policies.
118
148
 
119
- Copyright (c) 2017 Sqreen. See LICENSE.txt for further details.
149
+ ## Let us know how it works for you
120
150
 
151
+ So, that's about all there is to it! Having a problem? Have an idea for how we could improve this Devise plugin? [Open an issue](https://github.com/sqreen/devise_sqreener/issues/new), and let us know what we can do better.
@@ -0,0 +1,7 @@
1
+ en:
2
+ devise:
3
+ failure:
4
+ user:
5
+ forbidden: "Signing in was forbidden by current policy"
6
+ registrations:
7
+ forbidden: "Signing up was forbidden by current policy"
@@ -63,7 +63,7 @@ module Devise
63
63
  return false if oracle.blank? || !oracle.respond_to?(:call)
64
64
  if oracle.call(current_sqreened_email,
65
65
  current_sqreened_ip_address, self)
66
- errors[:base] = I18n.t(:forbidden, :scope => %i(devise registrations))
66
+ errors[:base] << I18n.t(:forbidden, :scope => %i(devise registrations))
67
67
  return true
68
68
  end
69
69
  false
@@ -1,4 +1,6 @@
1
1
  require 'net/http'
2
+ require 'devise_sqreener/version'
3
+
2
4
  module DeviseSqreener
3
5
  # sqreen an email of ip
4
6
  class Sqreen
@@ -28,9 +30,10 @@ module DeviseSqreener
28
30
 
29
31
  def sqreen(kind, value)
30
32
  uri = URI(format(BASE_URL, kind, value))
33
+ user_agent = "DeviseSqreener/#{DeviseSqreener::VERSION} #{Gem::Platform.local.os}/#{Gem::Platform.local.version} Rails/#{Rails::VERSION::STRING} Ruby/#{RUBY_VERSION}"
31
34
  response = Net::HTTP.start(uri.hostname, uri.port,
32
35
  :use_ssl => uri.scheme == 'https') do |http|
33
- http.request_get(uri, 'x-api-key' => sqreen_api_token.to_s)
36
+ http.request_get(uri, 'x-api-key' => sqreen_api_token.to_s, 'User-Agent' => user_agent)
34
37
  end
35
38
 
36
39
  handle_response(kind, value, response)
@@ -1,3 +1,3 @@
1
1
  module DeviseSqreener
2
- VERSION="0.1.0"
2
+ VERSION="0.1.1"
3
3
  end
@@ -6,7 +6,13 @@ module ActiveRecord
6
6
  source_root File.expand_path("../", __FILE__)
7
7
 
8
8
  def copy_devise_migration
9
- migration_template "migration.rb", "db/migrate/devise_sqreener_add_to_#{table_name}.rb"
9
+ migration_template "migration.rb", "db/migrate/devise_sqreener_add_to_#{table_name}.rb", migration_version: migration_version
10
+ end
11
+
12
+ def migration_version
13
+ if Rails::VERSION::MAJOR >= 5
14
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
15
+ end
10
16
  end
11
17
  end
12
18
  end
@@ -1,4 +1,4 @@
1
- class DeviseSqreenerAddTo<%= table_name.camelize %> < ActiveRecord::Migration
1
+ class DeviseSqreenerAddTo<%= table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
2
2
  def change
3
3
  add_column :<%= table_name %>, :sqreened_email, :text
4
4
  if <%= class_name %>.devise_modules.include?(:trackable)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devise_sqreener
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benoit Larroque
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2017-06-01 00:00:00.000000000 Z
13
+ date: 2017-06-05 00:00:00.000000000 Z
14
14
  dependencies: []
15
15
  description: Sqreen emails/ips that are seen by Devise through the Sqreen API, and
16
16
  block bad actors from signing up to your Rails app.
@@ -23,6 +23,7 @@ files:
23
23
  - LICENSE
24
24
  - README.md
25
25
  - Rakefile
26
+ - config/locales/en.yml
26
27
  - lib/devise_sqreener.rb
27
28
  - lib/devise_sqreener/hook.rb
28
29
  - lib/devise_sqreener/model.rb
@@ -30,7 +31,7 @@ files:
30
31
  - lib/devise_sqreener/version.rb
31
32
  - lib/generators/active_record/devise_sqreener_generator.rb
32
33
  - lib/generators/active_record/migration.rb
33
- - lib/generators/devise_sqreener/devise_enricher_generator.rb
34
+ - lib/generators/devise_sqreener/devise_sqreener_generator.rb
34
35
  homepage: https://github.com/sqreen/devise_sqreener
35
36
  licenses:
36
37
  - MIT