Skip to content
This repository was archived by the owner on Oct 27, 2021. It is now read-only.

Commit

Permalink
Merge pull request #68 from maltek/cert-checks
Browse files Browse the repository at this point in the history
add a query for disabled ssl certificate checks in java
  • Loading branch information
itsacoderepo authored Apr 3, 2021
2 parents f67fe02 + ea7a2e3 commit d24228f
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/main/scala/io/joern/scanners/QueryTags.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ object QueryTags {

val alloc = "alloc"
val badfn = "badfn"
val badimpl = "badimpl"
val setxid = "setxid"
val metrics = "metrics"
val uaf = "uaf"
Expand Down
68 changes: 68 additions & 0 deletions src/main/scala/io/joern/scanners/java/CertificateChecks.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package io.joern.scanners.java

import io.joern.scanners.{Crew, QueryTags}
import io.shiftleft.codepropertygraph.generated._
import io.shiftleft.console._
import io.shiftleft.macros.QueryMacros._
import io.shiftleft.semanticcpg.language._
import overflowdb.traversal.Traversal

object CertificateChecks extends QueryBundle {

implicit val resolver: ICallResolver = NoResolve

@q
def certChecks(): Query =
Query.make(
name = "ineffective-certificate-check",
author = Crew.malte,
title =
"Ineffective Certificate Validation: The validation result is always positive",
description =
"""
|A certificate validation function is implemented as a function that only consists of a prologue where local
|variables are initialized to arguments, followed by a (positive) return statement.
|""".stripMargin,
score = 6,
withStrRep({ cpg =>
val validators = Map(
// javax.net.ssl.HostnameVerifier
"verify" -> "boolean(java.lang.String,javax.net.ssl.SSLSession)",
// javax.net.ssl.X509ExtendedTrustManager
"checkClientTrusted" -> "void(java.security.cert.X509Certificate[],java.lang.String,java.net.Socket)",
"checkClientTrusted" -> "void(java.security.cert.X509Certificate[],java.lang.String,javax.net.ssl.SSLEngine)",
"checkServerTrusted" -> "void(java.security.cert.X509Certificate[],java.lang.String,java.net.Socket)",
"checkServerTrusted" -> "void(java.security.cert.X509Certificate[],java.lang.String,javax.net.ssl.SSLEngine)",
)

// skip over arguments getting copied to local variables
def isPrologue(node: nodes.CfgNode): Boolean = node match {
case id: nodes.Identifier =>
id.refsTo.forall(_.isInstanceOf[nodes.Local])
case c: nodes.Call =>
c.methodFullName == Operators.assignment && c.argument.forall(
isPrologue
)
case _ => false
}
def skipPrologue(node: nodes.CfgNode): Traversal[nodes.CfgNode] =
node.repeat(_.cfgNext)(_.until(_.filter(!isPrologue(_))))

// format: off
cpg.method.
nameExact(validators.keys.toSeq: _*).
signatureExact(validators.values.toSeq: _*).
cfgFirst.
flatMap(skipPrologue).
filter {
case lit: nodes.Literal => // return true:
lit.code == "1" && lit.cfgNext
.forall(_.isInstanceOf[nodes.Return])
case _: nodes.Return => true // void return
case _ => false
}
// format: on
}),
tags = List(QueryTags.badimpl)
)
}

0 comments on commit d24228f

Please sign in to comment.