10: Create ImplicitIntentsPlugin
This commit is contained in:
@@ -2,6 +2,7 @@ package com.bartek.esa.core.di;
|
|||||||
|
|
||||||
import com.bartek.esa.core.desc.provider.DescriptionProvider;
|
import com.bartek.esa.core.desc.provider.DescriptionProvider;
|
||||||
import com.bartek.esa.core.executor.PluginExecutor;
|
import com.bartek.esa.core.executor.PluginExecutor;
|
||||||
|
import com.bartek.esa.core.java.JavaSyntaxRegexProvider;
|
||||||
import com.bartek.esa.core.xml.XmlHelper;
|
import com.bartek.esa.core.xml.XmlHelper;
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
import dagger.Provides;
|
import dagger.Provides;
|
||||||
@@ -19,6 +20,11 @@ public class CoreModule {
|
|||||||
return new DescriptionProvider();
|
return new DescriptionProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
public JavaSyntaxRegexProvider javaSyntaxRegexProvider() {
|
||||||
|
return new JavaSyntaxRegexProvider();
|
||||||
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
public XmlHelper xmlHelper() {
|
public XmlHelper xmlHelper() {
|
||||||
return new XmlHelper();
|
return new XmlHelper();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.bartek.esa.core.di;
|
package com.bartek.esa.core.di;
|
||||||
|
|
||||||
import com.bartek.esa.core.archetype.Plugin;
|
import com.bartek.esa.core.archetype.Plugin;
|
||||||
|
import com.bartek.esa.core.java.JavaSyntaxRegexProvider;
|
||||||
import com.bartek.esa.core.plugin.*;
|
import com.bartek.esa.core.plugin.*;
|
||||||
import com.bartek.esa.core.xml.XmlHelper;
|
import com.bartek.esa.core.xml.XmlHelper;
|
||||||
import com.bartek.esa.file.matcher.GlobMatcher;
|
import com.bartek.esa.file.matcher.GlobMatcher;
|
||||||
@@ -50,4 +51,10 @@ public class PluginModule {
|
|||||||
public Plugin secureRandomPlugin(GlobMatcher globMatcher, XmlHelper xmlHelper) {
|
public Plugin secureRandomPlugin(GlobMatcher globMatcher, XmlHelper xmlHelper) {
|
||||||
return new SecureRandomPlugin(globMatcher, xmlHelper);
|
return new SecureRandomPlugin(globMatcher, xmlHelper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@IntoSet
|
||||||
|
public Plugin implicitIntentsPlugin(GlobMatcher globMatcher, XmlHelper xmlHelper, JavaSyntaxRegexProvider javaSyntaxRegexProvider) {
|
||||||
|
return new ImplicitIntentsPlugin(globMatcher, xmlHelper, javaSyntaxRegexProvider);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.bartek.esa.core.java;
|
||||||
|
|
||||||
|
import com.github.javaparser.ast.expr.Expression;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class JavaSyntaxRegexProvider {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public JavaSyntaxRegexProvider() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pattern constant() {
|
||||||
|
return Pattern.compile("^[A-Z0-9_$]*$");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isConstant(Expression expression) {
|
||||||
|
String value = expression.toString();
|
||||||
|
if(expression.isNameExpr() && constant().matcher(value).matches()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(expression.isFieldAccessExpr()) {
|
||||||
|
return constant().matcher(expression.asFieldAccessExpr().getName().getIdentifier()).matches();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package com.bartek.esa.core.plugin;
|
||||||
|
|
||||||
|
import com.bartek.esa.core.archetype.JavaPlugin;
|
||||||
|
import com.bartek.esa.core.java.JavaSyntaxRegexProvider;
|
||||||
|
import com.bartek.esa.core.model.enumeration.Severity;
|
||||||
|
import com.bartek.esa.core.xml.XmlHelper;
|
||||||
|
import com.bartek.esa.file.matcher.GlobMatcher;
|
||||||
|
import com.github.javaparser.ast.CompilationUnit;
|
||||||
|
import com.github.javaparser.ast.NodeList;
|
||||||
|
import com.github.javaparser.ast.body.VariableDeclarator;
|
||||||
|
import com.github.javaparser.ast.expr.*;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class ImplicitIntentsPlugin extends JavaPlugin {
|
||||||
|
private final JavaSyntaxRegexProvider java;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ImplicitIntentsPlugin(GlobMatcher globMatcher, XmlHelper xmlHelper, JavaSyntaxRegexProvider javaSyntaxRegexProvider) {
|
||||||
|
super(globMatcher, xmlHelper);
|
||||||
|
this.java = javaSyntaxRegexProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(CompilationUnit compilationUnit) {
|
||||||
|
List<String> intentVariables = getIntentVariables(compilationUnit);
|
||||||
|
findAllSetActionMethodInvocations(compilationUnit, intentVariables);
|
||||||
|
compilationUnit.findAll(ObjectCreationExpr.class).stream()
|
||||||
|
.filter(expr -> expr.getType().getName().getIdentifier().equals("Intent"))
|
||||||
|
.filter(this::checkConstructor)
|
||||||
|
.forEach(objectCreation -> addIssue(Severity.INFO, getLineNumberFromExpression(objectCreation), objectCreation.toString()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkConstructor(ObjectCreationExpr objectCreation) {
|
||||||
|
NodeList<Expression> arguments = objectCreation.getArguments();
|
||||||
|
boolean isImplicit = false;
|
||||||
|
if (arguments.size() == 1) {
|
||||||
|
Expression argument = arguments.get(0);
|
||||||
|
isImplicit = java.isConstant(argument);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(arguments.size() == 2) {
|
||||||
|
Expression argument = arguments.get(0);
|
||||||
|
isImplicit = !argument.isThisExpr();
|
||||||
|
}
|
||||||
|
|
||||||
|
return isImplicit;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void findAllSetActionMethodInvocations(CompilationUnit compilationUnit, List<String> intentVariables) {
|
||||||
|
compilationUnit.findAll(MethodCallExpr.class).forEach(methodCall -> {
|
||||||
|
boolean isCalledOnIntentObject = methodCall.getScope()
|
||||||
|
.map(Expression::toString)
|
||||||
|
.filter(intentVariables::contains)
|
||||||
|
.isPresent();
|
||||||
|
if(isCalledOnIntentObject && methodCall.getName().getIdentifier().equals("setAction")) {
|
||||||
|
addIssue(Severity.INFO, getLineNumberFromExpression(methodCall), methodCall.toString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> getIntentVariables(CompilationUnit compilationUnit) {
|
||||||
|
return compilationUnit.findAll(VariableDeclarationExpr.class).stream()
|
||||||
|
.filter(expr -> expr.getElementType().toString().equals("Intent"))
|
||||||
|
.map(VariableDeclarationExpr::getVariables)
|
||||||
|
.flatMap(NodeList::stream)
|
||||||
|
.map(VariableDeclarator::getName)
|
||||||
|
.map(SimpleName::getIdentifier)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -49,4 +49,9 @@ com.bartek.esa.core.plugin.PermissionsRaceConditionPlugin=Potential permissions
|
|||||||
|
|
||||||
com.bartek.esa.core.plugin.SecureRandomPlugin=Initializing SecureRandom object with custom seed. \n\
|
com.bartek.esa.core.plugin.SecureRandomPlugin=Initializing SecureRandom object with custom seed. \n\
|
||||||
Specifying custom seed for SecureRandom can produce predictable sequence of numbers. \n\
|
Specifying custom seed for SecureRandom can produce predictable sequence of numbers. \n\
|
||||||
Please create SecureRandom object without any arguments instead.
|
Please create SecureRandom object without any arguments instead.
|
||||||
|
|
||||||
|
com.bartek.esa.core.plugin.ImplicitIntentsPlugin=Creating implicit intent. Potential data leakage. \n\
|
||||||
|
Implicit intents can be abused in man-in-the-middle attack. Malicious application can hijack intent and start its\n\
|
||||||
|
activity/send service etc. to steal sent data. \n\
|
||||||
|
Also make sure that no sensitive information is passing to this intent.
|
||||||
Reference in New Issue
Block a user