-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PHP: Add api tagger + include packages in probablesinks
- Loading branch information
Dattaprasad Mundada
authored and
Dattaprasad Mundada
committed
Mar 26, 2024
1 parent
0210435
commit 22ecd13
Showing
3 changed files
with
95 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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 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
71 changes: 71 additions & 0 deletions
71
src/main/scala/ai/privado/languageEngine/php/tagger/sink/APITagger.scala
This file contains 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,71 @@ | ||
package ai.privado.languageEngine.php.tagger.sink | ||
|
||
import ai.privado.cache.RuleCache | ||
import ai.privado.entrypoint.{PrivadoInput, ScanProcessor} | ||
import ai.privado.languageEngine.java.language.{NodeStarters, StepsForProperty} | ||
import ai.privado.languageEngine.java.semantic.JavaSemanticGenerator | ||
import ai.privado.metric.MetricHandler | ||
import ai.privado.model.{Constants, NodeType, RuleInfo} | ||
import ai.privado.tagger.PrivadoParallelCpgPass | ||
import ai.privado.tagger.utility.APITaggerUtility.sinkTagger | ||
import ai.privado.utility.Utilities | ||
import io.circe.Json | ||
import io.joern.dataflowengineoss.queryengine.{EngineConfig, EngineContext} | ||
import io.shiftleft.codepropertygraph.generated.nodes.Call | ||
import io.shiftleft.codepropertygraph.generated.{Cpg, Operators} | ||
import io.shiftleft.semanticcpg.language.* | ||
import org.slf4j.LoggerFactory | ||
|
||
import scala.jdk.CollectionConverters.CollectionHasAsScala | ||
import java.util.Calendar | ||
|
||
class APITagger(cpg: Cpg, ruleCache: RuleCache, privadoInput: PrivadoInput) | ||
extends PrivadoParallelCpgPass[RuleInfo](cpg) { | ||
private val logger = LoggerFactory.getLogger(this.getClass) | ||
val cacheCall: List[Call] = cpg.call.where(_.nameNot(Operators.ALL.asScala.toSeq: _*)).l | ||
val constructNameCall: List[Call] = cacheCall.where(_.name("__construct")).l | ||
|
||
val APISINKS_REGEX: String = ruleCache.getSystemConfigByKey(Constants.apiSinks) | ||
|
||
val apis: List[Call] = cacheCall.name("(?i)" + APISINKS_REGEX).l | ||
val constructApis: List[Call] = constructNameCall.where(_.methodFullName("(?i).*" + APISINKS_REGEX + "(->)__construct")).l | ||
|
||
MetricHandler.metricsData("apiTaggerVersion") = Json.fromString("Common HTTP Libraries Used") | ||
implicit val engineContext: EngineContext = Utilities.getEngineContext(privadoInput, 4) | ||
val commonHttpPackages: String = ruleCache.getSystemConfigByKey(Constants.apiHttpLibraries) | ||
|
||
val httpApis: List[Call] = (apis ++ constructApis) | ||
.or(_.methodFullName(commonHttpPackages), _.filter(_.dynamicTypeHintFullName.exists(_.matches(commonHttpPackages)))) | ||
.l | ||
|
||
// Support to use `identifier` in API's | ||
val identifierRegex: String = ruleCache.getSystemConfigByKey(Constants.apiIdentifier) | ||
|
||
override def generateParts(): Array[_ <: AnyRef] = { | ||
ruleCache.getRule.sinks | ||
.filter(rule => rule.nodeType.equals(NodeType.API)) | ||
.toArray | ||
} | ||
|
||
override def runOnPart(builder: DiffGraphBuilder, ruleInfo: RuleInfo): Unit = { | ||
val apiInternalSources = cpg.literal.code("(?:\"|'){0,1}(" + ruleInfo.combinedRulePattern + ")(?:\"|'){0,1}").l | ||
val propertySources = cpg.property.filter(p => p.value matches (ruleInfo.combinedRulePattern)).usedAt.l | ||
|
||
val identifierSource = { | ||
if (!ruleInfo.id.equals(Constants.internalAPIRuleId)) | ||
cpg.identifier(identifierRegex).l ++ cpg.property.filter(p => p.name matches (identifierRegex)).usedAt.l | ||
else | ||
List() | ||
} | ||
|
||
logger.debug("Using Enhanced API tagger to find API sinks") | ||
sinkTagger( | ||
apiInternalSources ++ propertySources ++ identifierSource, | ||
(httpApis).distinct, | ||
builder, | ||
ruleInfo, | ||
ruleCache, | ||
privadoInput | ||
) | ||
} | ||
} |