AnnotationPresent checkΒΆ
ID: java/ineffective-annotation-present-check
Kind: problem
Security severity:
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ΒΆ
Java API Specification: Annotation Type Retention, RetentionPolicy.RUNTIME, AnnotatedElement.isAnnotationPresent().