Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
rkh committed May 23, 2011
0 parents commit 0985552
Show file tree
Hide file tree
Showing 21 changed files with 333 additions and 0 deletions.
2 changes: 2 additions & 0 deletions rack-protection/.gitignore
@@ -0,0 +1,2 @@
# please add general patterns to your global ignore list
# see https://github.com/github/gitignore#readme
2 changes: 2 additions & 0 deletions rack-protection/Gemfile
@@ -0,0 +1,2 @@
source "http://rubygems.org" unless ENV['QUICK']
gemspec
20 changes: 20 additions & 0 deletions rack-protection/License
@@ -0,0 +1,20 @@
Copyright (c) 2011 Konstantin Haase

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
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.
17 changes: 17 additions & 0 deletions rack-protection/README.md
@@ -0,0 +1,17 @@
You should use protection!

# Usage

``` ruby
# config.ru
require 'rack/protection'
use Rack::Protection
```

# Installation

gem install rack-protection

# TODO

* Write code and documentation
37 changes: 37 additions & 0 deletions rack-protection/Rakefile
@@ -0,0 +1,37 @@
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)

begin
require 'bundler'
Bundler::GemHelper.install_tasks
rescue LoadError => e
$stderr.puts e
end

desc "run specs"
task(:spec) { ruby '-S rspec spec' }

desc "generate gemspec"
task 'rack-protection.gemspec' do
require 'rack/protection/version'
content = File.read 'rack-protection.gemspec'

fields = {
:authors => `git shortlog -sn`.scan(/[^\d\s].*/),
:email => `git shortlog -sne`.scan(/[^<]+@[^>]+/),
:files => `git ls-files`.split("\n").reject { |f| f =~ /^(\.|Gemfile)/ }
}

fields.each do |field, values|
updated = " s.#{field} = ["
updated << values.map { |v| "\n %p" % v }.join(',')
updated << "\n ]"
content.sub!(/ s\.#{field} = \[\n( .*\n)* \]/, updated)
end

content.sub! /(s\.version.*=\s+).*/, "\\1\"#{Rack::Protection::VERSION}\""
File.open('rack-protection.gemspec', 'w') { |f| f << content }
end

task :gemspec => 'rack-protection.gemspec'
task :default => :spec
task :test => :spec
1 change: 1 addition & 0 deletions rack-protection/lib/rack-protection.rb
@@ -0,0 +1 @@
require "rack/protection"
33 changes: 33 additions & 0 deletions rack-protection/lib/rack/protection.rb
@@ -0,0 +1,33 @@
require 'rack/protection/version'
require 'rack'

module Rack
module Protection
autoload :AuthenticityToken, 'rack/protection/authenticity_token'
autoload :Base, 'rack/protection/base'
autoload :EscapedParams, 'rack/protection/escaped_params'
autoload :FormToken, 'rack/protection/form_token'
autoload :FrameOptions, 'rack/protection/frame_options'
autoload :NoReferrer, 'rack/protection/no_referrer'
autoload :PathTraversal, 'rack/protection/path_traversal'
autoload :RemoteReferrer, 'rack/protection/remote_referrer'
autoload :RemoteToken, 'rack/protection/remote_token'
autoload :SessionHijacking, 'rack/protection/session_hihacking'
autoload :XSSHeader, 'rack/protection/xss_header'

def self.new(app, options = {})
# does not include: AuthenticityToken, FormToken and NoReferrer
except = Array options[:except]
Rack::Builder.new do
use EscapedParams, options unless except.include? :escaped_params
use FrameOptions, options unless except.include? :frame_options
use PathTraversal, options unless except.include? :path_traversal
use RemoteReferrer, options unless except.include? :remote_referrer
use RemoteToken, options unless except.include? :remote_token
use SessionHijacking, options unless except.include? :session_hihacking
use XSSHeader, options unless except.include? :xss_header
run app
end.to_app
end
end
end
8 changes: 8 additions & 0 deletions rack-protection/lib/rack/protection/authenticity_token.rb
@@ -0,0 +1,8 @@
require 'rack/protection'

module Rack
module Protection
class AuthenticityToken < Base
end
end
end
44 changes: 44 additions & 0 deletions rack-protection/lib/rack/protection/base.rb
@@ -0,0 +1,44 @@
require 'rack/protection'

module Rack
module Protection
class Base
DEFAULT_OPTIONS = { :reaction => :drop_session, :logging => true }
attr_reader :app, :options

def self.default_options(options)
define_method(:default_options) { super().merge(options) }
end

def default_options
DEFAULT_OPTIONS
end

def initialize(app, options = {})
@app, @options = app, options.merge(default_options)
end

def accepts?(env)
raise NotImplementedError, "#{self.class} implementation pending"
end

def call(env)
unless accepts? env
result = send(options[:reaction], env)
return result if Array === result and result.size = 3
end
app.call(env)
end

def warn(env, message)
return unless options[:logging]
l = options[:logger] || env['rack.logger'] || ::Logger.new(env['rack.errors'])
l.warn(message)
end

def drop_session(env)
env['rack.session'] = {}
end
end
end
end
8 changes: 8 additions & 0 deletions rack-protection/lib/rack/protection/escaped_params.rb
@@ -0,0 +1,8 @@
require 'rack/protection'

module Rack
module Protection
class EscapedParams < Base
end
end
end
8 changes: 8 additions & 0 deletions rack-protection/lib/rack/protection/form_token.rb
@@ -0,0 +1,8 @@
require 'rack/protection'

module Rack
module Protection
class FormToken < AuthenticityToken
end
end
end
8 changes: 8 additions & 0 deletions rack-protection/lib/rack/protection/frame_options.rb
@@ -0,0 +1,8 @@
require 'rack/protection'

module Rack
module Protection
class FrameOptions < Base
end
end
end
8 changes: 8 additions & 0 deletions rack-protection/lib/rack/protection/no_referrer.rb
@@ -0,0 +1,8 @@
require 'rack/protection'

module Rack
module Protection
class NoReferrer < Base
end
end
end
8 changes: 8 additions & 0 deletions rack-protection/lib/rack/protection/path_traversal.rb
@@ -0,0 +1,8 @@
require 'rack/protection'

module Rack
module Protection
class PathTraversal < Base
end
end
end
8 changes: 8 additions & 0 deletions rack-protection/lib/rack/protection/remote_referrer.rb
@@ -0,0 +1,8 @@
require 'rack/protection'

module Rack
module Protection
class RemoteReferrer < Base
end
end
end
8 changes: 8 additions & 0 deletions rack-protection/lib/rack/protection/remote_token.rb
@@ -0,0 +1,8 @@
require 'rack/protection'

module Rack
module Protection
class RemoteToken < AuthenticityToken
end
end
end
8 changes: 8 additions & 0 deletions rack-protection/lib/rack/protection/session_hihacking.rb
@@ -0,0 +1,8 @@
require 'rack/protection'

module Rack
module Protection
class SessionHijacking < Base
end
end
end
44 changes: 44 additions & 0 deletions rack-protection/lib/rack/protection/version.rb
@@ -0,0 +1,44 @@
module Rack
module Protection
def self.version
VERSION
end

module VERSION
extend Comparable

MAJOR = 0
MINOR = 0
TINY = 1
SIGNATURE = [MAJOR, MINOR, TINY]
STRING = SIGNATURE.join '.'

def self.major; MAJOR end
def self.minor; MINOR end
def self.tiny; TINY end
def self.to_s; STRING end

def self.hash
STRING.hash
end

def self.<=>(other)
other = other.split('.').map { |i| i.to_i } if other.respond_to? :split
SIGNATURE <=> Array(other)
end

def self.inspect
STRING.inspect
end

def self.respond_to?(meth, *)
meth.to_s !~ /^__|^to_str$/ and STRING.respond_to? meth unless super
end

def self.method_missing(meth, *args, &block)
return super unless STRING.respond_to?(meth)
STRING.send(meth, *args, &block)
end
end
end
end
21 changes: 21 additions & 0 deletions rack-protection/lib/rack/protection/xss_header.rb
@@ -0,0 +1,21 @@
module Rack
module Protection
class XSSHeader
HEADERS = {
'X-XSS-Protection' => '1; mode=block',
'X-Frame-Options' => 'sameorigin'
}

def initialize(app, options)
@app = app
@headers = HEADERS.merge(options[:xss_headers] || {})
@headers.delete_if { |k,v| !v }
end

def call(env)
status, headers, body = @app.call(env)
[status, @headers.merge(headers), body]
end
end
end
end
35 changes: 35 additions & 0 deletions rack-protection/rack-protection.gemspec
@@ -0,0 +1,35 @@
# Run `rake rack-protection.gemspec` to update the gemspec.
Gem::Specification.new do |s|
# general infos
s.name = "rack-protection"
s.version = "0.0.1"
s.description = "You should use protection!"
s.homepage = "http://github.com/rkh/rack-protection"
s.summary = s.description

# generated from git shortlog -sn
s.authors = [
"Konstantin Haase"
]

# generated from git shortlog -sne
s.email = [
"konstantin.mailinglists@googlemail.com"
]

# generated from git ls-files
s.files = [
"License",
"README.md",
"Rakefile",
"lib/rack-protection.rb",
"lib/rack/protection.rb",
"lib/rack/protection/version.rb",
"rack-protection.gemspec",
"spec/rack_protection_spec.rb"
]

# dependencies
s.add_dependency "rack"
s.add_development_dependency "rspec", "~> 2.0"
end
5 changes: 5 additions & 0 deletions rack-protection/spec/rack_protection_spec.rb
@@ -0,0 +1,5 @@
require 'rack/protection'

describe Rack::Protection do
it "should behave"
end

0 comments on commit 0985552

Please sign in to comment.