@Override protected List<MethodMatcher> getMethodInvocationMatchers() { return ImmutableList.of( MethodMatcher.create() .typeDefinition(TypeCriteria.subtypeOf("java.lang.Class")) .name("forName") .withNoParameterConstraint(), MethodMatcher.create() .typeDefinition(TypeCriteria.subtypeOf("java.lang.ClassLoader")) .name("loadClass") .withNoParameterConstraint()); }
private static MethodMatcherCollection unboxingInvocationMatchers() { MethodMatcherCollection matchers = MethodMatcherCollection.create(); for (Entry<String, String> type : PRIMITIVE_TYPES_BY_WRAPPER.entrySet()) { String primitiveType = type.getValue(); TypeCriteria typeCriteria; if ("char".equals(primitiveType) || "boolean".equals(primitiveType)) { typeCriteria = TypeCriteria.is(type.getKey()); } else { typeCriteria = TypeCriteria.subtypeOf("java.lang.Number"); } matchers.add(MethodMatcher.create().callSite(typeCriteria).name(primitiveType + "Value")); } return matchers; }
@Rule(key = "S1217") public class ThreadRunCheck extends AbstractMethodDetection { private static final MethodMatcher THREAD_RUN_METHOD_MATCHER = MethodMatcher.create() .typeDefinition(TypeCriteria.subtypeOf("java.lang.Thread")) .name("run") .withNoParameterConstraint(); @Override protected List<MethodMatcher> getMethodInvocationMatchers() { return ImmutableList.of(THREAD_RUN_METHOD_MATCHER); } @Override protected void onMethodInvocationFound(MethodInvocationTree mit) { Tree parent = mit.parent(); while (parent != null && !parent.is(Tree.Kind.METHOD)) { parent = parent.parent(); } if (parent != null && THREAD_RUN_METHOD_MATCHER.matches((MethodTree) parent)) { return; } reportIssue( MethodsHelper.methodName(mit), "Call the method Thread.start() to execute the content of the run() method in a dedicated thread."); } }
private static MethodMatcherCollection getToStringMatchers(String... typeFullyQualifiedNames) { MethodMatcherCollection matchers = MethodMatcherCollection.create(); for (String fullyQualifiedName : typeFullyQualifiedNames) { matchers.add( MethodMatcher.create() .typeDefinition(TypeCriteria.subtypeOf(fullyQualifiedName)) .name("toString") .withoutParameter()); } return matchers; }
@Rule(key = "S2077") public class SQLInjectionCheck extends AbstractInjectionChecker { private static final MethodMatcher HIBERNATE_SESSION_CREATE_QUERY_MATCHER = MethodMatcher.create() // method from the interface org.hibernate.SharedSessionContract, implemented by // org.hibernate.Session .callSite(TypeCriteria.subtypeOf("org.hibernate.Session")) .name("createQuery") .withAnyParameters(); private static final MethodMatcher STATEMENT_EXECUTE_QUERY_MATCHER = MethodMatcher.create() .typeDefinition(TypeCriteria.subtypeOf("java.sql.Statement")) .name("executeQuery") .withAnyParameters(); private static final MethodMatcherCollection CONNECTION_MATCHERS = MethodMatcherCollection.create( MethodMatcher.create() .typeDefinition(TypeCriteria.subtypeOf("java.sql.Connection")) .name("prepareStatement") .withAnyParameters(), MethodMatcher.create() .typeDefinition(TypeCriteria.subtypeOf("java.sql.Connection")) .name("prepareCall") .withAnyParameters()); private static final MethodMatcher ENTITY_MANAGER_CREATE_NATIVE_QUERY_MATCHER = MethodMatcher.create() .typeDefinition("javax.persistence.EntityManager") .name("createNativeQuery") .withAnyParameters(); @Override public void visitNode(Tree tree) { MethodInvocationTree methodTree = (MethodInvocationTree) tree; boolean isHibernateCall = isHibernateCall(methodTree); if (isHibernateCall || isExecuteQueryOrPrepareStatement(methodTree) || isEntityManagerCreateNativeQuery(methodTree)) { // We want to check the argument for the three methods. ExpressionTree arg = methodTree.arguments().get(0); parameterName = ""; if (isDynamicString(methodTree, arg, null, true)) { String message = "\"" + parameterName + "\" is provided externally to the method and not sanitized before use."; if (isHibernateCall) { message = "Use Hibernate's parameter binding instead of concatenation."; } reportIssue(MethodsHelper.methodName(methodTree), message); } } } private static boolean isExecuteQueryOrPrepareStatement(MethodInvocationTree methodTree) { return !methodTree.arguments().isEmpty() && (STATEMENT_EXECUTE_QUERY_MATCHER.matches(methodTree) || CONNECTION_MATCHERS.anyMatch(methodTree)); } private static boolean isHibernateCall(MethodInvocationTree methodTree) { return HIBERNATE_SESSION_CREATE_QUERY_MATCHER.matches(methodTree); } private static boolean isEntityManagerCreateNativeQuery(MethodInvocationTree methodTree) { return ENTITY_MANAGER_CREATE_NATIVE_QUERY_MATCHER.matches(methodTree); } }