contextual 0.0.1-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rspec ADDED
File without changes
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in contextual.gemspec
4
+ gemspec
@@ -0,0 +1,45 @@
1
+ # Runtime Contextual Autoescaper
2
+
3
+ A JRuby wrapper for [Mike Samuel's contextual HTML autoescaper](https://github.com/mikesamuel/html-contextual-autoescaper-java). Same one as [used by Google's Closure Templates](http://code.google.com/closure/templates/docs/security.html).
4
+
5
+ ## Example
6
+
7
+ First, let's define an Erb template:
8
+
9
+ ```erb
10
+ <% def helper(obj); "Hello, #{obj['world']}"; end %>
11
+
12
+ <div style="color: <%= object['color'] %>">
13
+ <a href="/<%= object['color'] %>?q=<%= object['world'] %>" onclick="alert('<%= helper(object) %>');return false"><%= helper(object) %></a>
14
+ <script>(function () { // Sleepy developers put sensitive info in comments.
15
+ var o = <%= object %>,
16
+ w = "<%= object['world'] %>";
17
+ })();</script>
18
+ </div>
19
+ ```
20
+
21
+ Let's load the template and execute it:
22
+
23
+ ```ruby
24
+ template = Erubis::ContextualEruby.new(template_string)
25
+
26
+ object = {"world" => "<Cincinnati>", "color" => "blue"}
27
+ puts template.result(binding())
28
+ ```
29
+
30
+ Output:
31
+
32
+ ```html
33
+ <div style="color: blue">
34
+ <a href="/blue?q=%3cCincinnati%3e" onclick="alert('Hello, \x3cCincinnati\x3e');return false">Hello, &lt;Cincinnati&gt;</a>
35
+ <script>(function () {
36
+ var o = {'world':'\x3cCincinnati\x3e','color':'blue'},
37
+ w = "\x3cCincinnati\x3e";
38
+ })();</script>
39
+ </div>
40
+ ```
41
+
42
+ The safe parts are treated as literal chunks of HTML/CSS/JS, the query string parameters are auto URI encoded, same data is also auto escaped within the JS block, and the rendered object within the javascript block is automatically converted to JSON! Additionally, extra comments are removed, data is properly HTML escaped, and so forth.
43
+
44
+ Contextual will also automatically strip variety of injection cases for JS, CSS, and HTML, and give you a [dozen other features](https://github.com/mikesamuel/html-contextual-autoescaper-java/tree/master/src/tests/com/google/autoesc) for free.
45
+
@@ -0,0 +1,11 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ task :default => [:spec]
5
+ task :test => [:spec]
6
+
7
+ desc "run spec tests"
8
+ RSpec::Core::RakeTask.new('spec') do |t|
9
+ t.pattern = 'spec/**_spec.rb'
10
+ end
11
+
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "contextual/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "contextual"
7
+ s.version = Contextual::VERSION
8
+ s.authors = ["Ilya Grigorik"]
9
+ s.email = ["ilya@igvita.com"]
10
+ s.homepage = "https://github.com/igrigorik/contextual"
11
+ s.summary = "Runtime contextual autoescaper"
12
+ s.description = s.summary
13
+
14
+ s.rubyforge_project = "contextual"
15
+ s.platform = "java"
16
+
17
+ s.add_development_dependency "rspec"
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ s.require_paths = ["lib"]
23
+ end
@@ -0,0 +1,3 @@
1
+ require "contextual/version"
2
+ require "contextual/contextual"
3
+ require "contextual/rails_erubis" if defined? Rails
@@ -0,0 +1,95 @@
1
+ require "java"
2
+ require "ext/guava"
3
+ require "ext/autoesc"
4
+
5
+ java_import com.google.autoesc.HTMLEscapingWriter
6
+
7
+ require "rubygems"
8
+ require "erubis"
9
+
10
+ module Erubis
11
+ module ContextualEscapeEnhancer
12
+
13
+ def self.desc # :nodoc:
14
+ "switch '<%= %>' to escaped and '<%== %>' to unescaped"
15
+ end
16
+
17
+ def add_expr(src, code, indicator)
18
+ case indicator
19
+ when '='
20
+ @escape ? add_expr_literal(src, code) : add_expr_escaped(src, code)
21
+ when '=='
22
+ @escape ? add_expr_escaped(src, code) : add_expr_literal(src, code)
23
+ when '==='
24
+ add_expr_debug(src, code)
25
+ end
26
+ end
27
+
28
+ def add_text(src, text)
29
+ if !text.empty?
30
+ src << " #{@bufvar}.writeSafe '" << text.to_s.gsub("'", "\\\\'") << "';"
31
+ end
32
+ end
33
+
34
+ def add_stmt(src, code)
35
+ src << code
36
+ src << ';' unless code[-1] == ?\n
37
+ end
38
+
39
+ def add_expr_literal(src, code)
40
+ src << " #{@bufvar}.writeSafe(" << code << ').to_s;'
41
+ end
42
+
43
+ def add_expr_escaped(src, code)
44
+ src << " #{@bufvar}.write(" << code << ').to_s;'
45
+ end
46
+ end
47
+
48
+ class ContextualBuffer
49
+ def initialize
50
+ @writer = java.io.StringWriter.new
51
+ @buf = HTMLEscapingWriter.new(@writer)
52
+ end
53
+
54
+ def writeSafe(code)
55
+ @buf.writeSafe(code)
56
+ end
57
+ alias :writeSafe= :writeSafe
58
+ alias :append= :writeSafe
59
+ alias :concat :writeSafe
60
+ alias :<< :writeSafe
61
+
62
+ def write(code)
63
+ @buf.write(code)
64
+ end
65
+ alias :write= :write
66
+ alias :safe_append= :write
67
+ alias :safe_concat :write
68
+
69
+ def to_s
70
+ @writer.to_s
71
+ end
72
+
73
+ def close
74
+ @writer.close
75
+ end
76
+
77
+ def presence
78
+ @writer.to_s.html_safe
79
+ end
80
+ end
81
+
82
+ class ContextualEruby < Eruby
83
+ include ContextualEscapeEnhancer
84
+
85
+ def add_preamble(src)
86
+ src << "#{@bufvar} = Erubis::ContextualBuffer.new; "
87
+ end
88
+
89
+ def add_postamble(src)
90
+ src << "\n" unless src[-1] == ?\n
91
+ src << "#{@bufvar}.close\n"
92
+ src << "#{@bufvar}.to_s\n"
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,94 @@
1
+ module ActionView
2
+ class Template
3
+ module Handlers
4
+
5
+ # class Erubis < ::Erubis::Eruby
6
+ # def add_preamble(src)
7
+ # src << "@output_buffer = output_buffer || ActionView::OutputBuffer.new;"
8
+ # end
9
+ #
10
+ # def add_text(src, text)
11
+ # return if text.empty?
12
+ # p [:add_text, :safe_concat, text]
13
+ # src << "@output_buffer.safe_concat('" << escape_text(text) << "');"
14
+ # end
15
+ #
16
+ # BLOCK_EXPR = /\s+(do|\{)(\s*\|[^|]*\|)?\s*\Z/
17
+ #
18
+ # def add_expr_literal(src, code)
19
+ # if code =~ BLOCK_EXPR
20
+ # p [:add_expr_literal, :block_append=, code]
21
+ #
22
+ # src << '@output_buffer.append= ' << code
23
+ # else
24
+ # p [:add_expr_literal, :append=, code]
25
+ #
26
+ # src << '@output_buffer.append= (' << code << ');'
27
+ # end
28
+ # end
29
+ #
30
+ # def add_expr_escaped(src, code)
31
+ # if code =~ BLOCK_EXPR
32
+ # p [:add_expr_escaped, :safe_append=, code]
33
+ #
34
+ # src << "@output_buffer.safe_append= " << code
35
+ # else
36
+ # p [:add_expr_escaped, :safe_concat, code]
37
+ # src << "@output_buffer.safe_concat((" << code << ").to_s);"
38
+ # end
39
+ # end
40
+ #
41
+ # def add_postamble(src)
42
+ # src << '@output_buffer.to_s'
43
+ # end
44
+ # end
45
+
46
+ class SafeErubis < ::Erubis::Eruby
47
+ BLOCK_EXPR = /\s+(do|\{)(\s*\|[^|]*\|)?\s*\Z/
48
+
49
+ def add_preamble(src)
50
+ src << "@output_buffer = output_buffer || Erubis::ContextualBuffer.new; "
51
+ end
52
+
53
+ def add_text(src, text)
54
+ if !text.empty?
55
+ src << "@output_buffer.concat('" << text.to_s.gsub("'", "\\\\'") << "');"
56
+ end
57
+ end
58
+
59
+ def add_expr_literal(src, code)
60
+ if code =~ BLOCK_EXPR
61
+ src << '@output_buffer.append= ' << code
62
+ else
63
+ src << <<-SRC
64
+ val = (#{code.to_s});
65
+ if (val.html_safe?);
66
+ @output_buffer.append=(val);
67
+ else;
68
+ @output_buffer.safe_append=(val);
69
+ end;
70
+ SRC
71
+ end
72
+ end
73
+
74
+ def add_expr_escaped(src, code)
75
+ if code =~ BLOCK_EXPR
76
+ src << "@output_buffer.append= " << code
77
+ else
78
+ src << "@output_buffer.append(" << code << ");"
79
+ end
80
+ end
81
+
82
+ def add_postamble(src)
83
+ src << "@output_buffer.close \n"
84
+ # src << "p [:CONTEXTUAL,@output_buffer, @output_buffer.to_s, @output_buffer.to_s.html_safe.html_safe?]\n"
85
+ src << "@output_buffer.to_s.html_safe"
86
+ end
87
+ end
88
+
89
+ ERB.erb_implementation = SafeErubis
90
+ ActionView::OutputBuffer = ::Erubis::ContextualBuffer
91
+
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,3 @@
1
+ module Contextual
2
+ VERSION = "0.0.1"
3
+ end
Binary file
Binary file
@@ -0,0 +1,70 @@
1
+ require "contextual"
2
+
3
+ TEMPLATE = <<-eos
4
+ <% def helper(obj); "Hello, \#{obj['world']}"; end %>
5
+
6
+ <div style="color: <%= object['color'] %>">
7
+ <a href="/<%= object['color'] %>?q=<%= object['world'] %>" onclick="alert('<%= helper(object) %>');return false"><%= helper(object) %></a>
8
+ <script>(function () { // Sleepy developers put sensitive info in comments.
9
+ var o = <%= object %>,
10
+ w = "<%= object['world'] %>";
11
+ })();</script>
12
+ </div>
13
+ eos
14
+
15
+ EXPECTED = <<-eos
16
+
17
+ <div style="color: blue">
18
+ <a href="/blue?q=%3cCincinnati%3e" onclick="alert('Hello, \\x3cCincinnati\\x3e');return false">Hello, &lt;Cincinnati&gt;</a>
19
+ <script>(function () {
20
+ var o = {'world':'\\x3cCincinnati\\x3e','color':'blue'},
21
+ w = "\\x3cCincinnati\\x3e";
22
+ })();</script>
23
+ </div>
24
+ eos
25
+
26
+ describe Contextual do
27
+
28
+ it "should escape unsafe content" do
29
+ t = Erubis::ContextualEruby.new(" \
30
+ <% elements.each do |e| %> \
31
+ <%= e %> \
32
+ <% end %> \
33
+ ")
34
+
35
+ elements = ['<script>', '&bar', 'style="test"']
36
+ res = t.result(binding())
37
+
38
+ res.should match('&lt;script&gt;')
39
+ res.should match('&amp;bar')
40
+ res.should match('style=&#34;test&#34;')
41
+ end
42
+
43
+ it "should preserve safe content" do
44
+ t = Erubis::ContextualEruby.new("<ul><%= '<script>' %></ul>")
45
+ t.result.should match('<ul>&lt;script&gt;</ul>')
46
+ end
47
+
48
+ it "should allow explicit safe content" do
49
+ t = Erubis::ContextualEruby.new("<ul><%== '<script>' %></ul>")
50
+ t.result.should match('<ul><script></ul>')
51
+ end
52
+
53
+ it "should skip comments" do
54
+ t = Erubis::ContextualEruby.new("<%# some comment %>")
55
+ t.result.should be_empty
56
+ end
57
+
58
+ it "should render contextual template" do
59
+ object = {"world" => "<Cincinnati>", "color" => "blue"}
60
+ template = Erubis::ContextualEruby.new(TEMPLATE)
61
+ res = template.result(binding())
62
+
63
+ # don't worry about trailing whitespace
64
+ res = res.split("\n").map {|r| r.strip}
65
+ exp = EXPECTED.split("\n").map {|r| r.strip}
66
+
67
+ res.should == exp
68
+ end
69
+
70
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: contextual
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: java
7
+ authors:
8
+ - Ilya Grigorik
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &2152973440 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *2152973440
25
+ description: Runtime contextual autoescaper
26
+ email:
27
+ - ilya@igvita.com
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - .gitignore
33
+ - .rspec
34
+ - Gemfile
35
+ - README.md
36
+ - Rakefile
37
+ - contextual.gemspec
38
+ - lib/contextual.rb
39
+ - lib/contextual/contextual.rb
40
+ - lib/contextual/rails_erubis.rb
41
+ - lib/contextual/version.rb
42
+ - lib/ext/autoesc.jar
43
+ - lib/ext/guava.jar
44
+ - spec/contextual_spec.rb
45
+ homepage: https://github.com/igrigorik/contextual
46
+ licenses: []
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubyforge_project: contextual
65
+ rubygems_version: 1.8.10
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: Runtime contextual autoescaper
69
+ test_files:
70
+ - spec/contextual_spec.rb
71
+ has_rdoc: