sl ocular
Ocular shell starts up and looks like this:
██████╗ ██████╗██╗ ██╗██╗ █████╗ ██████╗
██╔═══██╗██╔════╝██║ ██║██║ ██╔══██╗██╔══██╗
██║ ██║██║ ██║ ██║██║ ███████║██████╔╝
██║ ██║██║ ██║ ██║██║ ██╔══██║██╔══██╗
╚██████╔╝╚██████╗╚██████╔╝███████╗██║ ██║██║ ██║
╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝
Version: 0.3.114
Type `help` or `browse(help)` to begin
ocular>
ℹ️ Note: Following commands are now run on the Ocular Shell
https://github.com/DP-3T/dp3t-sdk-backend/releases/download/v1.1.0/dpppt-backend-sdk-ws.jar
val JARFILE = "/XXXX/dpppt-backend-sdk-ws.jar"
importCode(JARFILE)
run.securityprofile
//get dependencies (name, version) pair from manifest
def getDependencies(packageJsonFile : String) : Map[String,String] = {
val packageString = os.read(os.Path(packageJsonFile))
val packageData = ujson.read(packageString)
packageData.obj("dependencies").obj.toMap.map { case(k,v)=> k->v.toString.replaceAll("\"","") }
}
getDependencies(PACKAGE_FILE)
val source = cpg.method.filter(_.tag.name("EXPOSED_METHOD")).parameter
val api = cpg.method.name(".*=>.*").parameter
Table of Findings in text format:
cpg.finding.p
Title: JWT Unsafe Parsing: Unsafe parsing of JWT token via `token` to log in `DPPTJwtDecoder.decode`
Score: 5.0
Categories: [a3-sensitive-data-exposure]
Flow ids: [9219088073995584368]
Description: When `alg:none` is used, it becomes possible to skip signature check which may lead to authentication bypass
## Countermeasures
This vulnerability can be prevented by using `parseClaimsJws` method instead of `parse` method
## Additional information
**[CWE-347](https://cwe.mitre.org/data/definitions/347.html)**
**[OWASP-A3](https://owasp.org/www-project-top-ten/OWASP_Top_Ten_2017/Top_10-2017_A3-Sensitive_Data_Exposure)**
-------------------------------------
____________________________________________________________________________________
| tracked| lineNumber| method| file |
|===================================================================================|
| token | 38 | decode| org/dpppt/backend/sdk/ws/security/DPPTJwtDecoder.java|
| token | 39 | decode| org/dpppt/backend/sdk/ws/security/DPPTJwtDecoder.java|
| param0 | N/A | parse | io/jsonwebtoken/JwtParser.java |
Consumable JSON Format:
cpg.finding.toJsonPretty
Verify the name of the class than extends/implements org.springframework.security.oauth2.jwt.JwtDecoder
interface
cpg.typeDecl.l.filter(_.inheritsFromTypeFullName.contains("org.springframework.security.oauth2.jwt.JwtDecoder"))
res3: List[TypeDecl] = List(
TypeDecl(
id -> 2150L,
name -> "DPPTJwtDecoder",
fullName -> "org.dpppt.backend.sdk.ws.security.DPPTJwtDecoder",
isExternal -> false,
inheritsFromTypeFullName -> List(
"java.lang.Object",
"org.springframework.security.oauth2.jwt.JwtDecoder"
),
astParentType -> "NAMESPACE_BLOCK",
astParentFullName -> "org/dpppt/backend/sdk/ws/security/DPPTJwtDecoder.java:org.dpppt.backend.sdk.ws.security",
aliasTypeFullName -> None,
order -> null,
filename -> "org/dpppt/backend/sdk/ws/security/DPPTJwtDecoder.java"
)
)
val jwtImplClasszName = cpg.typeDecl.l.filter(_.inheritsFromTypeFullName.contains("org.springframework.security.oauth2.jwt.JwtDecoder")).head.fullName
jwtImplClasszName: String = "org.dpppt.backend.sdk.ws.security.DPPTJwtDecoder"
cpg.method.fullName(".*"+jwtImplClasszName+".*").l
res9: List[Method] = List(
Method(
id -> 5976128189582169760L,
name -> "setJwtValidator",
fullName -> "org.dpppt.backend.sdk.ws.security.DPPTJwtDecoder.setJwtValidator:void(org.springframework.security.oauth2.core.OAuth2TokenValidator)",
isExternal -> false,
signature -> "void(org.springframework.security.oauth2.core.OAuth2TokenValidator)",
astParentType -> "TYPE_DECL",
astParentFullName -> "org.dpppt.backend.sdk.ws.security.DPPTJwtDecoder",
lineNumber -> Some(32),
columnNumber -> None,
lineNumberEnd -> None,
columnNumberEnd -> None,
order -> null,
filename -> "org/dpppt/backend/sdk/ws/security/DPPTJwtDecoder.java",
hasMapping -> None,
depthFirstOrder -> Some(-8),
internalFlags -> Some(4),
binarySignature -> Some("(Lorg/springframework/security/oauth2/core/OAuth2TokenValidator;)V")
),
Method(
id -> 6387388624065243808L,
name -> "<init>",
fullName -> "org.dpppt.backend.sdk.ws.security.DPPTJwtDecoder.<init>:void(java.security.PublicKey)",
isExternal -> false,
signature -> "void(java.security.PublicKey)",
astParentType -> "TYPE_DECL",
astParentFullName -> "org.dpppt.backend.sdk.ws.security.DPPTJwtDecoder",
lineNumber -> Some(27),
columnNumber -> None,
lineNumberEnd -> None,
columnNumberEnd -> None,
order -> null,
filename -> "org/dpppt/backend/sdk/ws/security/DPPTJwtDecoder.java",
hasMapping -> None,
depthFirstOrder -> Some(-22),
internalFlags -> Some(4),
binarySignature -> Some("(Ljava/security/PublicKey;)V")
),
Method(
id -> 2733168305168762944L,
name -> "decode",
fullName -> "org.dpppt.backend.sdk.ws.security.DPPTJwtDecoder.decode:org.springframework.security.oauth2.jwt.Jwt(java.lang.String)",
isExternal -> false,
signature -> "org.springframework.security.oauth2.jwt.Jwt(java.lang.String)",
astParentType -> "TYPE_DECL",
astParentFullName -> "org.dpppt.backend.sdk.ws.security.DPPTJwtDecoder",
lineNumber -> Some(38),
columnNumber -> None,
lineNumberEnd -> None,
columnNumberEnd -> None,
order -> null,
filename -> "org/dpppt/backend/sdk/ws/security/DPPTJwtDecoder.java",
hasMapping -> None,
depthFirstOrder -> Some(-139),
internalFlags -> Some(4),
binarySignature -> Some("(Ljava/lang/String;)Lorg/springframework/security/oauth2/jwt/Jwt;")
)
)
Conduct dataflow analysis from attacker controlled source (decode
) to security sensitive sink (parse
)
var source = cpg.method.fullName(".*org.dpppt.backend.sdk.ws.security.DPPTJwtDecoder.decode.*").parameter
var sink = cpg.method.fullName(".*parse(.*").parameter
sink.reachableBy(source).flows.p
res7: List[String] = List(
""" _______________________________________________________________________________________________________
| tracked | lineNumber| method | file |
|======================================================================================================|
| this | 38 | decode | org/dpppt/backend/sdk/ws/security/DPPTJwtDecoder.java|
| this.parser| 39 | decode | org/dpppt/backend/sdk/ws/security/DPPTJwtDecoder.java|
| param1 | N/A | <operator>.assignment| N/A |
| param0 | N/A | <operator>.assignment| N/A |
| $r0 | 39 | decode | org/dpppt/backend/sdk/ws/security/DPPTJwtDecoder.java|
| $r0 | 39 | decode | org/dpppt/backend/sdk/ws/security/DPPTJwtDecoder.java|
| this | N/A | parse | io/jsonwebtoken/JwtParser.java |
""",
""" ____________________________________________________________________________________________
| tracked| lineNumber| method | file |
|===========================================================================================|
| token | 38 | decode | org/dpppt/backend/sdk/ws/security/DPPTJwtDecoder.java|
| token | 39 | decode | org/dpppt/backend/sdk/ws/security/DPPTJwtDecoder.java|
| param0 | N/A | parse | io/jsonwebtoken/JwtParser.java |
"""