frikandel 1.0.0

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.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +7 -0
  5. data/Gemfile +4 -0
  6. data/Guardfile +10 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +82 -0
  9. data/Rakefile +7 -0
  10. data/frikandel.gemspec +31 -0
  11. data/lib/frikandel.rb +32 -0
  12. data/lib/frikandel/configuration.rb +19 -0
  13. data/lib/frikandel/version.rb +3 -0
  14. data/spec/controllers/application_controller_spec.rb +57 -0
  15. data/spec/controllers/customized_on_expired_cookie_controller_spec.rb +39 -0
  16. data/spec/dummy/README.rdoc +28 -0
  17. data/spec/dummy/Rakefile +6 -0
  18. data/spec/dummy/app/assets/images/.keep +0 -0
  19. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  20. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  21. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  22. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  23. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  24. data/spec/dummy/app/mailers/.keep +0 -0
  25. data/spec/dummy/app/models/.keep +0 -0
  26. data/spec/dummy/app/models/concerns/.keep +0 -0
  27. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  28. data/spec/dummy/bin/bundle +3 -0
  29. data/spec/dummy/bin/rails +4 -0
  30. data/spec/dummy/bin/rake +4 -0
  31. data/spec/dummy/config.ru +4 -0
  32. data/spec/dummy/config/application.rb +28 -0
  33. data/spec/dummy/config/boot.rb +5 -0
  34. data/spec/dummy/config/database.yml +25 -0
  35. data/spec/dummy/config/environment.rb +5 -0
  36. data/spec/dummy/config/environments/development.rb +29 -0
  37. data/spec/dummy/config/environments/production.rb +80 -0
  38. data/spec/dummy/config/environments/test.rb +36 -0
  39. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  40. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  41. data/spec/dummy/config/initializers/inflections.rb +16 -0
  42. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  43. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  44. data/spec/dummy/config/initializers/session_store.rb +3 -0
  45. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  46. data/spec/dummy/config/locales/en.yml +23 -0
  47. data/spec/dummy/config/routes.rb +56 -0
  48. data/spec/dummy/db/test.sqlite3 +0 -0
  49. data/spec/dummy/lib/assets/.keep +0 -0
  50. data/spec/dummy/public/404.html +58 -0
  51. data/spec/dummy/public/422.html +58 -0
  52. data/spec/dummy/public/500.html +57 -0
  53. data/spec/dummy/public/favicon.ico +0 -0
  54. data/spec/lib/frikandel/configuration_spec.rb +43 -0
  55. data/spec/spec_helper.rb +21 -0
  56. data/spec/support/application_controller.rb +16 -0
  57. metadata +242 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5d21550e8f406f5cfadd7246e3a5b511e6719b2d
4
+ data.tar.gz: c205899f482cc2e2e6fc64f69070c7b5f4cdda59
5
+ SHA512:
6
+ metadata.gz: 40977fc969914d45e38951d1bcd37577bb8376f8e8c9e13dbf56d2076194973409de535136ee6af30e3c31b5ab34f52b1350e630cc6723c179b0c131f8288b0b
7
+ data.tar.gz: 62eb2c7883e57b57c297db621bc5eccf42ab4f653a93ff7e7867fa7bc57d386c7765fd11914cdb5f954085c1aea8842d1a27dc33346598b30ebdd7b79334630c
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .ruby-*
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+
20
+ spec/dummy/log/
21
+ .ruby-gemset
22
+ .ruby-version
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
6
+ - jruby-19mode
7
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in frikandel.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,10 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :rspec do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+
9
+ end
10
+
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Taktsoft
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,82 @@
1
+ # Frikandel
2
+
3
+ This Gem adds a TTL (Time To Live) Date to every cookie that your application sets. When the cookie has expired, the users session gets reset. This should help protect from Session-Fixation-Attacks.
4
+
5
+
6
+ ## Requirements
7
+
8
+ Rails 3.2 and 4.x are currently supported.
9
+
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'frikandel'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+
26
+ $ gem install frikandel
27
+
28
+
29
+ ## Usage
30
+
31
+ To activate frikandel's Session-Fixation-Protection for your application, you only need to include a module in your `ApplicationController`:
32
+
33
+ ```ruby
34
+ class ApplicationController < ActionController::Base
35
+ include Frikandel::LimitSessionLifetime
36
+
37
+ # ...
38
+ end
39
+ ```
40
+
41
+ ## Configuration
42
+
43
+ To configure frikandel's TTL-values, you can add an initializer in `config/initializers` namend `frikandel.rb` and insert the following lines:
44
+
45
+ ```ruby
46
+ Frikandel::Configuration.max_ttl = 2.days
47
+ Frikandel::Configuration.ttl = 4.hours
48
+ ```
49
+
50
+ The value at `Frikandel::Configuration.max_ttl` is the absolute value in seconds that a cookie is valid. In this example, all cookies will be invalidated after two days in all cases. This timestamp doesn't get refreshed.
51
+
52
+ The second value `Frikandel::Configuration.ttl` states how long (in seconds) a session/cookie is valid, when the cookie timestamp gets not refreshed. The timestamp gets refrehed everytime a user visits the site.
53
+
54
+ The default values are `24.hours` for `max_ttl` and `2.hours` for `ttl`. If you are okay with this settings, you don't need to create an initializer for frikandel.
55
+
56
+
57
+ ### Customize on_expired_session behavior
58
+
59
+ You can also overwrite what should happen when a cookie times out on the controller-level. The default behaviour is to do a `reset_session` and `redirect_to root_path`. For example, if you want to overwrite the default behavior when a user is on the `PublicController`, you want to overwrite the `on_expired_session`-method in your controller:
60
+
61
+ ```ruby
62
+ class PublicController < ApplicationController
63
+ def on_expired_session
64
+ raise "Your Session Has Expired! Oh No!"
65
+ end
66
+ end
67
+ ```
68
+
69
+ If you want to revert the original behavior in a sub-class of your `PublicController`, you simply re-alias the method to `original_on_expired_session` like this:
70
+
71
+ ```ruby
72
+ class AdminController < PublicController
73
+ alias on_expired_session original_on_expired_session
74
+ end
75
+ ```
76
+
77
+ ## Contributing
78
+ 1. Fork it
79
+ 2. Create your feature branch (git checkout -b my-new-feature)
80
+ 3. Commit your changes (git commit -am 'Add some feature')
81
+ 4. Push to the branch (git push origin my-new-feature)
82
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new('spec')
5
+
6
+ # If you want to make this the default task
7
+ task :default => :spec
data/frikandel.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'frikandel/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "frikandel"
8
+ spec.version = Frikandel::VERSION
9
+ spec.authors = ["Taktsoft"]
10
+ spec.email = ["developers@taktsoft.com"]
11
+ spec.summary = %q{This gem adds a ttl to the session cookie of your application.}
12
+ spec.description = spec.summary
13
+ spec.homepage = "https://github.com/taktsoft/frikandel"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = Dir["spec/**/*"]
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "sqlite3" unless RUBY_PLATFORM == 'java'
24
+ spec.add_development_dependency "jdbc-sqlite3" if RUBY_PLATFORM == 'java'
25
+ spec.add_development_dependency "activerecord-jdbcsqlite3-adapter" if RUBY_PLATFORM == 'java'
26
+ spec.add_development_dependency "rspec-rails"
27
+ spec.add_development_dependency "guard-rspec"
28
+ spec.add_development_dependency "pry"
29
+
30
+ spec.add_dependency "rails", ['>= 3.2.0', '< 5.0']
31
+ end
data/lib/frikandel.rb ADDED
@@ -0,0 +1,32 @@
1
+ require "frikandel/version"
2
+ require "frikandel/configuration"
3
+
4
+ module Frikandel
5
+ module LimitSessionLifetime
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ append_before_filter :validate_session_timestamp
10
+ append_after_filter :persist_session_timestamp
11
+ end
12
+
13
+ private
14
+
15
+ def validate_session_timestamp
16
+ if session.key?(:ttl) && session.key?(:max_ttl) && (session[:ttl] < Frikandel::Configuration.ttl.ago || session[:max_ttl] < Time.now)
17
+ on_expired_session
18
+ end
19
+ end
20
+
21
+ def persist_session_timestamp
22
+ session[:ttl] = Time.now
23
+ session[:max_ttl] ||= Frikandel::Configuration.max_ttl.from_now
24
+ end
25
+
26
+ def on_expired_session
27
+ reset_session
28
+ redirect_to root_path
29
+ end
30
+ alias original_on_expired_session on_expired_session
31
+ end
32
+ end
@@ -0,0 +1,19 @@
1
+ module Frikandel
2
+ class Configuration
3
+ include Singleton
4
+ extend SingleForwardable
5
+
6
+ attr_accessor :ttl, :max_ttl
7
+
8
+ def_delegators :instance, :defaults!, :ttl, :ttl=, :max_ttl, :max_ttl=
9
+
10
+ def initialize
11
+ defaults!
12
+ end
13
+
14
+ def defaults!
15
+ self.ttl = 2.hours
16
+ self.max_ttl = 24.hours
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module Frikandel
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,57 @@
1
+ require "spec_helper"
2
+ require "support/application_controller"
3
+
4
+ describe ApplicationController do
5
+
6
+ it "holds the session for at least .1 seconds" do
7
+ get :home
8
+ session[:user_id] = 1337
9
+ sleep 0.1
10
+ get :home
11
+
12
+ session[:user_id].should be_present
13
+ session[:user_id].should eq 1337
14
+ end
15
+
16
+ it "destroys the session after SESSION_TTL" do
17
+ get :home
18
+ session[:user_id] = 2337
19
+ request.session[:ttl] = (Frikandel::Configuration.ttl + 1.minute).seconds.ago
20
+ get :home
21
+
22
+ session[:user_id].should be_blank
23
+ end
24
+
25
+ it "destroys the session after SESSION_MAX_TTL" do
26
+ get :home
27
+ session[:user_id] = 3337
28
+
29
+ request.session[:max_ttl] = 1.minute.ago
30
+ get :home
31
+
32
+ session[:user_id].should be_blank
33
+ end
34
+
35
+ it "works when there was no session in the request" do
36
+ get :home
37
+ session[:user_id] = 4337
38
+ request.session = nil
39
+ get :home
40
+
41
+ session[:user_id].should be_blank
42
+ end
43
+
44
+ it "is configurable" do
45
+ old_value = Frikandel::Configuration.ttl
46
+ Frikandel::Configuration.ttl = 1.minute
47
+ get :home
48
+ session[:ttl] = 30.minutes.ago
49
+ session[:user_id] = 5337
50
+
51
+ get :home
52
+ session[:user_id].should be_blank
53
+
54
+ Frikandel::Configuration.ttl = old_value
55
+ end
56
+
57
+ end
@@ -0,0 +1,39 @@
1
+ require "spec_helper"
2
+ require "support/application_controller"
3
+
4
+ class SessionExpiredError < StandardError; end
5
+
6
+ class CustomizedOnExpiredSessionController < ApplicationController
7
+ def on_expired_session
8
+ raise SessionExpiredError.new("Your Session is DEAD!")
9
+ end
10
+ alias my_on_expired_session on_expired_session
11
+ end
12
+
13
+ describe CustomizedOnExpiredSessionController do
14
+
15
+ it "uses the overwritten on_expired_cookie function" do
16
+ get :home
17
+ request.session[:max_ttl] = 1.minute.ago
18
+
19
+ expect { get :home }.to raise_error SessionExpiredError
20
+ end
21
+
22
+ it "can revert the on_expired_cookie function back to the original" do
23
+ # NOTE: Don't confuse original_on_expired_session with my_on_expired_session!
24
+ class CustomizedOnExpiredSessionController < ApplicationController
25
+ alias on_expired_session original_on_expired_session # Setting it to the Gems original
26
+ end
27
+
28
+ get :home
29
+ request.session[:max_ttl] = 1.minute.ago
30
+
31
+ begin
32
+ expect { get :home }.to_not raise_error
33
+ ensure
34
+ class CustomizedOnExpiredSessionController < ApplicationController
35
+ alias on_expired_session my_on_expired_session # Reverting it back to the Customized function thats defined in this test
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,28 @@
1
+ == README
2
+
3
+ This README would normally document whatever steps are necessary to get the
4
+ application up and running.
5
+
6
+ Things you may want to cover:
7
+
8
+ * Ruby version
9
+
10
+ * System dependencies
11
+
12
+ * Configuration
13
+
14
+ * Database creation
15
+
16
+ * Database initialization
17
+
18
+ * How to run the test suite
19
+
20
+ * Services (job queues, cache servers, search engines, etc.)
21
+
22
+ * Deployment instructions
23
+
24
+ * ...
25
+
26
+
27
+ Please feel free to use a different markup language if you do not plan to run
28
+ <tt>rake doc:app</tt>.
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Dummy::Application.load_tasks
File without changes
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,13 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree .
13
+ */
@@ -0,0 +1,5 @@
1
+ class ApplicationController < ActionController::Base
2
+ # Prevent CSRF attacks by raising an exception.
3
+ # For APIs, you may want to use :null_session instead.
4
+ protect_from_forgery with: :exception
5
+ end