|
| 1 | +/** |
| 2 | + * @name JXBrowser with disabled certificate validation |
| 3 | + * @description Insecure configuration of JXBrowser disables certificate validation making the app vulnerable to man-in-the-middle attacks. |
| 4 | + * @kind problem |
| 5 | + * @id java/jxbrowser/disabled-certificate-validation |
| 6 | + * @tags security |
| 7 | + * external/cwe-295 |
| 8 | + */ |
| 9 | + |
| 10 | +import java |
| 11 | +import semmle.code.java.security.Encryption |
| 12 | +import semmle.code.java.dataflow.TaintTracking |
| 13 | + |
| 14 | +/* |
| 15 | + * This query is version specific to JXBrowser 6.x.x. The version is indirectly detected. |
| 16 | + * In version 6.x.x the `Browser` class is in a different package compared to version 7.x.x. |
| 17 | + */ |
| 18 | + |
| 19 | +/** The `com.teamdev.jxbrowser.chromium.Browser` class. */ |
| 20 | +private class JXBrowser extends RefType { |
| 21 | + JXBrowser() { this.hasQualifiedName("com.teamdev.jxbrowser.chromium", "Browser") } |
| 22 | +} |
| 23 | + |
| 24 | +/** The `setLoadHandler` method on the `com.teamdev.jxbrowser.chromium.Browser` class. */ |
| 25 | +private class JXBrowserSetLoadHandler extends Method { |
| 26 | + JXBrowserSetLoadHandler() { |
| 27 | + this.hasName("setLoadHandler") and this.getDeclaringType() instanceof JXBrowser |
| 28 | + } |
| 29 | +} |
| 30 | + |
| 31 | +/** The `com.teamdev.jxbrowser.chromium.LoadHandler` interface. */ |
| 32 | +private class JXBrowserLoadHandler extends RefType { |
| 33 | + JXBrowserLoadHandler() { this.hasQualifiedName("com.teamdev.jxbrowser.chromium", "LoadHandler") } |
| 34 | +} |
| 35 | + |
| 36 | +private predicate isOnCertificateErrorMethodSafe(Method m) { |
| 37 | + forex(ReturnStmt rs | rs.getEnclosingCallable() = m | |
| 38 | + rs.getResult().(CompileTimeConstantExpr).getBooleanValue() = true |
| 39 | + ) |
| 40 | +} |
| 41 | + |
| 42 | +/** A class that securely implements the `com.teamdev.jxbrowser.chromium.LoadHandler` interface. */ |
| 43 | +private class JXBrowserSafeLoadHandler extends RefType { |
| 44 | + JXBrowserSafeLoadHandler() { |
| 45 | + this.getASupertype() instanceof JXBrowserLoadHandler and |
| 46 | + exists(Method m | m.hasName("onCertificateError") and m.getDeclaringType() = this | |
| 47 | + isOnCertificateErrorMethodSafe(m) |
| 48 | + ) |
| 49 | + } |
| 50 | +} |
| 51 | + |
| 52 | +private class JXBrowserTaintTracking extends TaintTracking::Configuration { |
| 53 | + JXBrowserTaintTracking() { this = "JXBrowserTaintTracking" } |
| 54 | + |
| 55 | + override predicate isSource(DataFlow::Node src) { |
| 56 | + exists(ClassInstanceExpr newJXBrowser | newJXBrowser.getConstructedType() instanceof JXBrowser | |
| 57 | + newJXBrowser = src.asExpr() |
| 58 | + ) |
| 59 | + } |
| 60 | + |
| 61 | + override predicate isSink(DataFlow::Node sink) { |
| 62 | + exists(MethodAccess ma | ma.getMethod() instanceof JXBrowserSetLoadHandler | |
| 63 | + ma.getArgument(0).getType() instanceof JXBrowserSafeLoadHandler and |
| 64 | + ma.getQualifier() = sink.asExpr() |
| 65 | + ) |
| 66 | + } |
| 67 | +} |
| 68 | + |
| 69 | +from JXBrowserTaintTracking cfg, DataFlow::Node src |
| 70 | +where |
| 71 | + cfg.isSource(src) and |
| 72 | + not cfg.hasFlow(src, _) |
| 73 | +select src, "This JXBrowser instance allows man-in-the-middle attacks." |
0 commit comments