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().