Skip to content

Commit 0554d69

Browse files
Merge branch 'master' into rule/add-RSPEC-S7475
2 parents 7f34e22 + 23ef39d commit 0554d69

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+1539
-268
lines changed
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
=== Articles & blog posts
22

3-
* https://blog.sonarsource.com/moodle-remote-code-execution/[SonarSource, Evil Teacher: Code Injection in Moodle]
3+
* SonarSource - https://blog.sonarsource.com/moodle-remote-code-execution/[Evil Teacher: Code Injection in Moodle]
44

rules/S5334/java/how-to-fix-it/commons-compiler.adoc

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class ExampleController
1717
@GetMapping(value = "/")
1818
public void exec(@RequestParam("message") String message) throws IOException, InvocationTargetException {
1919
ScriptEvaluator se = new ScriptEvaluator();
20-
se.cook("System.out.println(\" + message \");");
20+
se.cook("System.out.println(" + message +");"); // Noncompliant
2121
se.evaluate(null);
2222
}
2323
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
== How to fix it in Commons Compiler
2+
3+
=== Code examples
4+
5+
The following code is vulnerable to arbitrary code execution because it compiles
6+
and runs HTTP data.
7+
8+
==== Noncompliant code example
9+
10+
[source,kotlin,diff-id=1,diff-type=noncompliant]
11+
----
12+
import org.codehaus.janino.ScriptEvaluator
13+
14+
@Controller
15+
class ExampleController {
16+
@GetMapping("/")
17+
fun exec(@RequestParam("message") message: String) {
18+
val se = ScriptEvaluator()
19+
se.cook("System.out.println($message);") // Noncompliant
20+
se.evaluate(null)
21+
}
22+
}
23+
----
24+
25+
==== Compliant solution
26+
27+
[source,kotlin,diff-id=1,diff-type=compliant]
28+
----
29+
import org.codehaus.janino.ScriptEvaluator
30+
31+
@Controller
32+
class ExampleController {
33+
@GetMapping("/")
34+
fun exec(@RequestParam("message") message: String) {
35+
val se = ScriptEvaluator()
36+
se.setParameters(arrayOf("input"), arrayOf(String::class.java))
37+
se.cook("System.out.println(input);")
38+
se.evaluate(arrayOf(message))
39+
}
40+
}
41+
----
42+
43+
=== How does this work?
44+
45+
include::../../common/fix/introduction.adoc[]
46+
47+
include::../../common/fix/parameters.adoc[]
48+
49+
The compliant code example uses such an approach.
50+
51+
include::../../common/fix/allowlist.adoc[]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
== How to fix it in Spring
2+
3+
=== Code examples
4+
5+
The following code is vulnerable to arbitrary code execution because it compiles
6+
and runs HTTP data.
7+
8+
==== Noncompliant code example
9+
10+
[source,kotlin,diff-id=11,diff-type=noncompliant]
11+
----
12+
import org.springframework.expression.spel.standard.SpelExpressionParser
13+
14+
@Controller
15+
class ExampleController {
16+
@GetMapping("/")
17+
fun exec(@RequestParam("message") message: String) {
18+
val parser = SpelExpressionParser()
19+
val exp = parser.parseExpression(message) // Noncompliant
20+
}
21+
}
22+
----
23+
24+
==== Compliant solution
25+
26+
[source,kotlin,diff-id=11,diff-type=compliant]
27+
----
28+
import org.springframework.expression.spel.standard.SpelExpressionParser
29+
30+
@Controller
31+
class ExampleController {
32+
@GetMapping("/")
33+
fun exec(@RequestParam("message") message: String) {
34+
val evaluationContext = StandardEvaluationContext()
35+
evaluationContext.setVariable("msg", message)
36+
val parser = SpelExpressionParser()
37+
val exp = parser.parseExpression("#msg")
38+
val result = exp.getValue(evaluationContext) as String
39+
}
40+
}
41+
----
42+
43+
=== How does this work?
44+
45+
include::../../common/fix/introduction.adoc[]
46+
47+
include::../../common/fix/parameters.adoc[]
48+
49+
The compliant code example uses such an approach.
50+
51+
include::../../common/fix/allowlist.adoc[]

rules/S5334/kotlin/metadata.json

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"securityStandards": {
3+
"CWE": [
4+
20,
5+
95,
6+
917
7+
],
8+
"OWASP": [
9+
"A1"
10+
],
11+
"OWASP Top 10 2021": [
12+
"A3"
13+
],
14+
"PCI DSS 3.2": [
15+
"6.5.1"
16+
],
17+
"PCI DSS 4.0": [
18+
"6.2.4"
19+
],
20+
"ASVS 4.0": [
21+
"5.1.3",
22+
"5.1.4",
23+
"5.2.4",
24+
"5.5.4"
25+
],
26+
"STIG ASD_V5R3": [
27+
"V-222609"
28+
]
29+
}
30+
}

rules/S5334/kotlin/rule.adoc

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
== Why is this an issue?
2+
3+
include::../rationale.adoc[]
4+
5+
include::../impact.adoc[]
6+
7+
// How to fix it section
8+
9+
include::how-to-fix-it/commons-compiler.adoc[]
10+
11+
include::how-to-fix-it/spring.adoc[]
12+
13+
== Resources
14+
15+
include::../common/resources/articles.adoc[]
16+
17+
include::../common/resources/standards.adoc[]
18+
19+
* CWE - https://cwe.mitre.org/data/definitions/917[CWE-917 - Improper Neutralization of Special Elements used in an Expression Language Statement ('Expression Language Injection')]
20+
21+
ifdef::env-github,rspecator-view[]
22+
23+
'''
24+
== Implementation Specification
25+
(visible only on this page)
26+
27+
include::../message.adoc[]
28+
29+
=== Highlighting
30+
31+
"[varname]" is tainted (assignments and parameters)
32+
33+
this argument is tainted (method invocations)
34+
35+
the returned value is tainted (returns & method invocations results)
36+
37+
38+
'''
39+
== Comments And Links
40+
(visible only on this page)
41+
42+
include::../comments-and-links.adoc[]
43+
44+
endif::env-github,rspecator-view[]
45+

rules/S5496/java/rule.adoc

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ include::how-to-fix-it/groovy.adoc[]
1515

1616
=== Articles & blog posts
1717

18-
* https://www.acunetix.com/blog/web-security-zone/exploiting-ssti-in-thymeleaf/[Exploiting SSTI in Thymeleaf]
18+
* Acunetix Web Security Blog - https://www.acunetix.com/blog/web-security-zone/exploiting-ssti-in-thymeleaf/[Exploiting SSTI in Thymeleaf]
1919

2020
include::../standards.adoc[]
2121

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
== How to fix it in Groovy
2+
3+
=== Code examples
4+
5+
==== Noncompliant code example
6+
7+
The following code example is vulnerable to a Server-Side Template Injection
8+
attack because it builds a template string from a user input without control or
9+
sanitation.
10+
11+
[source,kotlin,diff-id=21,diff-type=noncompliant]
12+
----
13+
import groovy.text.markup.MarkupTemplateEngine
14+
import groovy.text.markup.TemplateConfiguration
15+
16+
@Controller
17+
class ExampleController {
18+
@GetMapping("/example")
19+
fun example(@RequestParam("title") title: String): String {
20+
val templateString = "h1('$title')"
21+
val config = TemplateConfiguration()
22+
val engine = MarkupTemplateEngine(config)
23+
val template = engine.createTemplate(templateString) // Noncompliant
24+
val out = template.make()
25+
return out.toString()
26+
}
27+
}
28+
----
29+
30+
==== Compliant solution
31+
32+
[source,kotlin,diff-id=21,diff-type=compliant]
33+
----
34+
import groovy.text.markup.MarkupTemplateEngine
35+
import groovy.text.markup.TemplateConfiguration
36+
37+
@Controller
38+
class ExampleController {
39+
@GetMapping("/example")
40+
fun example(@RequestParam("title") title: String): String {
41+
val templateString = "h1(title)"
42+
43+
val ctx = mutableMapOf<String, Any>()
44+
ctx["title"] = title
45+
46+
val config = TemplateConfiguration()
47+
val engine = MarkupTemplateEngine(config)
48+
val template = engine.createTemplate(templateString)
49+
val out: Writable = template.make(ctx)
50+
return out.toString()
51+
}
52+
}
53+
----
54+
55+
=== How does this work?
56+
57+
The compliant code example uses a template binding to pass user information to
58+
the template. The rendering engine then ensures that this tainted data is
59+
processed in a way that will not change the template semantics.

rules/S5496/kotlin/metadata.json

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
{
2+
}

rules/S5496/kotlin/rule.adoc

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
== Why is this an issue?
2+
3+
include::../rationale.adoc[]
4+
5+
include::../impact.adoc[]
6+
7+
// How to fix it section
8+
9+
include::how-to-fix-it/groovy.adoc[]
10+
11+
12+
== Resources
13+
14+
=== Articles & blog posts
15+
16+
* Acunetix Web Security Blog - https://www.acunetix.com/blog/web-security-zone/exploiting-ssti-in-thymeleaf/[Exploiting SSTI in Thymeleaf]
17+
18+
include::../standards.adoc[]
19+
20+
21+
ifdef::env-github,rspecator-view[]
22+
23+
'''
24+
== Implementation Specification
25+
(visible only on this page)
26+
27+
=== Message
28+
29+
include::../message.adoc[]
30+
31+
'''
32+
endif::env-github,rspecator-view[]
+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
=== Documentation
22

3-
* https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html[OWASP, OS Command Injection Defense Cheat Sheet]
4-
* https://gtfobins.github.io/#+shell[GTFOBins, list of Unix binaries that can be used to bypass local security restrictions]
5-
* https://lolbas-project.github.io/#[LOLBAS, list of Windows binaries that can be used to bypass local security restrictions]
3+
* OWASP - https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html[OS Command Injection Defense Cheat Sheet]
4+
* GTFOBins - https://gtfobins.github.io/#+shell[list of Unix binaries that can be used to bypass local security restrictions]
5+
* LOLBAS - https://lolbas-project.github.io/#[list of Windows binaries that can be used to bypass local security restrictions]
66

rules/S5883/java/how-to-fix-it/java-se.adoc renamed to rules/S5883/java/how-to-fix-it/java-lang.adoc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
== How to fix it in Java SE
1+
== How to fix it in Java Lang Package
22

33
=== Code examples
44

rules/S5883/java/rule.adoc

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ include::../impact.adoc[]
77

88
// How to fix it section
99

10-
include::how-to-fix-it/java-se.adoc[]
10+
include::how-to-fix-it/java-lang.adoc[]
1111

1212
include::how-to-fix-it/apache-commons.adoc[]
1313

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
== How to fix it in Apache Commons
2+
3+
=== Code examples
4+
5+
include::../../common/fix/code-rationale.adoc[]
6+
7+
==== Noncompliant code example
8+
9+
[source,kotlin,diff-id=1,diff-type=noncompliant]
10+
----
11+
import org.apache.commons.exec.CommandLine
12+
13+
@Controller
14+
class ExampleController {
15+
@GetMapping("/find")
16+
fun find(@RequestParam("filename") filename: String) {
17+
val cmd = CommandLine("/usr/bin/find . -iname $filename") // Noncompliant
18+
}
19+
}
20+
----
21+
22+
==== Compliant solution
23+
24+
[source,kotlin,diff-id=1,diff-type=compliant]
25+
----
26+
import org.apache.commons.exec.CommandLine
27+
28+
@Controller
29+
class ExampleController {
30+
@GetMapping("/find")
31+
fun find(@RequestParam("filename") filename: String) {
32+
val cmd = CommandLine("/usr/bin/find")
33+
cmd.addArguments(arrayOf("/usr/bin/find", ".", "-iname", filename))
34+
}
35+
}
36+
----
37+
38+
=== How does this work?
39+
40+
include::../../common/fix/introduction.adoc[]
41+
42+
Here `org.apache.commons.exec.CommandLine.addArguments(addArguments: Array<String>)` takes care of escaping the passed arguments and internally
43+
creates a single string given to the operating system to be executed.

0 commit comments

Comments
 (0)