roda 2.12.0 → 2.13.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 +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: []
|