mirror of
https://github.com/github/codeql.git
synced 2026-05-01 11:45:14 +02:00
Merge pull request #12311 from maikypedia/maikypedia/ruby-ssti
Ruby: Add Server Side Template Injection query
This commit is contained in:
@@ -1063,3 +1063,69 @@ module Cryptography {
|
||||
|
||||
class BlockMode = SC::BlockMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* A data-flow node that constructs a template.
|
||||
*
|
||||
* Often, it is worthy of an alert if a template is constructed such that
|
||||
* executing it would be a security risk.
|
||||
*
|
||||
* If it is important that the template is rendered, use `TemplateRendering`.
|
||||
*
|
||||
* Extend this class to refine existing API models. If you want to model new APIs,
|
||||
* extend `TemplateConstruction::Range` instead.
|
||||
*/
|
||||
class TemplateConstruction extends DataFlow::Node instanceof TemplateConstruction::Range {
|
||||
/** Gets the argument that specifies the template to be constructed. */
|
||||
DataFlow::Node getTemplate() { result = super.getTemplate() }
|
||||
}
|
||||
|
||||
/** Provides a class for modeling new template rendering APIs. */
|
||||
module TemplateConstruction {
|
||||
/**
|
||||
* A data-flow node that constructs a template.
|
||||
*
|
||||
* Often, it is worthy of an alert if a template is constructed such that
|
||||
* executing it would be a security risk.
|
||||
*
|
||||
* If it is important that the template is rendered, use `TemplateRendering`.
|
||||
*
|
||||
* Extend this class to model new APIs. If you want to refine existing API models,
|
||||
* extend `TemplateConstruction` instead.
|
||||
*/
|
||||
abstract class Range extends DataFlow::Node {
|
||||
/** Gets the argument that specifies the template to be constructed. */
|
||||
abstract DataFlow::Node getTemplate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data-flow node that renders templates.
|
||||
*
|
||||
* If the context of interest is such that merely constructing a template
|
||||
* would be valuable to report, consider using `TemplateConstruction`.
|
||||
*
|
||||
* Extend this class to refine existing API models. If you want to model new APIs,
|
||||
* extend `TemplateRendering::Range` instead.
|
||||
*/
|
||||
class TemplateRendering extends DataFlow::Node instanceof TemplateRendering::Range {
|
||||
/** Gets the argument that specifies the template to be rendered. */
|
||||
DataFlow::Node getTemplate() { result = super.getTemplate() }
|
||||
}
|
||||
|
||||
/** Provides a class for modeling new template rendering APIs. */
|
||||
module TemplateRendering {
|
||||
/**
|
||||
* A data-flow node that renders templates.
|
||||
*
|
||||
* If the context of interest is such that merely constructing a template
|
||||
* would be valuable to report, consider using `TemplateConstruction`.
|
||||
*
|
||||
* Extend this class to model new APIs. If you want to refine existing API models,
|
||||
* extend `TemplateRendering` instead.
|
||||
*/
|
||||
abstract class Range extends DataFlow::Node {
|
||||
/** Gets the argument that specifies the template to be rendered. */
|
||||
abstract DataFlow::Node getTemplate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,5 +27,7 @@ private import codeql.ruby.frameworks.ActionDispatch
|
||||
private import codeql.ruby.frameworks.PosixSpawn
|
||||
private import codeql.ruby.frameworks.StringFormatters
|
||||
private import codeql.ruby.frameworks.Json
|
||||
private import codeql.ruby.frameworks.Erb
|
||||
private import codeql.ruby.frameworks.Slim
|
||||
private import codeql.ruby.frameworks.Sinatra
|
||||
private import codeql.ruby.frameworks.Twirp
|
||||
|
||||
46
ruby/ql/lib/codeql/ruby/frameworks/Erb.qll
Normal file
46
ruby/ql/lib/codeql/ruby/frameworks/Erb.qll
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Provides templating for embedding Ruby code into text files, allowing dynamic content generation in web applications.
|
||||
*/
|
||||
|
||||
private import codeql.ruby.ApiGraphs
|
||||
private import codeql.ruby.dataflow.FlowSummary
|
||||
private import codeql.ruby.Concepts
|
||||
|
||||
/**
|
||||
* Provides templating for embedding Ruby code into text files, allowing dynamic content generation in web applications.
|
||||
*/
|
||||
module Erb {
|
||||
/**
|
||||
* Flow summary for `ERB.new`. This method wraps a template string, compiling it.
|
||||
*/
|
||||
private class TemplateSummary extends SummarizedCallable {
|
||||
TemplateSummary() { this = "ERB.new" }
|
||||
|
||||
override MethodCall getACall() { result = any(ErbTemplateNewCall c).asExpr().getExpr() }
|
||||
|
||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||
input = "Argument[0]" and output = "ReturnValue" and preservesValue = false
|
||||
}
|
||||
}
|
||||
|
||||
/** A call to `ERB.new`, considered as a template construction. */
|
||||
private class ErbTemplateNewCall extends TemplateConstruction::Range, DataFlow::CallNode {
|
||||
ErbTemplateNewCall() { this = API::getTopLevelMember("ERB").getAnInstantiation() }
|
||||
|
||||
override DataFlow::Node getTemplate() { result = this.getArgument(0) }
|
||||
}
|
||||
|
||||
/** A call to `ERB.new(foo).result(binding)`, considered as a template rendering. */
|
||||
private class ErbTemplateRendering extends TemplateRendering::Range, DataFlow::CallNode {
|
||||
private DataFlow::Node template;
|
||||
|
||||
ErbTemplateRendering() {
|
||||
exists(ErbTemplateNewCall templateConstruction |
|
||||
this = templateConstruction.getAMethodCall("result") and
|
||||
template = templateConstruction.getTemplate()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getTemplate() { result = template }
|
||||
}
|
||||
}
|
||||
38
ruby/ql/lib/codeql/ruby/frameworks/Slim.qll
Normal file
38
ruby/ql/lib/codeql/ruby/frameworks/Slim.qll
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Provides templating for embedding Ruby code into text files, allowing dynamic content generation in web applications.
|
||||
*/
|
||||
|
||||
private import codeql.ruby.ApiGraphs
|
||||
private import codeql.ruby.dataflow.FlowSummary
|
||||
private import codeql.ruby.Concepts
|
||||
|
||||
/**
|
||||
* Provides templating for embedding Ruby code into text files, allowing dynamic content generation in web applications.
|
||||
*/
|
||||
module Slim {
|
||||
/** A call to `Slim::Template.new`, considered as a template construction. */
|
||||
private class SlimTemplateNewCall extends TemplateConstruction::Range, DataFlow::CallNode {
|
||||
SlimTemplateNewCall() {
|
||||
this = API::getTopLevelMember("Slim").getMember("Template").getAnInstantiation()
|
||||
}
|
||||
|
||||
override DataFlow::Node getTemplate() {
|
||||
result.asExpr().getExpr() =
|
||||
this.getBlock().(DataFlow::BlockNode).asCallableAstNode().getAStmt()
|
||||
}
|
||||
}
|
||||
|
||||
/** A call to `Slim::Template.new{ foo }.render`, considered as a template rendering */
|
||||
private class SlimTemplateRendering extends TemplateRendering::Range, DataFlow::CallNode {
|
||||
private DataFlow::Node template;
|
||||
|
||||
SlimTemplateRendering() {
|
||||
exists(SlimTemplateNewCall templateConstruction |
|
||||
this = templateConstruction.getAMethodCall("render") and
|
||||
template = templateConstruction.getTemplate()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getTemplate() { result = template }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Provides default sources, sinks and sanitizers for detecting
|
||||
* ERB Server Side Template Injections, as well as extension points for adding your own
|
||||
*/
|
||||
|
||||
private import codeql.ruby.Concepts
|
||||
private import codeql.ruby.DataFlow
|
||||
private import codeql.ruby.dataflow.BarrierGuards
|
||||
private import codeql.ruby.dataflow.RemoteFlowSources
|
||||
|
||||
/**
|
||||
* Provides default sources, sinks and sanitizers for detecting
|
||||
* Server Side Template Injections, as well as extension points for adding your own
|
||||
*/
|
||||
module TemplateInjection {
|
||||
/** A data flow source for SSTI vulnerabilities */
|
||||
abstract class Source extends DataFlow::Node { }
|
||||
|
||||
/** A data flow sink for SSTI vulnerabilities */
|
||||
abstract class Sink extends DataFlow::Node { }
|
||||
|
||||
/** A sanitizer for SSTI vulnerabilities. */
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A source of remote user input, considered as a flow source.
|
||||
*/
|
||||
private class RemoteFlowSourceAsSource extends Source, RemoteFlowSource { }
|
||||
|
||||
/**
|
||||
* An Server Side Template Injection rendering, considered as a flow sink.
|
||||
*/
|
||||
private class TemplateRenderingAsSink extends Sink {
|
||||
TemplateRenderingAsSink() { this = any(TemplateRendering e).getTemplate() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A comparison with a constant string, considered as a sanitizer-guard.
|
||||
*/
|
||||
private class StringConstCompareAsSanitizerGuard extends Sanitizer, StringConstCompareBarrier { }
|
||||
|
||||
/**
|
||||
* An inclusion check against an array of constant strings, considered as a
|
||||
* sanitizer-guard.
|
||||
*/
|
||||
private class StringConstArrayInclusionCallAsSanitizer extends Sanitizer,
|
||||
StringConstArrayInclusionCallBarrier
|
||||
{ }
|
||||
}
|
||||
21
ruby/ql/lib/codeql/ruby/security/TemplateInjectionQuery.qll
Normal file
21
ruby/ql/lib/codeql/ruby/security/TemplateInjectionQuery.qll
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Provides default sources, sinks and sanitizers for detecting
|
||||
* Server Side Template Injections, as well as extension points for adding your own
|
||||
*/
|
||||
|
||||
private import codeql.ruby.DataFlow
|
||||
private import codeql.ruby.TaintTracking
|
||||
import TemplateInjectionCustomizations::TemplateInjection
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for detecting Server Side Template Injections vulnerabilities.
|
||||
*/
|
||||
class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "TemplateInjection" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node source) { source instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
}
|
||||
4
ruby/ql/src/change-notes/2023-03-15-ssti-query.md
Normal file
4
ruby/ql/src/change-notes/2023-03-15-ssti-query.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: newQuery
|
||||
---
|
||||
* Added a new experimental query, `rb/server-side-template-injection`, to detect cases where user input may be embedded into a template's code in an unsafe manner.
|
||||
@@ -0,0 +1,38 @@
|
||||
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
Template Injection occurs when user input is embedded in a template's code in an unsafe manner.
|
||||
An attacker can use native template syntax to inject a malicious payload into a template, which is then executed server-side.
|
||||
This permits the attacker to run arbitrary code in the server's context.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
To fix this, ensure that untrusted input is not used as part of a template's code. If the application requirements do not allow this,
|
||||
use a sandboxed environment where access to unsafe attributes and methods is prohibited.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>
|
||||
Consider the example given below, an untrusted HTTP parameter <code>name</code> is used to generate a template string. This can lead to remote code execution.
|
||||
</p>
|
||||
<sample src="examples/SSTIBad.rb" />
|
||||
|
||||
<p>
|
||||
Here we have fixed the problem by including ERB/Slim syntax in the string, then the user input will be rendered but not evaluated.
|
||||
</p>
|
||||
<sample src="examples/SSTIGood.rb" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>
|
||||
Wikipedia: <a href="https://en.wikipedia.org/wiki/Code_injection#Server_Side_Template_Injection">Server Side Template Injection</a>.
|
||||
</li>
|
||||
<li>
|
||||
Portswigger : <a href="https://portswigger.net/web-security/server-side-template-injection">Server Side Template Injection</a>.
|
||||
</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @name Server-side template injection
|
||||
* @description Building a server-side template from user-controlled sources is vulnerable to
|
||||
* insertion of malicious code by the user.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @security-severity 8.8
|
||||
* @precision high
|
||||
* @id rb/server-side-template-injection
|
||||
* @tags security
|
||||
* external/cwe/cwe-94
|
||||
*/
|
||||
|
||||
import codeql.ruby.DataFlow
|
||||
import codeql.ruby.security.TemplateInjectionQuery
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where config.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "This template depends on a $@.", source.getNode(),
|
||||
"user-provided value"
|
||||
@@ -0,0 +1,24 @@
|
||||
require 'erb'
|
||||
require 'slim'
|
||||
|
||||
class BadERBController < ActionController::Base
|
||||
def some_request_handler
|
||||
name = params["name"]
|
||||
html_text = "
|
||||
<!DOCTYPE html><html><body>
|
||||
<h2>Hello %s </h2></body></html>
|
||||
" % name
|
||||
template = ERB.new(html_text).result(binding)
|
||||
end
|
||||
end
|
||||
|
||||
class BadSlimController < ActionController::Base
|
||||
def some_request_handler
|
||||
name = params["name"]
|
||||
html_text = "
|
||||
<!DOCTYPE html><html><body>
|
||||
<h2>Hello %s </h2></body></html>
|
||||
" % name
|
||||
Slim::Template.new{ html_text }.render
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,26 @@
|
||||
require 'erb'
|
||||
require 'slim'
|
||||
|
||||
class GoodController < ActionController::Base
|
||||
def some_request_handler
|
||||
name = params["name"]
|
||||
html_text = "
|
||||
<!DOCTYPE html><html><body>
|
||||
<h2>Hello <%= name %> </h2></body></html>
|
||||
"
|
||||
template = ERB.new(html_text).result(binding)
|
||||
end
|
||||
end
|
||||
|
||||
class GoodController < ActionController::Base
|
||||
def some_request_handler
|
||||
name = params["name"]
|
||||
html_text = "
|
||||
<!DOCTYPE html>
|
||||
html
|
||||
body
|
||||
h2 == name;
|
||||
"
|
||||
Slim::Template.new{ html_text }.render(Object.new, name: name)
|
||||
end
|
||||
end
|
||||
@@ -2805,6 +2805,7 @@
|
||||
| file://:0:0:0:0 | parameter position 0 of ActionController::Parameters#merge! | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#merge! |
|
||||
| file://:0:0:0:0 | parameter position 0 of Arel.sql | file://:0:0:0:0 | [summary] to write: return (return) in Arel.sql |
|
||||
| file://:0:0:0:0 | parameter position 0 of Base64.decode64() | file://:0:0:0:0 | [summary] to write: return (return) in Base64.decode64() |
|
||||
| file://:0:0:0:0 | parameter position 0 of ERB.new | file://:0:0:0:0 | [summary] to write: return (return) in ERB.new |
|
||||
| file://:0:0:0:0 | parameter position 0 of File.absolute_path | file://:0:0:0:0 | [summary] to write: return (return) in File.absolute_path |
|
||||
| file://:0:0:0:0 | parameter position 0 of File.dirname | file://:0:0:0:0 | [summary] to write: return (return) in File.dirname |
|
||||
| file://:0:0:0:0 | parameter position 0 of File.expand_path | file://:0:0:0:0 | [summary] to write: return (return) in File.expand_path |
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
class FooController < ActionController::Base
|
||||
def some_request_handler
|
||||
# A string tainted by user input is inserted into a template
|
||||
# (i.e a remote flow source)
|
||||
name = params[:name]
|
||||
|
||||
# Template with the source
|
||||
bad_text = "
|
||||
<!DOCTYPE html><html><body>
|
||||
<h2>Hello %s </h2></body></html>
|
||||
" % name
|
||||
|
||||
# BAD: user input is evaluated
|
||||
# where name is unsanitized
|
||||
template = ERB.new(bad_text).result(binding)
|
||||
|
||||
# Template with the source
|
||||
good_text = "
|
||||
<!DOCTYPE html><html><body>
|
||||
<h2>Hello <%= name %> </h2></body></html>
|
||||
"
|
||||
|
||||
# GOOD: user input is not evaluated
|
||||
template2 = ERB.new(good_text).result(binding)
|
||||
end
|
||||
end
|
||||
|
||||
class BarController < ApplicationController
|
||||
def safe_paths
|
||||
name1 = params["name1"]
|
||||
# GOOD: barrier guard prevents taint flow
|
||||
if name == "admin"
|
||||
text_bar1 = "
|
||||
<!DOCTYPE html><html><body>
|
||||
<h2>Hello %s </h2></body></html>
|
||||
" % name
|
||||
else
|
||||
text = "
|
||||
<!DOCTYPE html><html><body>
|
||||
<h2>Hello else </h2></body></html>
|
||||
"
|
||||
end
|
||||
template_bar1 = ERB.new(text_bar1).result(binding)
|
||||
|
||||
|
||||
name2 = params["name2"]
|
||||
# GOOD: barrier guard prevents taint flow
|
||||
name2 = if ["admin", "guest"].include? name2
|
||||
name2
|
||||
else
|
||||
name2 = "none"
|
||||
end
|
||||
text_bar2 = "
|
||||
<!DOCTYPE html><html><body>
|
||||
<h2>Hello %s </h2></body></html>
|
||||
" % name2
|
||||
template_bar2 = ERB.new(text_bar2).result(binding)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,67 @@
|
||||
class FooController < ActionController::Base
|
||||
def some_request_handler
|
||||
# A string tainted by user input is inserted into a template
|
||||
# (i.e a remote flow source)
|
||||
name = params[:name]
|
||||
|
||||
# Template with the source (no sanitizer)
|
||||
bad_text = "
|
||||
<!DOCTYPE html><html><body>
|
||||
<h2>Hello %s </h2></body></html>
|
||||
" % name
|
||||
# BAD: renders user input
|
||||
# where text is unsanitized
|
||||
Slim::Template.new{ bad_text }.render
|
||||
|
||||
# Template with the source (no sanitizer)
|
||||
bad2_text = "
|
||||
<!DOCTYPE html><html><body>
|
||||
<h2>Hello #{name} </h2></body></html>
|
||||
"
|
||||
# BAD: renders user input
|
||||
# where text is unsanitized
|
||||
Slim::Template.new{ bad2_text }.render
|
||||
|
||||
# Template with the source (no render)
|
||||
good_text = "
|
||||
<!DOCTYPE html>
|
||||
html
|
||||
body
|
||||
h2 == name;
|
||||
"
|
||||
# GOOD: user input is not evaluated
|
||||
Slim::Template.new{ good_text }.render(Object.new, name: name)
|
||||
end
|
||||
end
|
||||
|
||||
class BarController < ApplicationController
|
||||
def safe_paths
|
||||
name1 = params["name1"]
|
||||
# GOOD: barrier guard prevents taint flow
|
||||
if name == "admin"
|
||||
text_bar1 = "
|
||||
<!DOCTYPE html><html><body>
|
||||
<h2>Hello %s </h2></body></html>
|
||||
" % name
|
||||
else
|
||||
text_bar1 = "
|
||||
<!DOCTYPE html><html><body>
|
||||
<h2>Hello else </h2></body></html>
|
||||
"
|
||||
end
|
||||
template_bar1 = Slim::Template.new{ text_bar1 }.render
|
||||
|
||||
name2 = params["name2"]
|
||||
# GOOD: barrier guard prevents taint flow
|
||||
name2 = if ["admin", "guest"].include? name2
|
||||
name2
|
||||
else
|
||||
name2 = "none"
|
||||
end
|
||||
text_bar2 = "
|
||||
<!DOCTYPE html><html><body>
|
||||
<h2>Hello %s </h2></body></html>
|
||||
" % name2
|
||||
template_bar1 = Slim::Template.new{ text_bar2 }.render
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,33 @@
|
||||
edges
|
||||
| ErbInjection.rb:5:12:5:17 | call to params : | ErbInjection.rb:5:12:5:24 | ...[...] : |
|
||||
| ErbInjection.rb:5:12:5:24 | ...[...] : | ErbInjection.rb:11:11:11:14 | name : |
|
||||
| ErbInjection.rb:5:12:5:24 | ...[...] : | ErbInjection.rb:15:24:15:31 | bad_text |
|
||||
| ErbInjection.rb:8:16:11:14 | ... % ... : | ErbInjection.rb:15:24:15:31 | bad_text |
|
||||
| ErbInjection.rb:11:11:11:14 | name : | ErbInjection.rb:8:16:11:14 | ... % ... : |
|
||||
| SlimInjection.rb:5:12:5:17 | call to params : | SlimInjection.rb:5:12:5:24 | ...[...] : |
|
||||
| SlimInjection.rb:5:12:5:24 | ...[...] : | SlimInjection.rb:8:5:11:14 | ... = ... : |
|
||||
| SlimInjection.rb:5:12:5:24 | ...[...] : | SlimInjection.rb:11:11:11:14 | name : |
|
||||
| SlimInjection.rb:5:12:5:24 | ...[...] : | SlimInjection.rb:17:5:20:7 | ... = ... : |
|
||||
| SlimInjection.rb:8:5:11:14 | ... = ... : | SlimInjection.rb:14:25:14:32 | bad_text |
|
||||
| SlimInjection.rb:8:16:11:14 | ... % ... : | SlimInjection.rb:8:5:11:14 | ... = ... : |
|
||||
| SlimInjection.rb:11:11:11:14 | name : | SlimInjection.rb:8:16:11:14 | ... % ... : |
|
||||
| SlimInjection.rb:17:5:20:7 | ... = ... : | SlimInjection.rb:23:25:23:33 | bad2_text |
|
||||
nodes
|
||||
| ErbInjection.rb:5:12:5:17 | call to params : | semmle.label | call to params : |
|
||||
| ErbInjection.rb:5:12:5:24 | ...[...] : | semmle.label | ...[...] : |
|
||||
| ErbInjection.rb:8:16:11:14 | ... % ... : | semmle.label | ... % ... : |
|
||||
| ErbInjection.rb:11:11:11:14 | name : | semmle.label | name : |
|
||||
| ErbInjection.rb:15:24:15:31 | bad_text | semmle.label | bad_text |
|
||||
| SlimInjection.rb:5:12:5:17 | call to params : | semmle.label | call to params : |
|
||||
| SlimInjection.rb:5:12:5:24 | ...[...] : | semmle.label | ...[...] : |
|
||||
| SlimInjection.rb:8:5:11:14 | ... = ... : | semmle.label | ... = ... : |
|
||||
| SlimInjection.rb:8:16:11:14 | ... % ... : | semmle.label | ... % ... : |
|
||||
| SlimInjection.rb:11:11:11:14 | name : | semmle.label | name : |
|
||||
| SlimInjection.rb:14:25:14:32 | bad_text | semmle.label | bad_text |
|
||||
| SlimInjection.rb:17:5:20:7 | ... = ... : | semmle.label | ... = ... : |
|
||||
| SlimInjection.rb:23:25:23:33 | bad2_text | semmle.label | bad2_text |
|
||||
subpaths
|
||||
#select
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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,0 +1 @@
|
||||
experimental/template-injection/TemplateInjection.ql
|
||||
Reference in New Issue
Block a user