wunderbar 1.3.4 → 1.4.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.
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