use of com.android.tools.klint.client.api.JavaEvaluator in project kotlin by JetBrains.
the class BadHostnameVerifierDetector method checkClass.
@Override
public void checkClass(@NonNull JavaContext context, @NonNull UClass declaration) {
JavaEvaluator evaluator = context.getEvaluator();
for (PsiMethod method : declaration.findMethodsByName("verify", false)) {
if (evaluator.methodMatches(method, null, false, TYPE_STRING, "javax.net.ssl.SSLSession")) {
ComplexVisitor visitor = new ComplexVisitor(context);
declaration.accept(visitor);
if (visitor.isComplex()) {
return;
}
Location location = context.getNameLocation(method);
String message = String.format("`%1$s` always returns `true`, which " + "could cause insecure network traffic due to trusting " + "TLS/SSL server certificates for wrong hostnames", method.getName());
context.report(ISSUE, location, message);
break;
}
}
}
use of com.android.tools.klint.client.api.JavaEvaluator in project kotlin by JetBrains.
the class FragmentDetector method checkClass.
@Override
public void checkClass(@NonNull JavaContext context, @NonNull UClass node) {
if (node instanceof UAnonymousClass) {
String message = "Fragments should be static such that they can be re-instantiated by " + "the system, and anonymous classes are not static";
context.reportUast(ISSUE, node, context.getUastNameLocation(node), message);
return;
}
JavaEvaluator evaluator = context.getEvaluator();
if (evaluator.isAbstract(node)) {
return;
}
if (!evaluator.isPublic(node)) {
String message = String.format("This fragment class should be public (%1$s)", node.getQualifiedName());
context.reportUast(ISSUE, node, context.getUastNameLocation(node), message);
return;
}
if (node.getContainingClass() != null && !evaluator.isStatic(node)) {
String message = String.format("This fragment inner class should be static (%1$s)", node.getQualifiedName());
context.reportUast(ISSUE, node, context.getUastNameLocation(node), message);
return;
}
boolean hasDefaultConstructor = false;
boolean hasConstructor = false;
for (PsiMethod constructor : node.getConstructors()) {
hasConstructor = true;
if (constructor.getParameterList().getParametersCount() == 0) {
if (evaluator.isPublic(constructor)) {
hasDefaultConstructor = true;
} else {
Location location = context.getNameLocation(constructor);
context.report(ISSUE, constructor, location, "The default constructor must be public");
// Also mark that we have a constructor so we don't complain again
// below since we've already emitted a more specific error related
// to the default constructor
hasDefaultConstructor = true;
}
} else {
Location location = context.getNameLocation(constructor);
// TODO: Use separate issue for this which isn't an error
String message = "Avoid non-default constructors in fragments: " + "use a default constructor plus " + "`Fragment#setArguments(Bundle)` instead";
context.report(ISSUE, constructor, location, message);
}
}
if (!hasDefaultConstructor && hasConstructor) {
String message = String.format("This fragment should provide a default constructor (a public " + "constructor with no arguments) (`%1$s`)", node.getQualifiedName());
context.reportUast(ISSUE, node, context.getNameLocation(node), message);
}
}
use of com.android.tools.klint.client.api.JavaEvaluator in project kotlin by JetBrains.
the class SQLiteDetector method visitMethod.
@Override
public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor, @NonNull UCallExpression call, @NonNull UMethod uMethod) {
PsiMethod method = uMethod.getPsi();
JavaEvaluator evaluator = context.getEvaluator();
if (!JavaEvaluator.isMemberInClass(method, "android.database.sqlite.SQLiteDatabase")) {
return;
}
int parameterCount = evaluator.getParameterCount(method);
if (parameterCount == 0) {
return;
}
if (!evaluator.parameterHasType(method, 0, TYPE_STRING)) {
return;
}
// Try to resolve the String and look for STRING keys
UExpression argument = call.getValueArguments().get(0);
String sql = ConstantEvaluator.evaluateString(context, argument, true);
if (sql != null && (sql.startsWith("CREATE TABLE") || sql.startsWith("ALTER TABLE")) && sql.matches(".*\\bSTRING\\b.*")) {
String message = "Using column type STRING; did you mean to use TEXT? " + "(STRING is a numeric type and its value can be adjusted; for example, " + "strings that look like integers can drop leading zeroes. See issue " + "explanation for details.)";
context.report(ISSUE, call, context.getUastLocation(call), message);
}
}
use of com.android.tools.klint.client.api.JavaEvaluator in project kotlin by JetBrains.
the class SecureRandomDetector method visitMethod.
@Override
public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor, @NonNull UCallExpression call, @NonNull UMethod method) {
List<UExpression> arguments = call.getValueArguments();
if (arguments.isEmpty()) {
return;
}
UExpression seedArgument = arguments.get(0);
JavaEvaluator evaluator = context.getEvaluator();
if (JavaEvaluator.isMemberInClass(method, JAVA_SECURITY_SECURE_RANDOM) || evaluator.isMemberInSubClassOf(method, JAVA_UTIL_RANDOM, false) && isSecureRandomReceiver(context, call)) {
// Called with a fixed seed?
Object seed = ConstantEvaluator.evaluate(context, seedArgument);
//noinspection VariableNotUsedInsideIf
if (seed != null) {
context.report(ISSUE, call, context.getUastLocation(call), "Do not call `setSeed()` on a `SecureRandom` with a fixed seed: " + "it is not secure. Use `getSeed()`.");
} else {
// Called with a simple System.currentTimeMillis() seed or something like that?
PsiElement resolvedArgument = UastUtils.tryResolve(seedArgument);
if (resolvedArgument instanceof PsiMethod) {
PsiMethod seedMethod = (PsiMethod) resolvedArgument;
String methodName = seedMethod.getName();
if (methodName.equals("currentTimeMillis") || methodName.equals("nanoTime")) {
context.report(ISSUE, call, context.getUastLocation(call), "It is dangerous to seed `SecureRandom` with the current " + "time because that value is more predictable to " + "an attacker than the default seed.");
}
}
}
}
}
use of com.android.tools.klint.client.api.JavaEvaluator in project kotlin by JetBrains.
the class AddJavascriptInterfaceDetector method visitMethod.
@Override
public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor, @NonNull UCallExpression call, @NonNull UMethod method) {
// Ignore the issue if we never build for any API less than 17.
if (context.getMainProject().getMinSdk() >= 17) {
return;
}
JavaEvaluator evaluator = context.getEvaluator();
if (!evaluator.methodMatches(method, WEB_VIEW, true, TYPE_OBJECT, TYPE_STRING)) {
return;
}
String message = "`WebView.addJavascriptInterface` should not be called with minSdkVersion < 17 for security reasons: " + "JavaScript can use reflection to manipulate application";
UElement reportElement = call.getMethodIdentifier();
if (reportElement == null) {
reportElement = call;
}
context.reportUast(ISSUE, reportElement, context.getUastNameLocation(reportElement), message);
}
Aggregations