wunderbar 1.3.4 → 1.4.0

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
  SHA256:
3
- metadata.gz: faf3ed56159ea9aae14376907dd0c17efabb7560f08b886b1f4f781be5b630af
4
- data.tar.gz: f0a40ec22da2f77faf6b97c6a156198430a4afe12d96baacd37c8c489bcc037b
3
+ metadata.gz: 01faf4f44e9f567cf1ab080f8f4a54879c0eb6b5d07e0ad6d265ede2cbd4b86f
4
+ data.tar.gz: a0db8a63944a68305a337a1eb5cef8114f5f88034e7a9c451cd37228ad97bc40
5
5
  SHA512:
6
- metadata.gz: fba3b4c3676b35938fc132792a5fb8d73ea949fe3d76b9a4a05a2b83a2d24e3b933ce993b45e36717dc9877c8a2a429af80dceab4313dfaa3ef8eb63cdba4380
7
- data.tar.gz: f9d3f47d1f81627649f98ebfeda570f84dadb9f33e9839a06584f31c52da587b98ca9be027f411a805f82c09979bb96e92882be0a8907dd743193fbf4c51f8ee
6
+ metadata.gz: d104318bd2e0e2ee9cd721c3b49790ede15b4459dbe253bc58b9108b6fc91fcb077e932a399b9194417a5dc31c62500684db424db534b4b72c1c709e2defedc1
7
+ data.tar.gz: e2d9ca6b2bec1fdb12a253e1ca9df2f73296388c60ee2b165c63305216a353fc0fe37e3ede10c48b6524b7391e060230ca53fa8f393b4d24b957f225da3363a2
data/README.md CHANGED
@@ -366,26 +366,7 @@ Secure by default
366
366
 
367
367
  Wunderbar will properly escape all HTML and JSON output, eliminating problems
368
368
  of HTML or JavaScript injection. This includes calls to `_` to insert text
369
- directly. Unless `nokogiri` was previously required (see [optional
370
- dependencies](#optional-dependencies) below), calls to insert markup
371
- (`_{...}`) will escape the markup if the input is `tainted` and not explicitly
372
- marked as `html-safe?` (when using Rails).
373
-
374
- For Ruby version < 2.6.0:
375
-
376
- > For all environments other than Rails, unless you call `Wunderbar.unsafe!` at
377
- > the top of your script, Wunderbar will also set
378
- > [`$SAFE=1`](http://www.ruby-doc.org/docs/ProgrammingRuby/html/taint.html)
379
- > before processing requests. This means that you will need to
380
- > [`untaint`](ruby-doc.org/core/Object.html#method-i-untaint) all inputs
381
- > received from external sources before you make system calls or access the file
382
- > system.
383
-
384
- A special feature that effectively is only available in the Rails environment:
385
- if the first argument to call that creates an element is `html_safe?`, then
386
- that argument will be treated as a markup instead of as text. This allows one
387
- to make calls like `_td link_to...` without placing the call to `link_to` in a
388
- block.
369
+ directly.
389
370
 
390
371
  Globals provided
391
372
  ---
@@ -454,7 +435,6 @@ The following gems, if installed, will produce cleaner and prettier output:
454
435
  * `nokogumbo` also cleans up HTML fragments inserted via `<<` and `_{}`. If
455
436
  this gem is available, it will be preferred over direct usage of `nokogiri`.
456
437
  * `escape` prettier quoting of `system` commands
457
- * `sanitize` will remove unsafe markup from tainted input
458
438
 
459
439
  Related efforts
460
440
  ---
@@ -30,14 +30,14 @@ module Wunderbar
30
30
  return @path if @path or @contents
31
31
 
32
32
  if @options[:name]
33
- source = (@options[:file] || __FILE__).untaint
33
+ source = @options[:file] || __FILE__
34
34
  @mtime = File.mtime(source)
35
35
  @path = @options[:name]
36
36
 
37
37
  # look for asset in site
38
38
  if ENV['DOCUMENT_ROOT']
39
- root = File.join(ENV['DOCUMENT_ROOT'], 'assets').untaint
40
- dest = File.expand_path(@path, root).untaint
39
+ root = File.join(ENV['DOCUMENT_ROOT'], 'assets')
40
+ dest = File.expand_path(@path, root)
41
41
  if File.exist?(dest) and File.size(dest) == File.size(source)
42
42
  @path = "/assets/#{@path}"
43
43
  return @path
@@ -45,7 +45,7 @@ module Wunderbar
45
45
  end
46
46
 
47
47
  # look for asset in app
48
- dest = File.expand_path(@path, Asset.root).untaint
48
+ dest = File.expand_path(@path, Asset.root)
49
49
  if File.exist?(dest) and File.size(dest) == File.size(source)
50
50
  return @path
51
51
  end
@@ -103,7 +103,7 @@ module Wunderbar
103
103
  @path = '../' * env['PATH_INFO'].to_s.count('/') + 'assets'
104
104
  @root ||= nil
105
105
  @root = File.dirname(env['SCRIPT_FILENAME']) if env['SCRIPT_FILENAME']
106
- @root = File.expand_path((@root || Dir.pwd) + "/assets").untaint
106
+ @root = File.expand_path((@root || Dir.pwd) + "/assets")
107
107
 
108
108
  # Options: typically :name plus either :file or :contents
109
109
  # :name => name to be used for the asset
@@ -51,14 +51,14 @@ module Wunderbar
51
51
  secret = command - flat
52
52
  begin
53
53
  # if available, use escape as it does prettier quoting
54
- raise LoadError if $SAFE > 0 and not defined? Escape
54
+ raise LoadError if not defined? Escape
55
55
  require 'escape'
56
56
  echo = Escape.shell_command(command.compact - secret)
57
57
  rescue LoadError
58
58
  # std-lib function that gets the job done
59
59
  echo = Shellwords.join(command.compact - secret)
60
60
  end
61
- command = flat.compact.map(&:dup).map(&:untaint)
61
+ command = flat.compact
62
62
  else
63
63
  echo = command
64
64
  command = [command]
@@ -120,7 +120,7 @@ module Wunderbar
120
120
  # asset support for Rack
121
121
  request = (scope.respond_to? :request) ? scope.request : nil
122
122
  if request and request.path =~ %r{/assets/\w[-.\w]+}
123
- path = ('.' + scope.request.path).untaint
123
+ path = '.' + scope.request.path
124
124
  headers = {'type' => 'text/plain'}
125
125
  headers['type'] = 'application/javascript' if path =~ /\.js$/
126
126
  out?(scope, headers) { File.read path if File.exist? path }
@@ -2,15 +2,6 @@ require 'wunderbar'
2
2
  require 'coderay'
3
3
  require 'nokogiri'
4
4
 
5
- # workaround for https://github.com/rubychan/coderay/pull/159
6
- module CodeRay::PluginHost
7
- alias_method :old_plugin_path, :plugin_path
8
- def plugin_path *args
9
- args.first.untaint if args.first == CodeRay::CODERAY_PATH
10
- old_plugin_path(*args)
11
- end
12
- end
13
-
14
5
  module Wunderbar
15
6
  class HtmlMarkup
16
7
  def _coderay(*args)
@@ -5,40 +5,6 @@ module Wunderbar
5
5
  TEXT = ARGV.delete('--text')
6
6
  end
7
7
 
8
- # Ruby 2.6.0 gets rid of $SAFE > 1; unfortunately in the process it
9
- # treats $SAFE = 1 as a higher level; @FAFE = 1 no longer is limited
10
- # to taintness checks, it not treats all File operations as unsafe
11
- @@unsafe = (RUBY_VERSION.split('.').map(&:to_i) <=> [2, 6, 0]) == 1
12
-
13
- def self.unsafe!(mode=true)
14
- @@unsafe=mode
15
- end
16
-
17
- def self.safe?
18
- if not @@unsafe and $SAFE == 0
19
- # some gems (e.g. em-websocket-0.3.6) insert unsafe entries into the
20
- # path, and that prevents requires from succeeding. If it looks like
21
- # we are about to make a transition to $SAFE=1, clean up that mess
22
- # before proceeding.
23
- #
24
- # the goal of $SAFE is not to protect us against software which was
25
- # installed by the owner of the site, but from injection attacks
26
- # contained within data provided by users of the site.
27
- $:.each_with_index do |path, index|
28
- if path.tainted?
29
- $:[index] = File.expand_path(path.dup.untaint).untaint
30
- end
31
- end
32
-
33
- # avoid: "Insecure PATH - (SecurityError)" when using Bundler
34
- if defined? Bundler
35
- ENV['PATH'] = ENV['PATH'].dup.untaint
36
- end
37
- end
38
-
39
- not @@unsafe
40
- end
41
-
42
8
  class Scope
43
9
  attr_accessor :env
44
10
  def initialize(env)
@@ -133,7 +133,7 @@ module Wunderbar
133
133
  # * Proxied Rack server. Document base may be relate to the
134
134
  # HTTP_X_WUNDERBAR_BASE
135
135
  #
136
- cwd = File.realpath(Dir.pwd.untaint)
136
+ cwd = File.realpath(Dir.pwd)
137
137
  base = @_scope.env['DOCUMENT_ROOT'] if @_scope.env.respond_to? :[]
138
138
  base ||= cwd
139
139
  href = (head.children[1].attrs[:href] || '')
@@ -189,8 +189,8 @@ module Wunderbar
189
189
  name = name.to_s.gsub('_', '-')
190
190
 
191
191
  if flag != '!'
192
- if String === args.first and args.first.respond_to? :html_safe?
193
- if args.first.html_safe? and not block and args.first =~ /[>&]/
192
+ if String === args.first
193
+ if not block and args.first =~ /[>&]/
194
194
  markup = args.shift
195
195
  block = Proc.new {_ {markup}}
196
196
  end
@@ -362,11 +362,7 @@ module Wunderbar
362
362
  def _(text=nil, &block)
363
363
  unless block
364
364
  if text
365
- if text.respond_to? :html_safe? and text.html_safe?
366
- _ {text}
367
- else
368
- @_x.indented_text! text.to_s
369
- end
365
+ _ {text}
370
366
  end
371
367
  return @_x
372
368
  end
@@ -374,20 +370,13 @@ module Wunderbar
374
370
  children = instance_eval(&block)
375
371
 
376
372
  if String === children
377
- safe = !children.tainted?
378
- safe ||= children.html_safe? if children.respond_to? :html_safe?
379
- safe &&= defined? Nokogiri
380
- ok = safe || defined? Sanitize
381
- safe = true
382
-
383
- if ok and (children.include? '<' or children.include? '&')
373
+ if children.include? '<' or children.include? '&'
384
374
  if defined? Nokogiri::HTML5.fragment
385
375
  doc = Nokogiri::HTML5.fragment(children.to_s)
386
376
  else
387
377
  doc = Nokogiri::HTML.fragment(children.to_s)
388
378
  end
389
379
 
390
- Sanitize.new.clean_node! doc.dup.untaint if not safe
391
380
  children = doc.children.to_a
392
381
 
393
382
  # ignore leading whitespace
@@ -25,7 +25,7 @@ module Wunderbar
25
25
  # clear environment of cgi cruft
26
26
  require 'cgi'
27
27
  ENV.keys.select {|key| key =~ /^HTTP_/}.each do |key|
28
- ENV.delete key.dup.untaint
28
+ ENV.delete key
29
29
  end
30
30
  ::CGI::QueryExtension.public_instance_methods.each do |method|
31
31
  ENV.delete method.to_s.upcase
@@ -17,8 +17,6 @@ module Wunderbar
17
17
  Rack::Mime::MIME_TYPES[File.extname(env['PATH_INFO'])]
18
18
  @_response.set_header('Content-Type', mime) if mime
19
19
  @_response.write(file[:content] || file[:source].call)
20
- elsif Wunderbar.safe? and $SAFE==0
21
- Proc.new { $SAFE=1; Wunderbar::CGI.call(self) }.call
22
20
  else
23
21
  Wunderbar::CGI.call(self)
24
22
  end
@@ -35,17 +35,3 @@ class Wunderbar::Render
35
35
  "</pre>"
36
36
  end
37
37
  end
38
-
39
- # Monkeypatch to address https://github.com/sstephenson/execjs/pull/180
40
- require 'execjs'
41
- class ExecJS::ExternalRuntime::Context
42
- alias_method :w_write_to_tempfile, :write_to_tempfile
43
- def write_to_tempfile(*args)
44
- tmpfile = w_write_to_tempfile(*args).path.untaint
45
- tmpfile = Struct.new(:path, :to_str).new(tmpfile, tmpfile)
46
- def tmpfile.unlink
47
- File.unlink path
48
- end
49
- tmpfile
50
- end
51
- end
@@ -82,14 +82,12 @@ class Wunderbar::XmlMarkup
82
82
 
83
83
  src = File.join(base, src) if not base.empty?
84
84
  src = src.sub(/\?.*$/, '') # strip queries (typically mtimes)
85
- src.untaint
86
85
 
87
- name = File.expand_path(src, @_scope.settings.public_folder.untaint)
88
- name.untaint unless src.tainted?
86
+ name = File.expand_path(src, @_scope.settings.public_folder)
89
87
  if File.exist? name
90
88
  result = File.read(name)
91
89
  else
92
- file = File.expand_path(src+'.rb', @_scope.settings.views.untaint)
90
+ file = File.expand_path(src+'.rb', @_scope.settings.views)
93
91
  result = Wunderbar::Asset.convert(file)
94
92
  end
95
93
  else
@@ -113,11 +111,11 @@ class Wunderbar::XmlMarkup
113
111
  scripts.unshift script.contents
114
112
  elsif script.path
115
113
  if script.path.start_with? '/'
116
- path = (ENV['DOCUMENT_ROOT'] + script.path).untaint
114
+ path = ENV['DOCUMENT_ROOT'] + script.path
117
115
  else
118
- path = File.expand_path(script.path, Wunderbar::Asset.root).untaint
116
+ path = File.expand_path(script.path, Wunderbar::Asset.root)
119
117
  end
120
- setup << File.read(script.options[:server].untaint || path)
118
+ setup << File.read(script.options[:server] || path)
121
119
  end
122
120
  end
123
121
 
@@ -82,22 +82,14 @@ module Wunderbar
82
82
  builder.set_variables_from_params(locals)
83
83
 
84
84
  if not block
85
- builder.instance_eval(data.untaint, eval_file)
85
+ builder.instance_eval(data, eval_file)
86
86
  elsif not data
87
87
  builder.instance_eval(&block)
88
88
  else
89
89
  context = builder.get_binding do
90
90
  builder.instance_eval {_(&block)}
91
91
  end
92
- context.eval(data.untaint, eval_file)
93
- end
94
- end
95
-
96
- def _evaluate_safely(*args, &block)
97
- if Wunderbar.safe? and $SAFE==0
98
- Proc.new { $SAFE=1; _evaluate(*args, &block) }.call
99
- else
100
- _evaluate(*args, &block)
92
+ context.eval(data, eval_file)
101
93
  end
102
94
  end
103
95
  end
@@ -108,7 +100,7 @@ module Wunderbar
108
100
  def evaluate(scope, locals, &block)
109
101
  builder = HtmlMarkup.new(scope)
110
102
  begin
111
- _evaluate_safely(builder, scope, locals, &block)
103
+ _evaluate(builder, scope, locals, &block)
112
104
  rescue Exception => exception
113
105
  scope.response.status = Wunderbar::ServerError.status
114
106
  builder.clear!
@@ -132,7 +124,7 @@ module Wunderbar
132
124
  def evaluate(scope, locals, &block)
133
125
  builder = JsonBuilder.new(scope)
134
126
  begin
135
- result = _evaluate_safely(builder, scope, locals, &block)
127
+ result = _evaluate(builder, scope, locals, &block)
136
128
 
137
129
  # if no output was produced, use the result
138
130
  builder._! result if builder.target? == {} and result
@@ -154,7 +146,7 @@ module Wunderbar
154
146
  def evaluate(scope, locals, &block)
155
147
  builder = TextBuilder.new(scope)
156
148
  begin
157
- result = _evaluate_safely(builder, scope, locals, &block)
149
+ result = _evaluate(builder, scope, locals, &block)
158
150
 
159
151
  # if no output was produced, use the result
160
152
  builder._ result.to_s if builder.target!.empty? and result
@@ -240,13 +232,12 @@ Tilt.register 'xhtml.rb', Wunderbar::Template::Xhtml
240
232
  helpers Wunderbar::SinatraHelpers
241
233
 
242
234
  if Dir.exist? settings.public_folder
243
- Wunderbar::Asset.root = File.join(settings.public_folder, 'assets').untaint
235
+ Wunderbar::Asset.root = File.join(settings.public_folder, 'assets')
244
236
  end
245
237
 
246
238
  Wunderbar::Asset.virtual = true
247
239
 
248
240
  get "/#{Wunderbar::Asset.path}/:name" do |name|
249
- name.untaint if name =~ /^([-\w]\.?)+$/
250
241
  file = "#{Wunderbar::Asset.root}/#{name}"
251
242
  _text do
252
243
  if File.exist? file
@@ -1,8 +1,8 @@
1
1
  module Wunderbar
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 1
4
- MINOR = 3
5
- TINY = 4
4
+ MINOR = 4
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -14,7 +14,7 @@ class Wunderbar::Render
14
14
  path = `which nodejs`.chomp
15
15
  path = `which node`.chomp if path.empty?
16
16
  raise RuntimeError.new('Unable to locate nodejs') if path.empty?
17
- @nodejs = path.untaint
17
+ @nodejs = path
18
18
  end
19
19
 
20
20
  def self.server(common)
@@ -50,7 +50,7 @@ class Wunderbar::Render
50
50
  stdout += "\n<pre>#{CGI.escapeHTML(stderr)}</pre>"
51
51
  end
52
52
 
53
- stdout.untaint
53
+ stdout
54
54
  rescue => e
55
55
  Wunderbar.error e
56
56
  "<pre>#{CGI.escapeHTML(e.message)}</pre>"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wunderbar
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.4
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Ruby