Modify All Current Education Rules: Support intuitive view (#1256)

This commit is contained in:
Loris S 2022-09-15 10:28:08 +02:00 committed by Christophe Zürn
parent 16919a7fc1
commit 8815e23ae8
48 changed files with 485 additions and 617 deletions

View File

@ -2,25 +2,24 @@
include::../../common/fix/code-rationale.adoc[]
[cols="a"]
|===
h| Non-compliant code example
|
[source,csharp]
==== Non-compliant code example
[source,csharp,diff-id=1,diff-type=noncompliant]
----
public class ExampleController : Controller
{
public void Run(string binary)
{
Process p = new Process();
p.StartInfo.FileName = binary; // Noncompliant
p.StartInfo.FileName = binary;
p.Start();
}
}
----
h| Compliant solution
|
[source,csharp]
==== Compliant solution
[source,csharp,diff-id=1,diff-type=compliant]
----
public class ExampleController : Controller
{
@ -36,7 +35,6 @@ public class ExampleController : Controller
}
}
----
|===
=== How does this work?

View File

@ -2,11 +2,9 @@
include::../../common/fix/code-rationale.adoc[]
[cols="a"]
|===
h| Non-compliant code example
|
[source,java]
==== Non-compliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
@Controller
public class ExampleController
@ -14,15 +12,16 @@ public class ExampleController
@GetMapping(value = "/exec")
public void exec(@RequestParam("command") String command) throws IOException {
CommandLine cmd = new CommandLine(command); // Noncompliant
CommandLine cmd = new CommandLine(command);
DefaultExecutor executor = new DefaultExecutor();
executor.execute(cmd);
}
}
----
h| Compliant solution
|
[source,java]
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
@Controller
public class ExampleController
@ -42,7 +41,6 @@ public class ExampleController
}
}
----
|===
=== How does this work?

View File

@ -2,11 +2,9 @@
include::../../common/fix/code-rationale.adoc[]
[cols="a"]
|===
h| Non-compliant code example
|
[source,java]
==== Non-compliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
@Controller
public class ExampleController
@ -14,13 +12,14 @@ public class ExampleController
@GetMapping(value = "/exec")
public void exec(@RequestParam("command") String command) throws IOException {
Runtime.getRuntime().exec(command); // Noncompliant
Runtime.getRuntime().exec(command);
}
}
----
h| Compliant solution
|
[source,java]
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
@Controller
public class ExampleController
@ -36,7 +35,6 @@ public class ExampleController
}
}
----
|===
++java.lang.Runtime++ is sometimes used over ++java.lang.ProcessBuilder++ due to ease of use. Flexibility in methods often introduces security issues as edge cases are easily missed. The compliant solution logic is also applied to ++java.lang.ProcessBuilder++.

View File

@ -3,11 +3,9 @@
The following non-compliant code is vulnerable to LDAP injections because untrusted data is
concatenated in an LDAP query without prior validation.
[cols="a"]
|===
h| Non-compliant code example
|
[source,csharp]
==== Non-compliant code example
[source,csharp,diff-id=1,diff-type=noncompliant]
----
public class ExampleController : Controller
{
@ -16,15 +14,16 @@ public class ExampleController : Controller
DirectoryEntry directory = new DirectoryEntry("LDAP://ou=system");
DirectorySearcher search = new DirectorySearcher(directory);
search.Filter = "(&(uid=" + user + ")(userPassword=" + pass + "))"; // Noncompliant
search.Filter = "(&(uid=" + user + ")(userPassword=" + pass + "))";
return Json(search.FindOne() != null);
}
}
----
h| Compliant solution
|
[source,csharp]
==== Compliant solution
[source,csharp,diff-id=1,diff-type=compliant]
----
public class ExampleController : Controller
{
@ -45,7 +44,6 @@ public class ExampleController : Controller
}
}
----
|===
=== How does this work?

View File

@ -3,11 +3,9 @@
The following non-compliant code is vulnerable to LDAP injections because untrusted data is
concatenated to an LDAP query without prior sanitization or validation.
[cols="a"]
|===
h| Non-compliant code example
|
[source,java]
==== Non-compliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
public boolean authenticate(HttpServletRequest req, DirContext ctx) throws NamingException {
@ -16,13 +14,14 @@ public boolean authenticate(HttpServletRequest req, DirContext ctx) throws Namin
String filter = "(&(uid=" + user + ")(userPassword=" + pass + "))";
NamingEnumeration<SearchResult> results = ctx.search("ou=system", filter, new SearchControls()); // Noncompliant
NamingEnumeration<SearchResult> results = ctx.search("ou=system", filter, new SearchControls());
return results.hasMore();
}
----
h| Compliant solution
|
[source,java]
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
public boolean authenticate(HttpServletRequest req, DirContext ctx) throws NamingException {
String user = req.getParameter("user");
@ -34,7 +33,6 @@ public boolean authenticate(HttpServletRequest req, DirContext ctx) throws Namin
return results.hasMore();
}
----
|===
=== How does this work?
@ -46,5 +44,4 @@ and
https://www.javadoc.io/doc/org.owasp.esapi/esapi/latest/org/owasp/esapi/Encoder.html#encodeForLDAP-java.lang.String-[`encodeForLDAP`]
allow sanitizing these characters automatically.
In the compliant solution example, the `search` function allows to safely parameterize the query.

View File

@ -3,11 +3,9 @@
:canonicalization_function: System.IO.Path.GetFullPath
include::../../common/fix/code-rationale.adoc[]
[cols="a"]
|===
h| Non-compliant code example
|
[source,csharp]
==== Non-compliant code example
[source,csharp,diff-id=1,diff-type=noncompliant]
----
public class ExampleController : Controller
{
@ -16,13 +14,14 @@ public class ExampleController : Controller
public void Example(string filename)
{
string path = Path.Combine(TargetDirectory, filename);
System.IO.File.Delete(path); // Noncompliant
System.IO.File.Delete(path);
}
}
----
h| Compliant solution
|
[source,csharp]
==== Compliant solution
[source,csharp,diff-id=1,diff-type=compliant]
----
public class ExampleController : Controller
{
@ -40,7 +39,6 @@ public class ExampleController : Controller
}
}
----
|===
=== How does this work?

View File

@ -3,11 +3,9 @@
:canonicalization_function: java.io.File.getCanonicalPath
include::../../common/fix/code-rationale.adoc[]
[cols="a"]
|===
h| Non-compliant code example
|
[source,java]
==== Non-compliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
@Controller
public class ExampleController
@ -18,13 +16,14 @@ public class ExampleController
public void delete(@RequestParam("filename") String filename) throws IOException {
File file = new File(targetDirectory + filename);
file.delete(); // Noncompliant
file.delete();
}
}
----
h| Compliant solution
|
[source,java]
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
@Controller
public class ExampleController
@ -45,7 +44,6 @@ public class ExampleController
}
}
----
|===
=== How does this work?

View File

@ -2,11 +2,9 @@
The following code is vulnerable to XPath injections because untrusted data is
concatenated in an XPath query without prior validation.
[cols="a"]
|===
h| Non-compliant code example
|
[source,csharp]
==== Non-compliant code example
[source,csharp,diff-id=1,diff-type=noncompliant]
----
public class ExampleController : Controller
{
@ -17,14 +15,15 @@ public class ExampleController : Controller
String expression = "/users/user[@name='" + user + "' and @pass='" + pass + "']";
return Json(doc.SelectSingleNode(expression) != null); // Noncompliant
return Json(doc.SelectSingleNode(expression) != null);
}
}
----
h| Compliant solution
|
[source,csharp]
==== Compliant solution
[source,csharp,diff-id=1,diff-type=compliant]
----
public class ExampleController : Controller
{
@ -43,7 +42,6 @@ public class ExampleController : Controller
}
}
----
|===
=== How does this work?

View File

@ -3,11 +3,9 @@
The following non-compliant code is vulnerable to XPath injections because untrusted data is
concatenated to an XPath query without prior validation.
[cols="a"]
|===
h| Non-compliant code example
|
[source,java]
==== Non-compliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
public boolean authenticate(HttpServletRequest req, XPath xpath, Document doc) throws XPathExpressionException {
String user = request.getParameter("user");
@ -15,12 +13,13 @@ public boolean authenticate(HttpServletRequest req, XPath xpath, Document doc) t
String expression = "/users/user[@name='" + user + "' and @pass='" + pass + "']";
return (boolean)xpath.evaluate(expression, doc, XPathConstants.BOOLEAN); // Noncompliant
return (boolean)xpath.evaluate(expression, doc, XPathConstants.BOOLEAN);
}
----
h| Compliant solution
|
[source,java]
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
public boolean authenticate(HttpServletRequest req, XPath xpath, Document doc) throws XPathExpressionException {
String user = request.getParameter("user");
@ -43,7 +42,6 @@ public boolean authenticate(HttpServletRequest req, XPath xpath, Document doc) t
}
----
|===
=== How does this work?

View File

@ -4,25 +4,24 @@ The following non-compliant code is vulnerable to Regex Denial of Service
because untrusted data is used as a regex to scan a string without prior
sanitization or validation.
[cols="a"]
|===
h| Non-compliant code example
|
[source,csharp]
==== Non-compliant code example
[source,csharp,diff-id=1,diff-type=noncompliant]
----
public class ExampleController : Controller
{
public IActionResult Validate(string regex, string input)
{
bool match = Regex.IsMatch(input, regex); // Noncompliant
bool match = Regex.IsMatch(input, regex);
return Json(match);
}
}
----
h| Compliant solution
|
[source,csharp]
==== Compliant solution
[source,csharp,diff-id=1,diff-type=compliant]
----
public class ExampleController : Controller
{
@ -34,7 +33,6 @@ public class ExampleController : Controller
}
}
----
|===
=== How does this work?

View File

@ -4,22 +4,21 @@ The following non-compliant code is vulnerable to Regex Denial of Service
because untrusted data is used as a regex to scan a string without prior
sanitization or validation.
[cols="a"]
|===
h| Non-compliant code example
|
[source,java]
==== Non-compliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
public boolean validate(HttpServletRequest request) {
String regex = request.getParameter("regex");
String input = request.getParameter("input");
return input.matches(regex); // Noncompliant
return input.matches(regex);
}
----
h| Compliant solution
|
[source,java]
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
public boolean validate(HttpServletRequest request) {
String regex = request.getParameter("regex");
@ -28,7 +27,6 @@ public boolean validate(HttpServletRequest request) {
return input.matches(Pattern.quote(regex));
}
----
|===
=== How does this work?

View File

@ -2,11 +2,9 @@
include::../../common/fix/code-rationale.adoc[]
[cols="a"]
|===
h| Non-compliant code example
|
[source,csharp]
==== Non-compliant code example
[source,csharp,diff-id=1,diff-type=noncompliant]
----
public class ExampleController : Controller
{
@ -18,7 +16,7 @@ public class ExampleController : Controller
{
var query = "SELECT * FROM users WHERE user = '" + use + "' AND pass = '" + pass + "'";
var result = connection.QueryFirst<User>(query); // Noncompliant
var result = connection.QueryFirst<User>(query);
if (result == null) {
Unauthorized();
}
@ -27,9 +25,10 @@ public class ExampleController : Controller
}
}
----
h| Compliant solution
|
[source,csharp]
==== Compliant solution
[source,csharp,diff-id=1,diff-type=compliant]
----
public class ExampleController : Controller
{
@ -51,7 +50,6 @@ public class ExampleController : Controller
}
}
----
|===
=== How does this work?

View File

@ -2,11 +2,9 @@
include::../../common/fix/code-rationale.adoc[]
[cols="a"]
|===
h| Non-compliant code example
|
[source,csharp]
==== Non-compliant code example
[source,csharp,diff-id=1,diff-type=noncompliant]
----
public class ExampleController : Controller
{
@ -18,7 +16,7 @@ public class ExampleController : Controller
var queryResults = Context
.Database
.ExecuteSqlCommand(query); // Noncompliant
.ExecuteSqlCommand(query);
if (queryResults == 0)
{
@ -29,9 +27,10 @@ public class ExampleController : Controller
}
}
----
h| Compliant solution
|
[source,csharp]
==== Compliant solution
[source,csharp,diff-id=1,diff-type=compliant]
----
public class ExampleController : Controller
{
@ -54,7 +53,6 @@ public class ExampleController : Controller
}
}
----
|===
=== How does this work?

View File

@ -2,11 +2,9 @@
include::../../common/fix/code-rationale.adoc[]
[cols="a"]
|===
h| Non-compliant code example
|
[source,java]
==== Non-compliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
@RestController
public class ApiController
@ -24,7 +22,7 @@ public class ApiController
try {
queryProducer
.createNativeQuery(query) // Noncompliant
.createNativeQuery(query)
.getSingleResult();
} catch (Exception e) {
@ -35,9 +33,10 @@ public class ApiController
}
}
----
h| Compliant solution
|
[source,java]
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
@RestController
public class ApiController
@ -68,7 +67,6 @@ public class ApiController
}
}
----
|===
=== How does this work?

View File

@ -2,11 +2,9 @@
include::../../common/fix/code-rationale.adoc[]
[cols="a"]
|===
h| Non-compliant code example
|
[source,java]
==== Non-compliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
@RestController
public class ApiController
@ -24,7 +22,7 @@ public class ApiController
try (Statement statement = connection.createStatement()) {
ResultSet resultSet = statement.executeQuery(query); // Noncompliant
ResultSet resultSet = statement.executeQuery(query);
if (!resultSet.next()) {
return new ResponseEntity<>("Unauthorized", HttpStatus.UNAUTHORIZED);
@ -35,9 +33,10 @@ public class ApiController
}
}
----
h| Compliant solution
|
[source,java]
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
@RestController
public class ApiController
@ -68,7 +67,6 @@ public class ApiController
}
}
----
|===
=== How does this work?

View File

@ -2,11 +2,9 @@
include::../../common/fix/code-rationale.adoc[]
[cols="a"]
|===
h| Non-compliant code example
|
[source,java]
==== Non-compliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
@RestController
public class ApiController
@ -24,7 +22,7 @@ public class ApiController
try {
BeanPropertyRowMapper<User> userType = new BeanPropertyRowMapper(User.class);
User queryResult = jdbcTemplate.queryForObject(query, userType); // Noncompliant
User queryResult = jdbcTemplate.queryForObject(query, userType);
} catch (Exception e) {
return new ResponseEntity<>("Unauthorized", HttpStatus.UNAUTHORIZED);
@ -34,9 +32,10 @@ public class ApiController
}
}
----
h| Compliant solution
|
[source,java]
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
@RestController
public class ApiController
@ -64,7 +63,6 @@ public class ApiController
}
}
----
|===
=== How does this work?

View File

@ -1,10 +1,8 @@
=== How to fix it in ASP.NET
[cols="a"]
|===
h| Non-compliant code example
|
[source,csharp]
==== Non-compliant code example
[source,csharp,diff-id=1,diff-type=noncompliant]
----
using System.Web;
using System.Web.Mvc;
@ -19,9 +17,10 @@ public class HelloController : Controller
}
}
----
h| Compliant solution
|
[source,csharp]
==== Compliant solution
[source,csharp,diff-id=1,diff-type=compliant]
----
using System.Web;
using System.Web.Mvc;
@ -37,15 +36,12 @@ public class HelloController : Controller
}
}
----
|===
=== How does this work?
If the HTTP response is HTML code, it is highly recommended to use https://docs.microsoft.com/en-us/aspnet/web-pages/overview/getting-started/introducing-razor-syntax-c[Razor-based view templates] to generate it.
This template engine separates the view from the business logic and automatically encodes the output of variables, drastically reducing the risk of cross-site scripting vulnerabilities.
include::../../common/fix/data_encoding.adoc[]
`System.Web.HttpUtility.HtmlEncode` is the recommended method to encode HTML entities.

View File

@ -3,11 +3,9 @@
The following code is vulnerable to cross-site scripting because auto-escaping of special HTML characters has been disabled.
The recommended way to fix this code is to move the HTML content to the template and to only inject the dynamic value. Therefore, it is not necessary to disable auto-escaping.
[cols="a"]
|===
h| Non-compliant code example
|
[source,csharp]
==== Non-compliant code example
[source,csharp,diff-id=1,diff-type=noncompliant]
----
using Microsoft.AspNetCore.Mvc;
@ -21,13 +19,14 @@ public class HelloController : Controller
}
----
[source,html]
[source,html,diff-id=2,diff-type=noncompliant]
----
@Html.Raw(ViewData["Hello"])
----
h| Compliant solution
|
[source,csharp]
==== Compliant solution
[source,csharp,diff-id=1,diff-type=compliant]
----
using Microsoft.AspNetCore.Mvc;
@ -41,11 +40,10 @@ public class HelloController : Controller
}
----
[source,html]
[source,html,diff-id=2,diff-type=compliant]
----
<h1>@ViewData["Name"]</h1>
----
|===
=== How does this work?

View File

@ -4,11 +4,9 @@ The following code is vulnerable to cross-site scripting because JSP does not au
User input embedded in HTML code should be HTML-encoded to prevent the injection of additional code. This can be done with the https://owasp.org/www-project-java-encoder/[OWASP Java Encoder] or similar libraries.
[cols="a"]
|===
h| Non-compliant code example
|
[source,html]
==== Non-compliant code example
[source,html,diff-id=1,diff-type=noncompliant]
----
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="e" uri="https://www.owasp.org/index.php/OWASP_Java_Encoder_Project" %>
@ -19,9 +17,10 @@ h| Non-compliant code example
</body>
</html>
----
h| Compliant solution
|
[source,html]
==== Compliant solution
[source,html,diff-id=1,diff-type=compliant]
----
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="e" uri="https://www.owasp.org/index.php/OWASP_Java_Encoder_Project" %>
@ -32,7 +31,6 @@ h| Compliant solution
</body>
</html>
----
|===
=== How does this work?

View File

@ -5,23 +5,22 @@ The following code is vulnerable to cross-site scripting because it returns an H
Third-party data, such as user input, is not to be trusted.
If embedded in HTML code, it should be HTML-encoded to prevent the injection of additional code. This can be done with the https://owasp.org/www-project-java-encoder/[OWASP Java Encoder] or similar libraries.
[cols="a"]
|===
h| Non-compliant code example
|
[source,java]
==== Non-compliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
public void endpoint(HttpServletRequest request, HttpServletResponse response) throws IOException
{
String data = request.getParameter("input");
PrintWriter writer = response.getWriter();
writer.print(data); // Noncompliant
writer.print(data);
}
----
h| Compliant solution
|
[source,java]
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
import org.owasp.encoder.Encode;
@ -33,29 +32,27 @@ public void endpoint(HttpServletRequest request, HttpServletResponse response) t
writer.print(Encode.forHtml(data));
}
----
|===
If you do not intend to send HTML code to clients, the vulnerability can be fixed by specifying the type of data returned in the response with the content-type header.
For example, setting the content-type to `text/plain` with the `setContentType` function allows to safely reflect user input because browsers will not try to parse and execute the response.
[cols="a"]
|===
h| Non-compliant code example
|
[source,java]
==== Non-compliant code example
[source,java,diff-id=2,diff-type=noncompliant]
----
public void endpoint(HttpServletRequest request, HttpServletResponse response) throws IOException
{
String data = request.getParameter("input");
PrintWriter writer = response.getWriter();
writer.print(data); // Noncompliant
writer.print(data);
}
----
h| Compliant solution
|
[source,java]
==== Compliant solution
[source,java,diff-id=2,diff-type=compliant]
----
public void endpoint(HttpServletRequest request, HttpServletResponse response) throws IOException
{
@ -66,7 +63,6 @@ public void endpoint(HttpServletRequest request, HttpServletResponse response) t
writer.print(data);
}
----
|===
=== How does this work?

View File

@ -5,11 +5,9 @@ The following code is vulnerable to cross-site scripting because it returns an H
If you do not intend to send HTML code to clients, the vulnerability can be fixed by specifying the type of data returned in the response.
For example, you can use the `produces` property of the `GetMapping` annotation.
[cols="a"]
|===
h| Non-compliant code example
|
[source,java]
==== Non-compliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
@RestController
public class ApiController
@ -17,13 +15,14 @@ public class ApiController
@GetMapping(value = "/endpoint")
public String endpoint(@RequestParam("input") input)
{
return input; // Noncompliant
return input;
}
}
----
h| Compliant solution
|
[source,java]
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
@RestController
public class ApiController
@ -35,7 +34,6 @@ public class ApiController
}
}
----
|===
=== How does this work?
@ -48,7 +46,6 @@ Thus, the response is not vulnerable to reflected cross-site scripting.
For example, setting the content-type to `text/plain` allows to safely reflect user input since browsers will not try to parse and execute the response.
=== Pitfalls
include::../../common/pitfalls/content-types.adoc[]

View File

@ -4,27 +4,25 @@ The following code is vulnerable to cross-site scripting.
User input embedded in HTML code should be HTML-encoded to prevent the injection of additional code.
[cols="a"]
|===
h| Non-compliant code example
|
[source,html]
==== Non-compliant code example
[source,html,diff-id=1,diff-type=noncompliant]
----
<body>
<p th:utext="Hello, ${input}!" /> <!-- Noncompliant -->
<p>Hello, [(${input})]!</p> <!-- Noncompliant -->
</body>
----
h| Compliant solution
|
[source,html]
==== Compliant solution
[source,html,diff-id=1,diff-type=compliant]
----
<body>
<p th:text="Hello, ${input}!" />
<p>Hello, [[${input}]]!</p>
</body>
----
|===
=== How does this work?

View File

@ -5,49 +5,45 @@ The following code is vulnerable to cross-site scripting because it returns an H
If you do not intend to send HTML code to clients, the vulnerability can be fixed by specifying the type of data returned in the response.
For example, you can use the `JsonResponse` class to safely return JSON messages.
[cols="a"]
|===
h| Non-compliant code example
|
[source,javascript]
==== Non-compliant code example
[source,javascript,diff-id=1,diff-type=noncompliant]
----
function (req, res) {
json = JSON.stringify({ "data": req.query.input });
res.send(tainted); // Noncompliant
res.send(tainted);
};
----
h| Compliant solution
|
[source,javascript]
==== Compliant solution
[source,javascript,diff-id=1,diff-type=compliant]
----
function (req, res) {
res.json({ "data": req.query.input });
};
----
|===
It is also possible to set the content-type header manually using the `content_type` parameter when creating an `HttpResponse` object.
[cols="a"]
|===
h| Non-compliant code example
|
[source,javascript]
==== Non-compliant code example
[source,javascript,diff-id=2,diff-type=noncompliant]
----
function (req, res) {
res.send(req.query.input); // Noncompliant
res.send(req.query.input);
};
----
h| Compliant solution
|
[source,javascript]
==== Compliant solution
[source,javascript,diff-id=2,diff-type=compliant]
----
function (req, res) {
res.set('Content-Type', 'text/plain');
res.send(req.query.input);
};
----
|===
=== How does this work?

View File

@ -5,43 +5,38 @@ The following code is vulnerable to cross-site scripting because it returns an H
User input embedded in HTML code should be HTML-encoded to prevent the injection of additional code.
PHP provides the built-in function `htmlspecialchars` to do this.
[cols="a"]
|===
h| Non-compliant code example
|
[source,php]
==== Non-compliant code example
[source,php,diff-id=1,diff-type=noncompliant]
----
echo '<h1>' . $input . '</h1>'; // Noncompliant
echo '<h1>' . $input . '</h1>';
----
h| Compliant solution
|
[source,php]
==== Compliant solution
[source,php,diff-id=1,diff-type=compliant]
----
echo '<h1>' . htmlspecialchars($input) . '</h1>';
----
|===
If you do not intend to send HTML code to clients, the vulnerability can be fixed by specifying the type of data returned in the response with the content-type header.
For example, setting the content-type to `text/plain` using the built-in `header` function allows to safely reflect user input since browsers will not try to parse and execute the response.
==== Non-compliant code example
[cols="a"]
|===
h| Non-compliant code example
|
[source,php]
[source,php,diff-id=2,diff-type=noncompliant]
----
echo $input; // Noncompliant
echo $input;
----
h| Compliant solution
|
[source,php]
==== Compliant solution
[source,php,diff-id=2,diff-type=compliant]
----
header('Content-Type: text/plain');
echo $input;
----
|===
=== How does this work?
@ -57,21 +52,19 @@ By default, `htmlspecialchars` does not encode single quotes, so if `++$input++`
Make sure to set the option `ENT_QUOTES` to encode single quotes.
[cols="a"]
|===
h| Non-compliant code example
|
[source,php]
===== Non-compliant code example
[source,php,diff-id=3,diff-type=noncompliant]
----
echo "<img src='" . htmlspecialchars($input) . "'>";
----
h| Compliant solution
|
[source,php]
===== Compliant solution
[source,php,diff-id=3,diff-type=compliant]
----
echo "<img src='" . htmlspecialchars($input, ENT_QUOTES) . "'>";
----
|===
==== Headers and output
@ -79,24 +72,22 @@ If the HTTP body is sent before `header` is called, no headers will be sent to t
To fix this issue, send the headers before any output.
[cols="a"]
|===
h| Non-compliant code example
|
[source,php]
===== Non-compliant code example
[source,php,diff-id=4,diff-type=noncompliant]
----
echo 'No more headers at this point';
header('Content-Type: text/plain');
echo $input;
----
h| Compliant solution
|
[source,php]
===== Compliant solution
[source,php,diff-id=4,diff-type=compliant]
----
header('Content-Type: text/plain');
echo $input;
----
|===
=== Going the extra mile

View File

@ -5,39 +5,35 @@ The following code is vulnerable to cross-site scripting because it returns an H
If you do not intend to send HTML code to clients, the vulnerability can be fixed by specifying the type of data returned in the response.
For example, you can use the `json` method of the `Response` class to safely return JSON messages.
[cols="a"]
|===
h| Non-compliant code example
|
[source,php]
==== Non-compliant code example
[source,php,diff-id=1,diff-type=noncompliant]
----
$response = response(json_encode(['data' => $input]), 200); // Noncompliant
$response = response(json_encode(['data' => $input]), 200);
----
h| Compliant solution
|
[source,php]
==== Compliant solution
[source,php,diff-id=1,diff-type=compliant]
----
$response = response()->json(['data' => $input]);
----
|===
It is also possible to set the content-type header manually using the `header` method of the `Response` class.
[cols="a"]
|===
h| Non-compliant code example
|
[source,php]
==== Non-compliant code example
[source,php,diff-id=2,diff-type=noncompliant]
----
$response = response($input, 200); // Noncompliant
$response = response($input, 200);
----
h| Compliant solution
|
[source,php]
==== Compliant solution
[source,php,diff-id=2,diff-type=compliant]
----
$response = response($input, 200)->header('Content-Type', 'text/plain');
----
|===
=== How does this work?

View File

@ -5,43 +5,40 @@ The following code is vulnerable to cross-site scripting because it returns an H
If you do not intend to send HTML code to clients, the vulnerability can be fixed by specifying the type of data returned in the response.
For example, you can use the class `JsonResponse` to return JSON messages safely.
[cols="a"]
|===
h| Non-compliant code example
|
[source,php]
==== Non-compliant code example
[source,php,diff-id=1,diff-type=noncompliant]
----
use Symfony\Component\HttpFoundation\Response;
$response = new Response();
$response->setContent(json_encode(['data' => $input])); // Noncompliant
$response->setContent(json_encode(['data' => $input]));
----
h| Compliant solution
|
[source,php]
==== Compliant solution
[source,php,diff-id=1,diff-type=compliant]
----
use Symfony\Component\HttpFoundation\JsonResponse;
$response = new JsonResponse(['data' => $input]);
----
|===
It is also possible to set the content-type manually using the `headers` attribute.
[cols="a"]
|===
h| Non-compliant code example
|
[source,php]
==== Non-compliant code example
[source,php,diff-id=2,diff-type=noncompliant]
----
use Symfony\Component\HttpFoundation\Response;
$response = new Response();
$response->setContent($input); // Noncompliant
$response->setContent($input);
----
h| Compliant solution
|
[source,php]
==== Compliant solution
[source,php,diff-id=2,diff-type=compliant]
----
use Symfony\Component\HttpFoundation\Response;
@ -49,7 +46,6 @@ $response = new Response();
$response->headers->set('Content-Type', 'text/plain');
$response->setContent($input);
----
|===
=== How does this work?

View File

@ -5,22 +5,21 @@ The following code is vulnerable to cross-site scripting because it returns an H
If you do not intend to send HTML code to clients, the vulnerability can be fixed by specifying the type of data returned in the response.
For example, you can use the `JsonResponse` class to return JSON messages securely.
[cols="a"]
|===
h| Non-compliant code example
|
[source,python]
==== Non-compliant code example
[source,python,diff-id=1,diff-type=noncompliant]
----
from django.http import HttpResponse
import json
def index(request):
json = json.dumps({ "data": request.GET.get("input") })
return HttpResponse(json) # Noncompliant
return HttpResponse(json)
----
h| Compliant solution
|
[source,python]
==== Compliant solution
[source,python,diff-id=1,diff-type=compliant]
----
from django.http import JsonResponse
@ -28,31 +27,28 @@ def index(request):
json = { "data": request.GET.get("input") }
return JsonResponse(json)
----
|===
It is also possible to set the content-type manually with the `content_type` parameter when creating an `HttpResponse` object.
[cols="a"]
|===
h| Non-compliant code example
|
[source,python]
==== Non-compliant code example
[source,python,diff-id=2,diff-type=noncompliant]
----
from django.http import HttpResponse
def index(request):
return HttpResponse(request.GET.get("input")) # Noncompliant
return HttpResponse(request.GET.get("input"))
----
h| Compliant solution
|
[source,python]
==== Compliant solution
[source,python,diff-id=2,diff-type=compliant]
----
from django.http import HttpResponse
def index(request):
return HttpResponse(request.GET.get("input"), content_type="text/plain")
----
|===
=== How does this work?

View File

@ -2,11 +2,9 @@
The following code is vulnerable to cross-site scripting because auto-escaping of special HTML characters has been disabled. The recommended way to fix this code is to move the HTML content to the template and to only inject the dynamic value. Therefore, it is not necessary to disable auto-escaping.
[cols="a"]
|===
h| Non-compliant code example
|
[source,python]
==== Non-compliant code example
[source,python,diff-id=1,diff-type=noncompliant]
----
from django.shortcuts import render
@ -16,16 +14,17 @@ def hello(request):
return render(request, 'hello.html', {'hello': hello})
----
[source,html]
[source,html,diff-id=2,diff-type=noncompliant]
----
<!doctype html>
{% autoescape false %}
{{ hello }} <!-- Noncompliant -->
{% endautoescape %}
----
h| Compliant solution
|
[source,python]
==== Compliant solution
[source,python,diff-id=1,diff-type=compliant]
----
from django.shortcuts import render
@ -34,12 +33,11 @@ def hello(request):
return render(request, 'hello.html', {'name': name})
----
[source,html]
[source,html,diff-id=2,diff-type=compliant]
----
<!doctype html>
<h1>Hello {{ name }}</h1>
----
|===
=== How does this work?
@ -53,11 +51,9 @@ Django template auto-escaping only takes care of HTML entity encoding. It does n
Auto-escaping can also be disabled at the application level and introduce XSS vulnerabilities even if `++{% autoescape false %}++` or `++|safe++` are not used.
[cols="a"]
|===
h| Non-compliant code example
|
[source,python]
==== Non-compliant code example
[source,python,diff-id=3,diff-type=noncompliant]
----
# settings.py
TEMPLATES = [
@ -70,9 +66,10 @@ TEMPLATES = [
},
]
----
h| Compliant solution
|
[source,python]
==== Compliant solution
[source,python,diff-id=3,diff-type=compliant]
----
# settings.py
TEMPLATES = [
@ -86,8 +83,6 @@ TEMPLATES = [
]
----
|===
=== Pitfalls
==== Variables in script blocks
@ -97,24 +92,22 @@ In such a case it is better to add the value to an attribute.
Another option is to use the `++json_script++` filter to insert a data structure that can then be accessed through the JavaScript code.
[cols="a"]
|===
h| Non-compliant code example
|
[source,html]
===== Non-compliant code example
[source,html,diff-id=4,diff-type=noncompliant]
----
<!doctype html>
<script> var name = '{{ name }}';</script>
----
h| Compliant solution
|
[source,html]
===== Compliant solution
[source,html,diff-id=4,diff-type=compliant]
----
<!doctype html>
{{ name\|json_script:"name-data" }}
<script> var name = JSON.parse(document.getElementById('name-data').textContent);</script>
----
|===
include::../../common/pitfalls/validation.adoc[]

View File

@ -5,23 +5,22 @@ The following code is vulnerable to cross-site scripting because it returns an H
If you do not intend to send HTML code to clients, the vulnerability can be fixed by specifying the type of data returned in the response.
For example, you can use the `jsonify` class to return JSON messages safely.
[cols="a"]
|===
h| Non-compliant code example
|
[source,python]
==== Non-compliant code example
[source,python,diff-id=1,diff-type=noncompliant]
----
from flask import make_response, request
import json
@app.route('/')
def index():
json = json.dumps({ "data": request.args.get("input") }) # Noncompliant
json = json.dumps({ "data": request.args.get("input") })
return make_response(json)
----
h| Compliant solution
|
[source,python]
==== Compliant solution
[source,python,diff-id=1,diff-type=compliant]
----
from flask import jsonify, request
@ -29,25 +28,23 @@ from flask import jsonify, request
def index():
return jsonify({ "data": request.args.get("input") })
----
|===
It is also possible to set the content-type manually with the `mimetype` parameter when calling the `make_response` function.
[cols="a"]
|===
h| Non-compliant code example
|
[source,python]
==== Non-compliant code example
[source,python,diff-id=2,diff-type=noncompliant]
----
from flask import make_response, request
@app.route('/')
def index():
return make_response(request.args.get("input")) # Noncompliant
return make_response(request.args.get("input"))
----
h| Compliant solution
|
[source,python]
==== Compliant solution
[source,python,diff-id=2,diff-type=compliant]
----
from flask import make_response, request
@ -55,7 +52,6 @@ from flask import make_response, request
def index():
return make_response(request.args.get("input"), mimetype="text/plain")
----
|===
=== How does this work?

View File

@ -3,11 +3,9 @@
The following code is vulnerable to cross-site scripting because auto-escaping of special HTML characters has been disabled.
The recommended way to fix this code is to move the HTML content to the template and to only inject the dynamic value. Therefore, it is not necessary to disable auto-escaping.
[cols="a"]
|===
h| Non-compliant code example
|
[source,python]
==== Non-compliant code example
[source,python,diff-id=1,diff-type=noncompliant]
----
from flask import render_template
@ -17,16 +15,17 @@ def hello(name=None):
return render_template('hello.html', hello=hello)
----
[source,html]
[source,html,diff-id=2,diff-type=noncompliant]
----
<!doctype html>
{% autoescape false %}
{{ hello }} <!-- Noncompliant -->
{% endautoescape %}
----
h| Compliant solution
|
[source,python]
==== Compliant solution
[source,python,diff-id=1,diff-type=compliant]
----
from flask import render_template
@ -35,12 +34,11 @@ def hello(name=None):
return render_template('hello.html', name=name)
----
[source,html]
[source,html,diff-id=2,diff-type=compliant]
----
<!doctype html>
<h1>Hello {{ name }}</h1>
----
|===
=== How does this work?
@ -58,24 +56,22 @@ Although auto-escaping drastically decreases the chance of introducing cross-sit
Injecting user-controlled values inside a ``++script++`` is dangerous. In such a case, the best practice is to add the value to an attribute.
Another option is to use the ``++tojson++`` filter to insert a data structure in the JavaScript code at render time.
[cols="a"]
|===
h| Non-compliant code example
|
[source,html]
===== Non-compliant code example
[source,html,diff-id=3,diff-type=noncompliant]
----
<!doctype html>
<script> var name = '{{ name }}';</script>
----
h| Compliant solution
|
[source,html]
===== Compliant solution
[source,html,diff-id=3,diff-type=compliant]
----
<!doctype html>
<script> var name = {{ name \| tojson }}</script>
----
|===
=== Going the extra mile

View File

@ -3,11 +3,9 @@
The following code is vulnerable to deserialization attacks because it
deserializes HTTP data without validating it first.
[cols="a"]
|===
h| Non-compliant code example
|
[source,csharp]
==== Non-compliant code example
[source,csharp,diff-id=1,diff-type=noncompliant]
----
public class Example : Controller
{
@ -20,9 +18,10 @@ public class Example : Controller
}
}
----
h| Compliant solution
|
[source,csharp]
==== Compliant solution
[source,csharp,diff-id=1,diff-type=compliant]
----
public class Example : Controller
{
@ -35,7 +34,6 @@ public class Example : Controller
}
}
----
|===
=== How does this work?
@ -62,4 +60,3 @@ these capabilities:
* `LosFormatter`
* `ObjectStateFormatter`

View File

@ -3,23 +3,22 @@
The following code is vulnerable to deserialization attacks because it
deserializes HTTP data without validating it first.
[cols="a"]
|===
h| Non-compliant code example
|
[source,java]
==== Non-compliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
public class RequestProcessor {
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
ServletInputStream servletIS = request.getInputStream();
ObjectInputStream objectIS = new ObjectInputStream(servletIS);
Object input = objectIS.readObject(); // Noncompliant
Object input = objectIS.readObject();
}
}
----
h| Compliant solution
|
[source,java]
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
public class SecureObjectInputStream extends ObjectInputStream {
@ -47,7 +46,6 @@ public class RequestProcessor {
}
----
|===
=== How does this work?

View File

@ -2,11 +2,9 @@
include::../../common/fix/code-rationale.adoc[]
[cols="a"]
|===
h| Non-compliant code example
|
[source,csharp]
==== Non-compliant code example
[source,csharp,diff-id=1,diff-type=noncompliant]
----
using System.Web;
using System.Web.Mvc;
@ -16,15 +14,16 @@ public class ExampleController : Controller
[HttpGet]
public IActionResult ImageFetch(string location)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(location); // Noncompliant
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(location);
return Ok();
}
}
----
h| Compliant solution
|
[source,csharp]
==== Compliant solution
[source,csharp,diff-id=1,diff-type=compliant]
----
using System.Web;
using System.Web.Mvc;
@ -50,6 +49,5 @@ public class ExampleController : Controller
}
}
----
|===
include::../../common/fix/how-does-this-work.adoc[]
include::../../common/fix/how-does-this-work.adoc[]

View File

@ -2,23 +2,22 @@
include::../../common/fix/code-rationale.adoc[]
[cols="a"]
|===
h| Non-compliant code example
|
[source,java]
==== Non-compliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String location = req.getParameter("url");
URL url = new URL(location);
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // Noncompliant
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
}
----
h| Compliant solution
|
[source,java]
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String location = req.getParameter("url");
@ -33,6 +32,5 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
}
----
|===
include::../../common/fix/how-does-this-work.adoc[]
include::../../common/fix/how-does-this-work.adoc[]

View File

@ -2,11 +2,9 @@
include::../../common/fix/code-rationale.adoc[]
[cols="a"]
|===
h| Non-compliant code example
|
[source,csharp]
==== Non-compliant code example
[source,csharp,diff-id=1,diff-type=noncompliant]
----
using System.Web;
using System.Web.Mvc;
@ -20,14 +18,15 @@ public class ExampleController : Controller
{
if (data != null)
{
_logger.Info("Log: " + data); // Noncompliant
_logger.Info("Log: " + data);
}
}
}
----
h| Compliant solution
|
[source,csharp]
==== Compliant solution
[source,csharp,diff-id=1,diff-type=compliant]
----
using System.Web;
using System.Web.Mvc;
@ -47,6 +46,5 @@ public class ExampleController : Controller
}
}
----
|===
include::../../common/fix/how-does-this-work.adoc[]
include::../../common/fix/how-does-this-work.adoc[]

View File

@ -2,11 +2,9 @@
include::../../common/fix/code-rationale.adoc[]
[cols="a"]
|===
h| Non-compliant code example
|
[source,java]
==== Non-compliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
private static final Logger logger = Logger.getLogger("Logger");
@ -14,13 +12,14 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
String data = request.getParameter("data");
if(data != null){
logger.log(Level.INFO, "Data: {0} ", data); // Noncompliant
logger.log(Level.INFO, "Data: {0} ", data);
}
}
----
h| Compliant solution
|
[source,java]
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
private static final Logger logger = Logger.getLogger("Logger");
@ -33,6 +32,5 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
}
}
----
|===
include::../../common/fix/how-does-this-work.adoc[]
include::../../common/fix/how-does-this-work.adoc[]

View File

@ -2,11 +2,9 @@
include::../../common/fix/code-rationale.adoc[]
[cols="a"]
|===
h| Non-compliant code example
|
[source,csharp]
==== Non-compliant code example
[source,csharp,diff-id=1,diff-type=noncompliant]
----
using System.Web;
using System.Web.Mvc;
@ -16,13 +14,14 @@ public class ExampleController : Controller
[HttpGet]
public void Redirect(string url)
{
Response.Redirect(url); // Noncompliant
Response.Redirect(url);
}
}
----
h| Compliant solution
|
[source,csharp]
==== Compliant solution
[source,csharp,diff-id=1,diff-type=compliant]
----
using System.Web;
using System.Web.Mvc;
@ -42,6 +41,5 @@ public class ExampleController : Controller
}
}
----
|===
include::../../common/fix/how-does-this-work.adoc[]
include::../../common/fix/how-does-this-work.adoc[]

View File

@ -2,20 +2,19 @@
include::../../common/fix/code-rationale.adoc[]
[cols="a"]
|===
h| Non-compliant code example
|
[source,java]
==== Non-compliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String location = req.getParameter("url");
resp.sendRedirect(location); // Noncompliant
resp.sendRedirect(location);
}
----
h| Compliant solution
|
[source,java]
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String location = req.getParameter("url");
@ -28,6 +27,5 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO
resp.sendRedirect(location);
}
----
|===
include::../../common/fix/how-does-this-work.adoc[]
include::../../common/fix/how-does-this-work.adoc[]

View File

@ -4,11 +4,9 @@ The following code is vulnerable to NoSQL injections because untrusted data is
concatenated to the `$where` operator. This operator indicates to the backend
that the expression needs to be interpreted, resulting in code injection.
[cols="a"]
|===
h| Non-compliant code example
|
[source,java]
==== Non-compliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
import com.mongodb.MongoClient;
import com.mongodb.DB;
@ -24,14 +22,15 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws Un
DBCollection collection = database.getCollection("exampleCollection");
BasicDBObject query = new BasicDBObject();
query.append("$where", "this.field == \"" + input + "\""); // Noncompliant
query.append("$where", "this.field == \"" + input + "\"");
collection.find(query);
}
----
h| Compliant solution
|
[source,java]
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
import com.mongodb.MongoClient;
import com.mongodb.DB;
@ -52,7 +51,6 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws Un
collection.find(query);
}
----
|===
=== How does this work?

View File

@ -3,11 +3,9 @@
The following code is vulnerable to arbitrary code execution because it compiles
and runs HTTP data.
[cols="a"]
|===
h| Non-compliant code example
|
[source,csharp]
==== Non-compliant code example
[source,csharp,diff-id=1,diff-type=noncompliant]
----
using System.CodeDom.Compiler;
@ -17,8 +15,8 @@ public class ExampleController : Controller
{
string code = @"
using System;
public class MyClass
{
public class MyClass
{
public void MyMethod()
{
Console.WriteLine(""" + message + @""");
@ -28,15 +26,16 @@ public class ExampleController : Controller
var provider = CodeDomProvider.CreateProvider("CSharp");
var compilerParameters = new CompilerParameters { ReferencedAssemblies = { "System.dll", "System.Runtime.dll" } };
var compilerResults = provider.CompileAssemblyFromSource(compilerParameters, code); // Noncompliant
var compilerResults = provider.CompileAssemblyFromSource(compilerParameters, code);
object myInstance = compilerResults.CompiledAssembly.CreateInstance("MyClass");
myInstance.GetType().GetMethod("MyMethod").Invoke(myInstance, new object[0]);
}
}
----
h| Compliant solution
|
[source,csharp]
==== Compliant solution
[source,csharp,diff-id=1,diff-type=compliant]
----
using System.CodeDom.Compiler;
@ -46,8 +45,8 @@ public class ExampleController : Controller
{
const string code = @"
using System;
public class MyClass
{
public class MyClass
{
public void MyMethod(string input)
{
Console.WriteLine(input);
@ -63,7 +62,6 @@ public class ExampleController : Controller
}
}
----
|===
=== How does this work?

View File

@ -3,11 +3,9 @@
The following code is vulnerable to arbitrary code execution because it compiles
and runs HTTP data.
[cols="a"]
|===
h| Non-compliant code example
|
[source,java]
==== Non-compliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
import org.codehaus.janino.ScriptEvaluator;
@ -17,14 +15,15 @@ public class ExampleController
@GetMapping(value = "/")
public void exec(@RequestParam("message") String message) throws IOException, InvocationTargetException {
ScriptEvaluator se = new ScriptEvaluator();
se.cook("System.out.println(\" + message \");"); // Noncompliant
se.cook("System.out.println(\" + message \");");
se.evaluate(null);
}
}
----
h| Compliant solution
|
[source,java]
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
import org.codehaus.janino.ScriptEvaluator;
@ -40,10 +39,8 @@ public class ExampleController
}
}
----
|===
=== How does this work?
include::../../common/fix/introduction.adoc[]

View File

@ -15,11 +15,9 @@ In this particular case, an attacker may remove files in `/some/folder` with the
'*' -exec rm -rf {} \;
----
[cols="a"]
|===
h| Non-compliant code example
|
[source,csharp]
==== Non-compliant code example
[source,csharp,diff-id=1,diff-type=noncompliant]
----
public class ExampleController : Controller
{
@ -27,14 +25,15 @@ public class ExampleController : Controller
{
Process p = new Process();
p.StartInfo.FileName = "/usr/bin/find";
p.StartInfo.Arguments = "/some/folder -iname " + args; // Noncompliant
p.StartInfo.Arguments = "/some/folder -iname " + args;
p.Start();
}
}
----
h| Compliant solution
|
[source,csharp]
==== Compliant solution
[source,csharp,diff-id=1,diff-type=compliant]
----
public class ExampleController : Controller
{
@ -49,15 +48,12 @@ public class ExampleController : Controller
}
}
----
|===
=== How does this work?
include::../../common/fix/introduction.adoc[]
Here `ArgumentList` takes care of escaping the passed arguments and internally
creates a single string given to the operating system when `System.Diagnostics.Process.Start()` is
called.

View File

@ -2,11 +2,9 @@
include::../../common/fix/code-rationale.adoc[]
[cols="a"]
|===
h| Non-compliant code example
|
[source,java]
==== Non-compliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
@Controller
public class ExampleController
@ -14,13 +12,14 @@ public class ExampleController
@GetMapping(value = "/find")
public void find(@RequestParam("filename") String filename) throws IOException {
CommandLine cmd = new CommandLine("/usr/bin/find . -iname " + filename); // Noncompliant
CommandLine cmd = new CommandLine("/usr/bin/find . -iname " + filename);
}
}
----
h| Compliant solution
|
[source,java]
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
@Controller
public class ExampleController
@ -33,12 +32,10 @@ public class ExampleController
}
}
----
|===
=== How does this work?
include::../../common/fix/introduction.adoc[]
Here `org.apache.commons.exec.CommandLine.addArguments(String[] addArguments)` takes care of escaping the passed arguments and internally
creates a single string given to the operating system to be executed.

View File

@ -2,11 +2,9 @@
include::../../common/fix/code-rationale.adoc[]
[cols="a"]
|===
h| Non-compliant code example
|
[source,java]
==== Non-compliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
@Controller
public class ExampleController
@ -14,13 +12,14 @@ public class ExampleController
@GetMapping(value = "/find")
public void find(@RequestParam("filename") String filename) throws IOException {
Runtime.getRuntime().exec("/usr/bin/find . -iname " + filename); // Noncompliant
Runtime.getRuntime().exec("/usr/bin/find . -iname " + filename);
}
}
----
h| Compliant solution
|
[source,java]
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
@Controller
public class ExampleController
@ -33,7 +32,6 @@ public class ExampleController
}
}
----
|===
++java.lang.Runtime++ is sometimes used over ++java.lang.ProcessBuilder++ due to ease of use. Flexibility in methods often introduces security issues as edge cases are easily missed. The compliant solution logic is also applied to ++java.lang.ProcessBuilder++.
@ -41,6 +39,5 @@ public class ExampleController
include::../../common/fix/introduction.adoc[]
Here `java.lang.Runtime.exec(String[] cmdarray)` takes care of escaping the passed arguments and internally
creates a single string given to the operating system to be executed.

View File

@ -5,11 +5,9 @@
include::../../common/fix/code-rationale.adoc[]
[cols="a"]
|===
h| Non-compliant code example
|
[source,csharp]
==== Non-compliant code example
[source,csharp,diff-id=1,diff-type=noncompliant]
----
public class ExampleController : Controller
{
@ -20,13 +18,14 @@ public class ExampleController : Controller
ZipArchiveEntry entry = entriesEnumerator.Current;
string destinationPath = Path.Combine(TargetDirectory, entry.FullName);
entry.ExtractToFile(destinationPath); // Noncompliant
entry.ExtractToFile(destinationPath);
}
}
----
h| Compliant solution
|
[source,csharp]
==== Compliant solution
[source,csharp,diff-id=1,diff-type=compliant]
----
public class ExampleController : Controller
{
@ -45,7 +44,6 @@ public class ExampleController : Controller
}
}
----
|===
=== How does this work?

View File

@ -5,11 +5,9 @@
include::../../common/fix/code-rationale.adoc[]
[cols="a"]
|===
h| Non-compliant code example
|
[source,java]
==== Non-compliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
public class Example {
@ -23,13 +21,14 @@ public class Example {
File file = new File(targetDirectory + entry.getName());
Files.copy(inputStream, file.toPath(), StandardCopyOption.REPLACE_EXISTING); // Noncompliant
Files.copy(inputStream, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
}
----
h| Compliant solution
|
[source,java]
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
public class Example {
@ -51,7 +50,6 @@ public class Example {
}
}
----
|===
=== How does this work?

View File

@ -2,11 +2,9 @@
include::../../common/fix/code-rationale.adoc[]
[cols="a"]
|===
h| Non-compliant code example
|
[source,csharp]
==== Non-compliant code example
[source,csharp,diff-id=1,diff-type=noncompliant]
----
using System.Web;
using System.Web.Mvc;
@ -18,16 +16,17 @@ public class ExampleController : Controller
{
if (Request.Cookies["ASP.NET_SessionId"] == null)
{
Response.Cookies.Append("ASP.NET_SessionId", cookie); // Noncompliant
Response.Cookies.Append("ASP.NET_SessionId", cookie);
}
return View("Welcome");
}
}
----
h| Compliant solution
|
[source,csharp]
==== Compliant solution
[source,csharp,diff-id=1,diff-type=compliant]
----
using System.Web;
using System.Web.Mvc;
@ -46,6 +45,5 @@ public class ExampleController : Controller
}
}
----
|===
include::../../common/fix/how-does-this-work.adoc[]
include::../../common/fix/how-does-this-work.adoc[]

View File

@ -2,11 +2,9 @@
include::../../common/fix/code-rationale.adoc[]
[cols="a"]
|===
h| Non-compliant code example
|
[source,java]
==== Non-compliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
Optional<Cookie> cookieOpt = Arrays.stream(request.getCookies())
@ -15,16 +13,17 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
if (!cookieOpt.isPresent()) {
String cookie = request.getParameter("cookie");
Cookie cookieObj = new Cookie("jsessionid", cookie); // Noncompliant
Cookie cookieObj = new Cookie("jsessionid", cookie);
response.addCookie(cookieObj);
}
response.sendRedirect("/welcome.jsp");
}
----
h| Compliant solution
|
[source,java]
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
Optional<Cookie> cookieOpt = Arrays.stream(request.getCookies())
@ -38,6 +37,5 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
}
}
----
|===
include::../../common/fix/how-does-this-work.adoc[]
include::../../common/fix/how-does-this-work.adoc[]