Skip to content

Commit 388b2ab

Browse files
authored
Merge pull request github#12821 from maikypedia/maikypedia/ruby-ssti
Ruby: Add Rails `render inline:` as Template Injection Sink
2 parents 2e5a048 + 82c0250 commit 388b2ab

File tree

5 files changed

+28
-0
lines changed

5 files changed

+28
-0
lines changed

ruby/ql/lib/codeql/ruby/frameworks/Rails.qll

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,3 +400,19 @@ private class AccessLocalsKeySummary extends SummarizedCallable {
400400
preservesValue = true
401401
}
402402
}
403+
404+
/** A call to `render inline: foo`, considered as a ERB template rendering. */
405+
private class RailsTemplateRendering extends TemplateRendering::Range, DataFlow::CallNode {
406+
private DataFlow::Node template;
407+
408+
RailsTemplateRendering() {
409+
(
410+
this.asExpr().getExpr() instanceof Rails::RenderCall
411+
or
412+
this.asExpr().getExpr() instanceof Rails::RenderToCall
413+
) and
414+
template = this.getKeywordArgument("inline")
415+
}
416+
417+
override DataFlow::Node getTemplate() { result = template }
418+
}

ruby/ql/src/experimental/template-injection/examples/SSTIBad.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ def some_request_handler
99
<h2>Hello %s </h2></body></html>
1010
" % name
1111
template = ERB.new(html_text).result(binding)
12+
render inline: html_text
1213
end
1314
end
1415

ruby/ql/src/experimental/template-injection/examples/SSTIGood.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ def some_request_handler
99
<h2>Hello <%= name %> </h2></body></html>
1010
"
1111
template = ERB.new(html_text).result(binding)
12+
render inline: html_text
1213
end
1314
end
1415

ruby/ql/test/query-tests/experimental/TemplateInjection/ErbInjection.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ def some_request_handler
1414
# where name is unsanitized
1515
template = ERB.new(bad_text).result(binding)
1616

17+
# BAD: user input is evaluated
18+
# where name is unsanitized
19+
render inline: bad_text
20+
1721
# Template with the source
1822
good_text = "
1923
<!DOCTYPE html><html><body>
@@ -22,6 +26,9 @@ def some_request_handler
2226

2327
# GOOD: user input is not evaluated
2428
template2 = ERB.new(good_text).result(binding)
29+
30+
# GOOD: user input is not evaluated
31+
render inline: good_text
2532
end
2633
end
2734

ruby/ql/test/query-tests/experimental/TemplateInjection/TemplateInjection.expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ edges
44
| ErbInjection.rb:5:12:5:17 | call to params | ErbInjection.rb:5:12:5:24 | ...[...] |
55
| ErbInjection.rb:5:12:5:24 | ...[...] | ErbInjection.rb:5:5:5:8 | name |
66
| ErbInjection.rb:8:5:8:12 | bad_text | ErbInjection.rb:15:24:15:31 | bad_text |
7+
| ErbInjection.rb:8:5:8:12 | bad_text | ErbInjection.rb:19:20:19:27 | bad_text |
78
| ErbInjection.rb:8:16:11:14 | ... % ... | ErbInjection.rb:8:5:8:12 | bad_text |
89
| ErbInjection.rb:11:11:11:14 | name | ErbInjection.rb:8:16:11:14 | ... % ... |
910
| SlimInjection.rb:5:5:5:8 | name | SlimInjection.rb:8:5:8:12 | bad_text |
@@ -23,6 +24,7 @@ nodes
2324
| ErbInjection.rb:8:16:11:14 | ... % ... | semmle.label | ... % ... |
2425
| ErbInjection.rb:11:11:11:14 | name | semmle.label | name |
2526
| ErbInjection.rb:15:24:15:31 | bad_text | semmle.label | bad_text |
27+
| ErbInjection.rb:19:20:19:27 | bad_text | semmle.label | bad_text |
2628
| SlimInjection.rb:5:5:5:8 | name | semmle.label | name |
2729
| SlimInjection.rb:5:12:5:17 | call to params | semmle.label | call to params |
2830
| SlimInjection.rb:5:12:5:24 | ...[...] | semmle.label | ...[...] |
@@ -35,5 +37,6 @@ nodes
3537
subpaths
3638
#select
3739
| ErbInjection.rb:15:24:15:31 | bad_text | ErbInjection.rb:5:12:5:17 | call to params | ErbInjection.rb:15:24:15:31 | bad_text | This template depends on a $@. | ErbInjection.rb:5:12:5:17 | call to params | user-provided value |
40+
| ErbInjection.rb:19:20:19:27 | bad_text | ErbInjection.rb:5:12:5:17 | call to params | ErbInjection.rb:19:20:19:27 | bad_text | This template depends on a $@. | ErbInjection.rb:5:12:5:17 | call to params | user-provided value |
3841
| SlimInjection.rb:14:25:14:32 | bad_text | SlimInjection.rb:5:12:5:17 | call to params | SlimInjection.rb:14:25:14:32 | bad_text | This template depends on a $@. | SlimInjection.rb:5:12:5:17 | call to params | user-provided value |
3942
| SlimInjection.rb:23:25:23:33 | bad2_text | SlimInjection.rb:5:12:5:17 | call to params | SlimInjection.rb:23:25:23:33 | bad2_text | This template depends on a $@. | SlimInjection.rb:5:12:5:17 | call to params | user-provided value |

0 commit comments

Comments
 (0)