Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Convert to gem #5

Merged
merged 2 commits into from

2 participants

Piotr Boniecki Maciej Litwiniuk
Piotr Boniecki
Owner

#4

Maciej Litwiniuk mlitwiniuk merged commit 6a0f1d4 into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 25, 2013
  1. Piotr Boniecki

    do not depend on warden

    Bonias authored
  2. Piotr Boniecki

    make gem

    Bonias authored
This page is out of date. Refresh to see the latest.
18 .gitignore
View
@@ -1 +1,17 @@
-.redcar/**
+*.gem
+*.rbc
+.bundle
+.config
+.yardoc
+Gemfile.lock
+InstalledFiles
+_yardoc
+coverage
+doc/
+lib/bundler/man
+pkg
+rdoc
+spec/reports
+test/tmp
+test/version_tmp
+tmp
4 Gemfile
View
@@ -0,0 +1,4 @@
+source 'https://rubygems.org'
+
+# Specify your gem's dependencies in session_protector2.gemspec
+gemspec
6 MIT-LICENSE → LICENSE.txt
View
@@ -1,4 +1,6 @@
-Copyright (c) 2010 [name of plugin creator]
+Copyright (c) 2013 Bonias
+
+MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -17,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16 README.md
View
@@ -9,21 +9,27 @@ DESCRIPTION
**WARNING:** this only makes a little bit harder to hijack user session, our solution basically have nothing to do with session security!!
-Logout user if HTTP_USER_AGENT and IP differs from the one saved in session. This make it harder to successfully use session hijacking tools like [firesheep](http://codebutler.com/firesheep).
+Clear session if HTTP_USER_AGENT and IP differs from the one saved in session. This make it harder to successfully use session hijacking tools like [firesheep](http://codebutler.com/firesheep).
Also, usage of `browser_fingerprint.js` allows usage of pseudo-unique fingerprint of users browser details. Both combined makes much harder (at least for script kiddies using firesheep for evil purposes) to hijack session (yeah, right).
REQUIREMENTS
------------
-**Devise** or other authentication system based on **Warden**
+**Rails**
INSTALL
-------
-`rails plugin install git://github.com/galdomedia/session_protector.git`
+add
-You MAY also want to install browser_fingerprint script. To do this simply run:
+`gem 'session_protector'`
+
+to Gemfile and run
+
+`bundle install`
+
+You MAY also want to install browser_fingerprint script. To do this simply:
`rails generate session_protector:install`
@@ -68,4 +74,4 @@ CREDITS
* [Kevin van Zonneveld](http://phpjs.org/functions/md5:469) - JavaScript MD5
-Copyright (c) 2010 Piotr Boniecki (piotr [at] galdomedia [dot] pl), released under the MIT license
+Copyright (c) 2010 Piotr Boniecki (piotr [at] galdomedia [dot] pl), released under the MIT license
25 Rakefile
View
@@ -1,23 +1,8 @@
-require 'rake'
-require 'rake/testtask'
-require 'rake/rdoctask'
+require "bundler/gem_tasks"
-desc 'Default: run unit tests.'
-task :default => :test
+require 'rspec/core/rake_task'
-desc 'Test the session_protector plugin.'
-Rake::TestTask.new(:test) do |t|
- t.libs << 'lib'
- t.libs << 'test'
- t.pattern = 'test/**/*_test.rb'
- t.verbose = true
-end
+RSpec::Core::RakeTask.new('spec')
-desc 'Generate documentation for the session_protector plugin.'
-Rake::RDocTask.new(:rdoc) do |rdoc|
- rdoc.rdoc_dir = 'rdoc'
- rdoc.title = 'SessionProtector'
- rdoc.options << '--line-numbers' << '--inline-source'
- rdoc.rdoc_files.include('README')
- rdoc.rdoc_files.include('lib/**/*.rb')
-end
+# If you want to make this the default task
+task :default => :spec
0  ...ctor/templates/javascripts/browser_fingerprint.js → app/assets/javascripts/browser_fingerprint.js
View
File renamed without changes
2  init.rb
View
@@ -1,2 +0,0 @@
-require 'session_protector'
-require 'warden/callback'
1  install.rb
View
@@ -1 +0,0 @@
-# Install hook code here
26 lib/generators/session_protector/install_generator.rb
View
@@ -1,27 +1,9 @@
module SessionProtector
class InstallGenerator < Rails::Generators::Base
+ source_root File.expand_path("../../../../app/assets/javascripts", __FILE__)
- FILES = [
- 'browser_fingerprint.js'
- ]
-
- desc "Copy session_protector files to public/javascript folder."
-
- source_root File.expand_path('../templates', __FILE__)
-
- def install_session_protector
- src_prefix = File.join('javascripts')
- dest_prefix = File.join('public', 'javascripts')
-
- FILES.each do |path|
- src = File.join(src_prefix, path)
- dest = File.join(dest_prefix, path)
-
- copy_file(src, dest) if path =~ /\./
- end
-
+ def copy_browser_fingerprint
+ copy_file "browser_fingerprint.js", "app/assets/javascripts/browser_fingerprint.js"
end
-
end
-
-end
+end
23 lib/rack/session_protector.rb
View
@@ -0,0 +1,23 @@
+require 'session_protector/base'
+
+module Rack
+ class SessionProtector
+
+ def initialize(app, options={})
+ @options = {:check_ip => ::SessionProtector.check_ip}.merge(options)
+ @app = app
+ end
+
+ def call(env)
+ @request = ActionDispatch::Request.new(env)
+ protector = ::SessionProtector::Base.new(@request, @options)
+ if protector.safe_request?
+ @app.call(env)
+ else
+ @request.reset_session
+ [302, {"Location" => "/"}, []]
+ end
+ end
+
+ end
+end
15 lib/session_protector.rb
View
@@ -1,11 +1,20 @@
+require "session_protector/version"
+
module SessionProtector
- VERSION = '0.0.1'
-
# Check IP. True by default
- mattr_accessor :check_ip
+ def self.check_ip
+ @@check_ip
+ end
+
+ def self.check_ip= attr
+ @@check_ip = attr
+ end
+
@@check_ip = true
def self.setup
yield self
end
end
+
+require 'session_protector/rails'
81 lib/session_protector/base.rb
View
@@ -1,64 +1,61 @@
module SessionProtector
+ class Error < StandardError
+
+ end
+
class Base
CHECK_METHODS = %w(cookie env_vars)
-
- attr_accessor :warden, :scope, :session
-
- def initialize(warden, scope)
- @warden = warden
- @scope = scope
- @session = warden.session(scope)
- end
-
- def protect
+
+ attr_accessor :cookies, :session, :options, :request
+
+ def initialize(request, options)
+ @request = request
+ @session = @request.session
+ @cookies = @request.cookies
+ @options = options
+ end
+
+ def safe_request?
CHECK_METHODS.each do |method|
- self.send("set_#{method}")
+ self.send("check_#{method}")
end
-
- CHECK_METHODS.inject(false) do |logged_out, method|
- logged_out || self.send("check_#{method}")
+
+ CHECK_METHODS.each do |method|
+ self.send("set_#{method}")
end
- end
-
+
+ true
+ rescue ::SessionProtector::Error => e
+ false
+ end
+
+ private
+
def cookie_required_string
- return @cookie_required_string if @cookie_required_string
- cookies = warden.request.cookies
- if cookies and cookies.keys.member?('_browser_fingerprint')
- @cookie_required_string = cookies['_browser_fingerprint']
- end
- @cookie_required_string
+ @cookie_required_string ||= cookies['_browser_fingerprint']
end
-
+
def set_cookie
session['browser_fingerprint'] ||= cookie_required_string if cookie_required_string.present?
end
-
+
def check_cookie
- if cookie_required_string != session['browser_fingerprint']
- warden.logout(scope)
- return true
- end
+ return if session['browser_fingerprint'].nil?
+ raise ::SessionProtector::Error, "Wrong browser_fingerprint: #{cookie_required_string} != #{session['browser_fingerprint']}" if cookie_required_string == session['browser_fingerprint']
end
-
+
def env_vars_required_string
- return @env_vars_required_string if @env_vars_required_string
- if !warden.env['HTTP_USER_AGENT'].nil?
- @env_vars_required_string = "#{warden.env['HTTP_USER_AGENT']}-#{SessionProtector.check_ip ? warden.request.remote_ip : ''}"
- end
- @env_vars_required_string
+ @env_vars_required_string ||= "#{request.env['HTTP_USER_AGENT']}-#{options[:check_ip] ? request.remote_ip : ''}"
end
-
+
def set_env_vars
session['user_agent_with_ip'] ||= env_vars_required_string if env_vars_required_string
end
-
+
def check_env_vars
- if env_vars_required_string
- if env_vars_required_string != session['user_agent_with_ip']
- warden.logout(scope)
- return true
- end
- end
+ return if session['user_agent_with_ip'].nil?
+ raise ::SessionProtector::Error, "Wrong user_agent_with_ip: #{env_vars_required_string} != #{session['user_agent_with_ip']}" if env_vars_required_string != session['user_agent_with_ip']
end
+
end
end
10 lib/session_protector/rails.rb
View
@@ -0,0 +1,10 @@
+require "rack/session_protector"
+require 'rails'
+
+module SessionProtector
+
+ class Engine < Rails::Engine
+ config.app_middleware.use Rack::SessionProtector
+ end
+
+end
3  lib/session_protector/version.rb
View
@@ -0,0 +1,3 @@
+module SessionProtector
+ VERSION = "0.1.1"
+end
4 lib/warden/callback.rb
View
@@ -1,4 +0,0 @@
-Warden::Manager.after_set_user do |record, warden, options|
- protector = SessionProtector::Base.new(warden, options[:scope])
- protector.protect
-end
25 session_protector.gemspec
View
@@ -0,0 +1,25 @@
+# -*- encoding: utf-8 -*-
+lib = File.expand_path('../lib', __FILE__)
+$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
+require 'session_protector/version'
+
+Gem::Specification.new do |gem|
+ gem.name = "session_protector"
+ gem.version = SessionProtector::VERSION
+ gem.authors = ["Piotr Boniecki", "GaldoMedia"]
+ gem.email = ["piotr@galdomedia.pl"]
+ gem.description = %q{Small middleware, that helps a little bit to protect user session from session hijacking (by checking browsers user_agent)}
+ gem.summary = %q{Small middleware, that helps a little bit to protect user session from session hijacking (by checking browsers user_agent)}
+ gem.homepage = "https://github.com/galdomedia/session_protector"
+ gem.license = "MIT"
+
+ gem.files = `git ls-files`.split($/)
+ gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
+ gem.require_paths = ["lib"]
+
+ gem.add_dependency "rails"
+
+ gem.add_development_dependency "rake"
+ gem.add_development_dependency "rspec"
+end
8 spec/session_protector_spec.rb
View
@@ -0,0 +1,8 @@
+require 'spec_helper'
+
+describe SessionProtector do
+ it 'should have a version number' do
+ SessionProtector::VERSION.should_not be_nil
+ end
+
+end
2  spec/spec_helper.rb
View
@@ -0,0 +1,2 @@
+$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
+require 'session_protector'
1  uninstall.rb
View
@@ -1 +0,0 @@
-# Uninstall hook code here
Something went wrong with that request. Please try again.