-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Java: Trust Boundary Violation Query #13413
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
egregius313
merged 24 commits into
github:main
from
egregius313:egregius313/trust-boundary
Aug 18, 2023
Merged
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
76438f1
Trust Boundary Query
egregius313 a8b7e70
Convert trust boundary models to MaD
egregius313 1537050
Add missing security severity
egregius313 3e7444c
Style fixes
egregius313 b9f2da7
Comments and import fixes
egregius313 ab9f024
Add taint steps for HTML encoding methods
egregius313 2aba425
TrustBoundary test ql file
egregius313 f58590c
Trust Boundary Work
egregius313 97d6e82
Stubs for `org.owasp.esapi`
egregius313 55fae2d
Added ESAPI sanitizer
egregius313 b567ec8
Documentation
egregius313 172b8a6
Documentation fixes
egregius313 52ebf9f
Java: Add trust boundary change note
egregius313 929090a
Typos and style fixes
egregius313 a3a4c31
Replace servlet source node with RemoteFlowSource
egregius313 e22a67e
Remove unnecessary methods
egregius313 60642c5
Use non-extending subtype
egregius313 a36c12f
Add trust-boundary-violation sink kind
egregius313 b305962
Use more appropriate description
egregius313 d468ea9
Add default sanitizers
egregius313 f53496b
Added documentation for trust-boundary-violation sink
egregius313 655a984
Remove `escapeHTML` models
egregius313 4eb1035
Documentation fixes
egregius313 8d88af1
Apply docs review suggestions
egregius313 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
extensions: | ||
- addsTo: | ||
pack: codeql/java-all | ||
extensible: summaryModel | ||
data: | ||
- ["org.apache.commons.lang", "StringEscapeUtils", true, "escapeHtml", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] | ||
- ["org.apache.commons.lang", "StringEscapeUtils", true, "escapeHtml", "(Writer,String)", "", "Argument[1]", "Argument[0]", "taint", "manual"] | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
extensions: | ||
- addsTo: | ||
pack: codeql/java-all | ||
extensible: sinkModel | ||
data: | ||
- ["org.apache.struts2.dispatcher", "SessionMap", False, "put", "", "", "Argument[0..1]", "trust-boundary-violation", "manual"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
extensions: | ||
- addsTo: | ||
pack: codeql/java-all | ||
extensible: sinkModel | ||
data: | ||
- ["org.apache.struts2.interceptor", "SessionAware", False, "setSession", "", "", "Argument[0]", "trust-boundary-violation", "manual"] | ||
- ["org.apache.struts2.interceptor", "SessionAware", False, "withSession", "", "", "Argument[0]", "trust-boundary-violation", "manual"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
extensions: | ||
- addsTo: | ||
pack: codeql/java-all | ||
extensible: summaryModel | ||
data: | ||
- ["org.owasp.esapi", "Encoder", true, "encodeForHTML", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/** Classes and predicates for reasoning about the `owasp.easpi` package. */ | ||
|
||
import java | ||
|
||
/** | ||
* The `org.owasp.esapi.Validator` interface. | ||
*/ | ||
class EsapiValidator extends RefType { | ||
EsapiValidator() { this.hasQualifiedName("org.owasp.esapi", "Validator") } | ||
} | ||
|
||
/** | ||
* The methods of `org.owasp.esapi.Validator` which validate data. | ||
*/ | ||
class EsapiIsValidMethod extends Method { | ||
EsapiIsValidMethod() { | ||
this.getDeclaringType() instanceof EsapiValidator and | ||
this.hasName([ | ||
"isValidCreditCard", "isValidDate", "isValidDirectoryPath", "isValidDouble", | ||
"isValidFileContent", "isValidFileName", "isValidInput", "isValidInteger", | ||
"isValidListItem", "isValidNumber", "isValidPrintable", "isValidRedirectLocation", | ||
"isValidSafeHTML", "isValidURI" | ||
]) | ||
} | ||
} | ||
|
||
/** | ||
* The methods of `org.owasp.esapi.Validator` which return validated data. | ||
*/ | ||
class EsapiGetValidMethod extends Method { | ||
EsapiGetValidMethod() { | ||
this.getDeclaringType() instanceof EsapiValidator and | ||
this.hasName([ | ||
"getValidCreditCard", "getValidDate", "getValidDirectoryPath", "getValidDouble", | ||
"getValidFileContent", "getValidFileName", "getValidInput", "getValidInteger", | ||
"getValidListItem", "getValidNumber", "getValidPrintable", "getValidRedirectLocation", | ||
"getValidSafeHTML", "getValidURI" | ||
]) | ||
} | ||
} |
70 changes: 70 additions & 0 deletions
70
java/ql/lib/semmle/code/java/security/TrustBoundaryViolationQuery.qll
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/** Provides classes and predicates to reason about trust boundary violations */ | ||
|
||
import java | ||
private import semmle.code.java.dataflow.DataFlow | ||
private import semmle.code.java.controlflow.Guards | ||
private import semmle.code.java.dataflow.ExternalFlow | ||
private import semmle.code.java.dataflow.FlowSources | ||
private import semmle.code.java.frameworks.owasp.Esapi | ||
|
||
/** | ||
* A source of data that crosses a trust boundary. | ||
*/ | ||
abstract class TrustBoundaryViolationSource extends DataFlow::Node { } | ||
|
||
private class RemoteSource extends TrustBoundaryViolationSource instanceof RemoteFlowSource { } | ||
|
||
/** | ||
* A sink for data that crosses a trust boundary. | ||
*/ | ||
class TrustBoundaryViolationSink extends DataFlow::Node { | ||
TrustBoundaryViolationSink() { sinkNode(this, "trust-boundary-violation") } | ||
} | ||
|
||
/** | ||
* A sanitizer for data that crosses a trust boundary. | ||
*/ | ||
abstract class TrustBoundaryValidationSanitizer extends DataFlow::Node { } | ||
|
||
/** | ||
* A node validated by an OWASP ESAPI validation method. | ||
*/ | ||
private class EsapiValidatedInputSanitizer extends TrustBoundaryValidationSanitizer { | ||
EsapiValidatedInputSanitizer() { | ||
this = DataFlow::BarrierGuard<esapiIsValidData/3>::getABarrierNode() or | ||
this.asExpr().(MethodAccess).getMethod() instanceof EsapiGetValidMethod | ||
} | ||
} | ||
|
||
/** | ||
* Holds if `g` is a guard that checks that `e` is valid data according to an OWASP ESAPI validation method. | ||
*/ | ||
private predicate esapiIsValidData(Guard g, Expr e, boolean branch) { | ||
branch = true and | ||
exists(MethodAccess ma | ma.getMethod() instanceof EsapiIsValidMethod | | ||
g = ma and | ||
e = ma.getArgument(1) | ||
) | ||
} | ||
|
||
/** | ||
* Taint tracking for data that crosses a trust boundary. | ||
*/ | ||
module TrustBoundaryConfig implements DataFlow::ConfigSig { | ||
predicate isSource(DataFlow::Node source) { source instanceof TrustBoundaryViolationSource } | ||
|
||
predicate isBarrier(DataFlow::Node node) { | ||
egregius313 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
node instanceof TrustBoundaryValidationSanitizer or | ||
node.getType() instanceof HttpServletSession or | ||
node.getType() instanceof NumberType or | ||
node.getType() instanceof PrimitiveType or | ||
node.getType() instanceof BoxedType | ||
} | ||
|
||
predicate isSink(DataFlow::Node sink) { sink instanceof TrustBoundaryViolationSink } | ||
} | ||
|
||
/** | ||
* Taint-tracking flow for values which cross a trust boundary. | ||
*/ | ||
module TrustBoundaryFlow = TaintTracking::Global<TrustBoundaryConfig>; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
public void doGet(HttpServletRequest request, HttpServletResponse response) { | ||
String username = request.getParameter("username"); | ||
|
||
if (validator.isValidInput("HTTP parameter", username, "username", 20, false)) { | ||
// GOOD: The input is sanitized before being written to the session. | ||
request.getSession().setAttribute("username", username); | ||
} | ||
} |
48 changes: 48 additions & 0 deletions
48
java/ql/src/Security/CWE/CWE-501/TrustBoundaryViolation.qhelp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<!DOCTYPE qhelp PUBLIC | ||
"-//Semmle//qhelp//EN" | ||
"qhelp.dtd"> | ||
<qhelp> | ||
<overview> | ||
<p> | ||
A trust boundary violation occurs when a value is passed from a less trusted context to a more trusted context. | ||
</p> | ||
|
||
<p> | ||
For example, a value that is generated by a less trusted source, such as a user, may be passed to a more trusted | ||
source, such as a system process. If the less trusted source is malicious, then the value may be crafted to | ||
exploit the more trusted source. | ||
</p> | ||
|
||
<p> | ||
Trust boundary violations are often caused by a failure to validate input. For example, if a web application | ||
accepts a cookie from a user, then the application should validate the cookie before using it. If the cookie is | ||
not validated, then the user may be able to craft a malicious cookie that exploits the application. | ||
</p> | ||
</overview> | ||
|
||
<recommendation> | ||
<p> | ||
To maintain a trust boundary, validate data from less trusted sources before use. | ||
</p> | ||
</recommendation> | ||
|
||
<example> | ||
<p> | ||
In the first (bad) example, the server accepts a parameter from the user, then uses it to set the username without validation. | ||
</p> | ||
<sample src="TrustBoundaryVulnerable.java" /> | ||
|
||
<p> | ||
In the second (good) example, the server validates the parameter from the user, then uses it to set the username. | ||
</p> | ||
<sample src="TrustBoundaryFixed.java" /> | ||
|
||
</example> | ||
|
||
<references> | ||
<li> | ||
Wikipedia: <a href="http://en.wikipedia.org/wiki/Trust_boundary">Trust boundary</a>. | ||
</li> | ||
</references> | ||
|
||
</qhelp> |
20 changes: 20 additions & 0 deletions
20
java/ql/src/Security/CWE/CWE-501/TrustBoundaryViolation.ql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/** | ||
* @id java/trust-boundary-violation | ||
* @name Trust boundary violation | ||
* @description Modifying the HTTP session attributes based on data from an untrusted source may violate a trust boundary. | ||
* @kind path-problem | ||
* @problem.severity error | ||
* @security-severity 8.8 | ||
* @precision medium | ||
* @tags security | ||
* external/cwe/cwe-501 | ||
*/ | ||
|
||
import java | ||
import semmle.code.java.security.TrustBoundaryViolationQuery | ||
import TrustBoundaryFlow::PathGraph | ||
|
||
from TrustBoundaryFlow::PathNode source, TrustBoundaryFlow::PathNode sink | ||
where TrustBoundaryFlow::flowPath(source, sink) | ||
select sink.getNode(), sink, source, | ||
"This servlet reads data from a remote source and writes it to a session variable." |
6 changes: 6 additions & 0 deletions
6
java/ql/src/Security/CWE/CWE-501/TrustBoundaryVulnerable.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
public void doGet(HttpServletRequest request, HttpServletResponse response) { | ||
String username = request.getParameter("username"); | ||
|
||
// BAD: The input is written to the session without being sanitized. | ||
request.getSession().setAttribute("username", username); | ||
} |
5 changes: 5 additions & 0 deletions
5
java/ql/src/change-notes/2023-07-25-trust-boundary-violation-query.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
category: newQuery | ||
--- | ||
* Added the `java/trust-boundary-violation` query to detect trust boundary violations between HTTP requests and the HTTP session. Also added the `trust-boundary-violation` sink kind for sinks which may cross a trust boundary, such as calls to the `HttpSession#setAttribute` method. | ||
|
2 changes: 2 additions & 0 deletions
2
java/ql/test/query-tests/security/CWE-501/TrustBoundaryViolations.expected
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
failures | ||
testFailures |
35 changes: 35 additions & 0 deletions
35
java/ql/test/query-tests/security/CWE-501/TrustBoundaryViolations.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import java.io.IOException; | ||
import javax.servlet.http.HttpServlet; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
import org.owasp.esapi.Validator; | ||
|
||
public class TrustBoundaryViolations extends HttpServlet { | ||
Validator validator; | ||
|
||
public void doGet(HttpServletRequest request, HttpServletResponse response) { | ||
String input = request.getParameter("input"); | ||
|
||
// BAD: The input is written to the session without being sanitized. | ||
request.getSession().setAttribute("input", input); // $ hasTaintFlow | ||
|
||
String input2 = request.getParameter("input2"); | ||
|
||
try { | ||
String sanitized = validator.getValidInput("HTTP parameter", input2, "HTTPParameterValue", 100, false); | ||
// GOOD: The input is sanitized before being written to the session. | ||
request.getSession().setAttribute("input2", sanitized); | ||
|
||
} catch (Exception e) { | ||
} | ||
|
||
try { | ||
String input3 = request.getParameter("input3"); | ||
if (validator.isValidInput("HTTP parameter", input3, "HTTPParameterValue", 100, false)) { | ||
// GOOD: The input is sanitized before being written to the session. | ||
request.getSession().setAttribute("input3", input3); | ||
} | ||
} catch (Exception e) { | ||
} | ||
} | ||
} |
4 changes: 4 additions & 0 deletions
4
java/ql/test/query-tests/security/CWE-501/TrustBoundaryViolations.ql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import java | ||
import semmle.code.java.security.TrustBoundaryViolationQuery | ||
import TestUtilities.InlineFlowTest | ||
import TaintFlowTest<TrustBoundaryConfig> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/esapi-2.0.1:${testdir}/../../../stubs/javax-servlet-2.5 |
5 changes: 5 additions & 0 deletions
5
java/ql/test/stubs/esapi-2.0.1/org/owasp/esapi/ValidationErrorList.java
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.