roda 2.12.0 → 2.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +4 -0
- data/README.rdoc +21 -30
- data/Rakefile +1 -1
- data/doc/release_notes/2.13.0.txt +10 -0
- data/lib/roda/plugins/render.rb +14 -1
- data/lib/roda/version.rb +1 -1
- data/spec/plugin/render_spec.rb +57 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f3983563024d2c3f03d3a9edcf291f9a6f128ee
|
4
|
+
data.tar.gz: 4ac86dfd93b62b8e4f79f19788cf9dbd110df8f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 807d5d4fcc03d18823d045b18cb8cf6ce532ea8501254c2f0ce7f245742e4ea6495e399c0e33ae1f7939726b0cb511bc7cc0d9620ec5d19099df86523d9c9847
|
7
|
+
data.tar.gz: cc40d28a3152b29755e7949304a4b3bd3a83147ce3975fe0fba829c332641651134727157726425da90feec610f8acfa6b1efd6ba5e8362c14ba97fb2dfe93a9
|
data/CHANGELOG
CHANGED
data/README.rdoc
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
= Roda
|
2
2
|
|
3
|
-
Roda is a routing tree web
|
3
|
+
Roda is a routing tree web toolkit, designed for building fast and
|
4
|
+
maintainable web applications in ruby.
|
4
5
|
|
5
6
|
= Installation
|
6
7
|
|
@@ -29,9 +30,8 @@ code.
|
|
29
30
|
|
30
31
|
=== Reliability
|
31
32
|
|
32
|
-
Roda
|
33
|
-
|
34
|
-
in production, which eliminates possible thread safety issues.
|
33
|
+
Roda supports and encourages immutability. Roda apps are designed
|
34
|
+
to be frozen in production, which eliminates possible thread safety issues.
|
35
35
|
Additionally, Roda limits the instance variables, constants, and
|
36
36
|
methods that it uses, so that they do not conflict with the ones
|
37
37
|
you use for your application.
|
@@ -45,8 +45,8 @@ to get the default behavior.
|
|
45
45
|
=== Performance
|
46
46
|
|
47
47
|
Roda has low per-request overhead, and the use of a routing tree
|
48
|
-
and intelligent caching of internal datastructures makes it
|
49
|
-
|
48
|
+
and intelligent caching of internal datastructures makes it
|
49
|
+
significantly faster than popular ruby web frameworks.
|
50
50
|
|
51
51
|
== Usage
|
52
52
|
|
@@ -143,7 +143,7 @@ The +.app+ is an optimization, which saves a few method calls for every request.
|
|
143
143
|
|
144
144
|
== The Routing Tree
|
145
145
|
|
146
|
-
Roda is called a routing tree web
|
146
|
+
Roda is called a routing tree web toolkit because the way most sites are structured,
|
147
147
|
routing takes the form of a tree (based on the URL structure of the site).
|
148
148
|
In general:
|
149
149
|
|
@@ -211,8 +211,7 @@ you can easily handle this in the routing tree:
|
|
211
211
|
end
|
212
212
|
|
213
213
|
Being able to operate on the request at any point during the routing
|
214
|
-
is one of the major advantages of Roda
|
215
|
-
that do not use a routing tree.
|
214
|
+
is one of the major advantages of Roda.
|
216
215
|
|
217
216
|
== Matchers
|
218
217
|
|
@@ -784,10 +783,10 @@ Example:
|
|
784
783
|
|
785
784
|
=== Rendering Templates Derived From User Input
|
786
785
|
|
787
|
-
Roda's rendering plugin assumes that template paths given to it are trusted
|
788
|
-
to the +render+/+view+ methods that is derived from user input, you
|
789
|
-
for people rendering arbitrary files on the system that that have a
|
790
|
-
default template extension. For example, if you do:
|
786
|
+
Roda's rendering plugin assumes that template paths given to it are trusted by default.
|
787
|
+
If you provide a path to the +render+/+view+ methods that is derived from user input, you
|
788
|
+
are opening yourself for people rendering arbitrary files on the system that that have a
|
789
|
+
file name ending in the default template extension. For example, if you do:
|
791
790
|
|
792
791
|
class App < Roda
|
793
792
|
plugin :render
|
@@ -801,18 +800,14 @@ to render the <tt>/tmp/upload.erb</tt> file. If you have another part of your s
|
|
801
800
|
allows users to create files with arbitrary extensions (even temporary files), then it may
|
802
801
|
be possible to combine these two issues into a remote code execution exploit.
|
803
802
|
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
view(page)
|
813
|
-
end
|
814
|
-
end
|
815
|
-
end
|
803
|
+
To mitigate against this issue, you can use the <tt>:check_paths => true</tt> render
|
804
|
+
option, which will check that the full path of the template to be rendered begins with the
|
805
|
+
+:views+ directory, and raises an exception if not. You can also use the +:allowed_paths+
|
806
|
+
render option to specify which paths are allowed. While
|
807
|
+
<tt>:check_paths => true</tt> is not currently the default, it will become the default in
|
808
|
+
Roda 3. Note that when specifying the +:path+ option when rendering a template, Roda will
|
809
|
+
not check paths, as it assumes that users and libraries that use this option will be checking
|
810
|
+
such paths manually.
|
816
811
|
|
817
812
|
== Reloading
|
818
813
|
|
@@ -828,9 +823,6 @@ Most rack-based reloaders will work with Roda, including:
|
|
828
823
|
|
829
824
|
By design, Roda has a very small core, providing only the essentials.
|
830
825
|
All nonessential features are added via plugins.
|
831
|
-
This is why Roda is referred to as a routing tree web framework toolkit.
|
832
|
-
Using a combination of Roda plugins,
|
833
|
-
you can build the routing tree web framework that suits your needs.
|
834
826
|
|
835
827
|
Roda's plugins can override any Roda method and call +super+
|
836
828
|
to get the default behavior, which makes Roda very extensible.
|
@@ -921,8 +913,7 @@ you can then introspect.
|
|
921
913
|
|
922
914
|
== Inspiration
|
923
915
|
|
924
|
-
Roda was inspired by {Sinatra}[http://www.sinatrarb.com] and {Cuba}[http://cuba.is]
|
925
|
-
two other Ruby web frameworks.
|
916
|
+
Roda was inspired by {Sinatra}[http://www.sinatrarb.com] and {Cuba}[http://cuba.is].
|
926
917
|
It started out as a fork of Cuba, from which it borrows the idea of using a routing tree
|
927
918
|
(which Cuba in turn took from {Rum}[https://github.com/chneukirchen/rum]).
|
928
919
|
From Sinatra, it takes the ideas that route blocks should return the request bodies
|
data/Rakefile
CHANGED
@@ -17,7 +17,7 @@ end
|
|
17
17
|
|
18
18
|
### RDoc
|
19
19
|
|
20
|
-
RDOC_DEFAULT_OPTS = ["--line-numbers", "--inline-source", '--title', 'Roda: Routing tree web
|
20
|
+
RDOC_DEFAULT_OPTS = ["--line-numbers", "--inline-source", '--title', 'Roda: Routing tree web toolkit']
|
21
21
|
|
22
22
|
begin
|
23
23
|
gem 'hanna-nouveau'
|
@@ -0,0 +1,10 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* The render plugin now supports :check_paths and :allowed_paths
|
4
|
+
options. Setting :check_paths to true will turn on path checking of
|
5
|
+
template files. By default, template files are required to be in
|
6
|
+
the :views directory, otherwise an exception will be raised. Using
|
7
|
+
the :check_paths option can prevent security issues when template
|
8
|
+
names are derived from user input. The :allowed_paths option
|
9
|
+
overrides which path prefixes are allowed. In Roda 3, :check_paths
|
10
|
+
will default to true.
|
data/lib/roda/plugins/render.rb
CHANGED
@@ -28,10 +28,14 @@ class Roda
|
|
28
28
|
#
|
29
29
|
# The following plugin options are supported:
|
30
30
|
#
|
31
|
+
# :allowed_paths :: Set the template paths to allow if +:check_paths+ is true.
|
32
|
+
# Defaults to the +:views+ directory.
|
31
33
|
# :cache :: nil/false to not cache templates (useful for development), defaults
|
32
34
|
# to true unless RACK_ENV is development to automatically use the
|
33
35
|
# default template cache.
|
34
36
|
# :cache_class :: A class to use as the template cache instead of the default.
|
37
|
+
# :check_paths :: Check template paths start with one of the entries in +:allowed_paths+,
|
38
|
+
# and raise a RodaError if the path doesn't.
|
35
39
|
# :engine :: The tilt engine to use for rendering, also the default file extension for
|
36
40
|
# templates, defaults to 'erb'.
|
37
41
|
# :escape :: Use Roda's Erubis escaping support, which makes <tt><%= %></tt> escape output,
|
@@ -137,6 +141,8 @@ class Roda
|
|
137
141
|
opts = app.opts[:render]
|
138
142
|
opts[:engine] = (opts[:engine] || opts[:ext] || "erb").dup.freeze
|
139
143
|
opts[:views] = File.expand_path(opts[:views]||"views", app.opts[:root]).freeze
|
144
|
+
opts[:allowed_paths] ||= [opts[:views]].freeze
|
145
|
+
opts[:allowed_paths] = opts[:allowed_paths].map{|f| ::File.expand_path(f)}.uniq.freeze
|
140
146
|
|
141
147
|
if opts.fetch(:cache, ENV['RACK_ENV'] != 'development')
|
142
148
|
if cache_class = opts[:cache_class]
|
@@ -352,7 +358,14 @@ class Roda
|
|
352
358
|
|
353
359
|
# The template path for the given options.
|
354
360
|
def template_path(opts)
|
355
|
-
"#{opts[:views]}/#{template_name(opts)}.#{opts[:engine]}"
|
361
|
+
path = "#{opts[:views]}/#{template_name(opts)}.#{opts[:engine]}"
|
362
|
+
if opts.fetch(:check_paths){render_opts[:check_paths]}
|
363
|
+
full_path = ::File.expand_path(path)
|
364
|
+
unless render_opts[:allowed_paths].any?{|f| full_path.start_with?(f)}
|
365
|
+
raise RodaError, "attempt to render path not in allowed_paths: #{path} (allowed: #{render_opts[:allowed_paths].join(', ')})"
|
366
|
+
end
|
367
|
+
end
|
368
|
+
path
|
356
369
|
end
|
357
370
|
|
358
371
|
# If a layout should be used, return a hash of options for
|
data/lib/roda/version.rb
CHANGED
data/spec/plugin/render_spec.rb
CHANGED
@@ -9,7 +9,7 @@ else
|
|
9
9
|
describe "render plugin" do
|
10
10
|
before do
|
11
11
|
app(:bare) do
|
12
|
-
plugin :render, :views=>"./spec/views"
|
12
|
+
plugin :render, :views=>"./spec/views", :check_paths=>true
|
13
13
|
|
14
14
|
route do |r|
|
15
15
|
r.on "home" do
|
@@ -437,6 +437,62 @@ describe "render plugin" do
|
|
437
437
|
|
438
438
|
Class.new(app).render_opts[:cache].must_equal false
|
439
439
|
end
|
440
|
+
|
441
|
+
it "with :check_paths=>true" do
|
442
|
+
render_opts = {}
|
443
|
+
app(:bare) do
|
444
|
+
plugin :render, :views=>"./spec/views", :check_paths=>true
|
445
|
+
|
446
|
+
route do |r|
|
447
|
+
r.get 'a' do
|
448
|
+
render("a", render_opts)
|
449
|
+
end
|
450
|
+
|
451
|
+
r.get 'c' do
|
452
|
+
render("about/_test", :locals=>{:title=>'a'})
|
453
|
+
end
|
454
|
+
|
455
|
+
render("b", render_opts)
|
456
|
+
end
|
457
|
+
end
|
458
|
+
|
459
|
+
body.strip.must_equal "b"
|
460
|
+
req("/a")
|
461
|
+
req("/c")
|
462
|
+
|
463
|
+
app.plugin :render, :allowed_paths=>[]
|
464
|
+
proc{req}.must_raise Roda::RodaError
|
465
|
+
proc{req("/a")}.must_raise Roda::RodaError
|
466
|
+
proc{req("/c")}.must_raise Roda::RodaError
|
467
|
+
|
468
|
+
app.plugin :render, :allowed_paths=>['spec/views/about']
|
469
|
+
proc{req}.must_raise Roda::RodaError
|
470
|
+
proc{req("/a")}.must_raise Roda::RodaError
|
471
|
+
req("/c")
|
472
|
+
|
473
|
+
app.plugin :render, :allowed_paths=>%w'spec/views/about spec/views/b'
|
474
|
+
body.strip.must_equal "b"
|
475
|
+
proc{req("/a")}.must_raise Roda::RodaError
|
476
|
+
req("/c")
|
477
|
+
|
478
|
+
render_opts[:check_paths] = true
|
479
|
+
app.plugin :render, :check_paths=>false
|
480
|
+
body.strip.must_equal "b"
|
481
|
+
proc{req("/a")}.must_raise Roda::RodaError
|
482
|
+
req("/c")
|
483
|
+
|
484
|
+
render_opts.delete(:check_paths)
|
485
|
+
app.plugin :render
|
486
|
+
body.strip.must_equal "b"
|
487
|
+
req("/a")
|
488
|
+
req("/c")
|
489
|
+
|
490
|
+
render_opts[:check_paths] = true
|
491
|
+
body.strip.must_equal "b"
|
492
|
+
proc{req("/a")}.must_raise Roda::RodaError
|
493
|
+
req("/c")
|
494
|
+
end
|
495
|
+
|
440
496
|
it "with a cache_class set" do
|
441
497
|
app(:bare) do
|
442
498
|
test_cache = Class.new(Roda::RodaCache) do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: roda
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Evans
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-04-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -178,6 +178,7 @@ extra_rdoc_files:
|
|
178
178
|
- doc/release_notes/2.10.0.txt
|
179
179
|
- doc/release_notes/2.11.0.txt
|
180
180
|
- doc/release_notes/2.12.0.txt
|
181
|
+
- doc/release_notes/2.13.0.txt
|
181
182
|
files:
|
182
183
|
- CHANGELOG
|
183
184
|
- MIT-LICENSE
|
@@ -193,6 +194,7 @@ files:
|
|
193
194
|
- doc/release_notes/2.10.0.txt
|
194
195
|
- doc/release_notes/2.11.0.txt
|
195
196
|
- doc/release_notes/2.12.0.txt
|
197
|
+
- doc/release_notes/2.13.0.txt
|
196
198
|
- doc/release_notes/2.2.0.txt
|
197
199
|
- doc/release_notes/2.3.0.txt
|
198
200
|
- doc/release_notes/2.4.0.txt
|
@@ -394,5 +396,5 @@ rubyforge_project:
|
|
394
396
|
rubygems_version: 2.5.1
|
395
397
|
signing_key:
|
396
398
|
specification_version: 4
|
397
|
-
summary: Routing tree web
|
399
|
+
summary: Routing tree web toolkit
|
398
400
|
test_files: []
|