CodeQL documentation

AnnotationPresent check

ID: java/ineffective-annotation-present-check
Kind: problem
Severity: error
Precision: medium
Tags:
   - correctness
   - logic
Query suites:
   - java-security-and-quality.qls

Click to see the query in the CodeQL repository

To be able to use the isAnnotationPresent method on an AnnotatedElement at runtime, an annotation must be explicitly annotated with a RUNTIME retention policy. Otherwise, the annotation is not retained at runtime and cannot be observed using reflection.

Recommendation

Explicitly annotate annotations with a RUNTIME retention policy if you want to observe their presence using AnnotatedElement.isAnnotationPresent at runtime.

Example

In the following example, the call to isAnnotationPresent returns false because the annotation cannot be observed using reflection.

public class AnnotationPresentCheck {
	public static @interface UntrustedData { }

	@UntrustedData
	public static String getUserData() {
		Scanner scanner = new Scanner(System.in);
		return scanner.nextLine();
	}

	public static void main(String[] args) throws NoSuchMethodException, SecurityException {
		String data = getUserData();
		Method m = AnnotationPresentCheck.class.getMethod("getUserData");
		if(m.isAnnotationPresent(UntrustedData.class)) {  // Returns 'false'
			System.out.println("Not trusting data from user.");
		}
	}
}

To correct this, the annotation is annotated with a RUNTIME retention policy.

public class AnnotationPresentCheckFix {
	@Retention(RetentionPolicy.RUNTIME)  // Annotate the annotation
	public static @interface UntrustedData { }

	@UntrustedData
	public static String getUserData() {
		Scanner scanner = new Scanner(System.in);
		return scanner.nextLine();
	}

	public static void main(String[] args) throws NoSuchMethodException, SecurityException {
		String data = getUserData();
		Method m = AnnotationPresentCheckFix.class.getMethod("getUserData");
		if(m.isAnnotationPresent(UntrustedData.class)) {  // Returns 'true'
			System.out.println("Not trusting data from user.");
		}
	}
}

References