I have a Spring Component like this:
package com.example.myproject;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class MyComponent implements ApplicationContextAware {
// ... some other stuff not relevant to this issue
private ConfigurableApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.context = (ConfigurableApplicationContext) applicationContext;
}
}
Now, this is triggering java:S3749
, which is classified as a security vulnerability, because the context instance field is not being automatically injected by Spring. However, there is nothing wrong with this code – it is acceptable for a bean to implement ApplicationContextAware
, have a setApplicationContext(ApplicationContext)
method, and then store the ApplicationContext
in a field. (I think I tried @Autowired
, and it didn’t work for some reason, but I don’t quite remember; I am going to try it again – but even if @Autowired
works, using the Spring ApplicationContextAware
interface is an entirely valid approach, not a security vulnerability.)
To exclude the false positive with ApplicationContextAware
, you want to exclude from this rule any private instance field of ApplicationContext
(or its subclasses) if the class implements ApplicationContextAware
and implements the setApplicationContext()
method from that class.
However, Spring actually has many instances of this Aware
pattern, not just ApplicationContextAware
. To fix the false positive generically, so the fix works for all Spring Aware
interfaces (such as EnvironmentAware
or BeanClassLoaderAware
), not just ApplicationContextAware
, you could use this logic: if a class C
implements some interface I
, where I
extends org.springframework.beans.factory.Aware
, and C
also implements a setter method of interface I
, where that setter method takes a single parameter of class T
, then exclude any private instance field of class T
(or a subclass thereof) from this rule.
I am reproducing the above using SonarQube Enterprise Edition Version 8.9.8 (build 54436). I don’t know if that is the latest – it is the version my employer provides us with. I don’t have the bandwidth right now to test the issue myself on a newer version (if that isn’t the newest), but hopefully someone from SonarSource can test it? (If necessary I can try to get a support ticket logged, since we are running Enterprise Edition, although I’d have to track down who at my work has login details to the support portal.)