ssti query and help updated

This commit is contained in:
John Doe
2020-05-05 03:58:29 +03:00
parent 09922e5bb4
commit 337be9c2e0
2 changed files with 25 additions and 20 deletions

View File

@@ -5,7 +5,7 @@
<overview>
<p>
Server-Side Template Injection vulnerabilities occur when user input is embedded
Server-Side Template Injection vulnerabilities occur when user input is embedded
in a template in an unsafe manner allowing attackers to access the template context and
run arbitrary code on the application server.
</p>
@@ -21,13 +21,30 @@ render engine with sandbox options.
<example>
<p>
The following example shows a page being rendered with user input allowing attackers to access the
The following example shows a page being rendered with user input allowing attackers to access the
template context and run arbitrary code on the application server.
Pug template engine (and other template engines) provides Interpolation feature - insertion of variable values into a string of some kind.
For example, `Hello #{user.username}!`, could be used for printing username from scoped variable user, but `user.username` expression will be executed as valid javascript code.
Unsafe injection of user input provides attacker ability to inject conteqnt like #{some_js_expression}.
Injection of `#{global.process.exit(1)}` leads to code execution of `global.process.exit(1)` by server.
Working exploit (as curl command):
curl -i -s -k -X $'POST' -H $'Host: 127.0.0.1:5061' -H $'Connection: close' -H $'Content-Length: 40' -H $'Content-Type: application/x-www-form-urlencoded' --data-binary $'name=%23%7Bglobal.process.exit%281%29%7D' $'http://127.0.0.1:5061/'
</p>
<sample src="examples/ServerSideTemplateInjection.js" />
</example>
<example>
<p>
As the example of safe usage of rendering engine, please see example below.
In opposite to first example, instead of concatenation of provided user input with the template
it is possible to provide user input as a context - user input will be safely insterted
and rendered inside correspondent placeholders.
</p>
<sample src="examples/ServerSideTemplateInjectionSafe.js" />
</example>
<references>
<li>
OWASP:
@@ -35,7 +52,7 @@ OWASP:
</li>
<li>
PortSwigger Research Blog:
<a href="https://portswigger.net/research/server-side-template-injection">Server Side Template Injection</a>.
<a href="https://portswigger.net/research/server-side-template-injection">Server-Side Template Injection</a>.
</li>
</references>
</qhelp>

View File

@@ -26,13 +26,12 @@ abstract class ServerSideTemplateInjectionSink extends DataFlow::Node { }
class SSTIPugSink extends ServerSideTemplateInjectionSink {
SSTIPugSink() {
exists(CallNode compile, ModuleImportNode renderImport, Node sink |
(renderImport = moduleImport("pug") or renderImport = moduleImport("jade")) and
renderImport = moduleImport(["pug", "jade"]) and
(
compile = renderImport.getAMemberCall("compile") and
compile.flowsTo(sink) and
sink.getStartLine() != sink.getASuccessor().getStartLine()
or
compile = renderImport.getAMemberCall("render") and compile.flowsTo(sink)
compile = renderImport.getAMemberCall("render")
) and
this = compile.getArgument(0)
)
@@ -43,7 +42,6 @@ class SSTIDotSink extends ServerSideTemplateInjectionSink {
SSTIDotSink() {
exists(CallNode compile, Node sink |
compile = moduleImport("dot").getAMemberCall("template") and
compile.flowsTo(sink) and
sink.getStartLine() != sink.getASuccessor().getStartLine() and
this = compile.getArgument(0)
)
@@ -51,26 +49,16 @@ class SSTIDotSink extends ServerSideTemplateInjectionSink {
}
class SSTIEjsSink extends ServerSideTemplateInjectionSink {
SSTIEjsSink() {
exists(CallNode compile, Node sink |
compile = moduleImport("ejs").getAMemberCall("render") and
compile.flowsTo(sink) and
this = compile.getArgument(0)
)
}
SSTIEjsSink() { this = moduleImport("ejs").getAMemberCall("render").getArgument(0) }
}
class SSTINunjucksSink extends ServerSideTemplateInjectionSink {
SSTINunjucksSink() {
exists(CallNode compile, Node sink |
compile = moduleImport("nunjucks").getAMemberCall("renderString") and
compile.flowsTo(sink) and
this = compile.getArgument(0)
)
this = moduleImport("nunjucks").getAMemberCall("renderString").getArgument(0)
}
}
from DataFlow::PathNode source, DataFlow::PathNode sink, ServerSideTemplateInjectionConfiguration c
where c.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "$@ flows to here and is used in an XPath expression.",
select sink.getNode(), source, sink, "$@ flows to here and unsafely used as part of rendered template",
source.getNode(), "User-provided value"