Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System.getenv() used in spring boot is shown as a security vulnerability in sonarQube

I have method in my spring boot application which takes the data from system environment variable, the method works as intended but sonarQube says "Make sure that environment variables are used safely here", I tried to find an alternative to fix this issue but I am unable to find a solution, here is the method:

How can I handle this security issue, I cannot use anything other than getting the values from environment variables.

public Map<String, Object> getConfigurations() {
    Map<String, Object> result = new HashMap<>();
    HttpResponse response = null;
    try {
         String xVaultToken = System.getenv("XVaultToken");
         String cityAppConfig = System.getenv("CityApp_Config");

        @SuppressWarnings("deprecation")
        HttpClient client = HttpClients.custom().setSSLHostnameVerifier(new NoopHostnameVerifier())
                .setSslcontext(
                        new SSLContextBuilder().loadTrustMaterial(null, (x509Certificates, s) -> true).build())
                .build();
        Map<String, Object> headerDatas = new HashMap<>();
        headerDatas.put("Content-Type", "application/json");
        headerDatas.put("X-Vault-Token", xVaultToken);
        HttpGet get = new HttpGet(cityAppConfig);
        Set<String> keys = headerDatas.keySet();
        for (String key : keys) {
            get.setHeader(key, headerDatas.get(key).toString());
        }
        response = client.execute(get);
        try(BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()))){
            String responseData = rd.readLine();
            result.put(Constants.RESPONSE, responseData);
        }
        int statusCode = response.getStatusLine().getStatusCode();
        result.put(Constants.STATUS, statusCode);

    } catch (Exception e) {
        logger.info("error is local settings getConfigurations" + e);
    }
    return result;
}

}

like image 543
Shivakumar N.R Avatar asked May 22 '20 15:05

Shivakumar N.R


People also ask

What is System Getenv in Java?

On the Java platform, an application uses System.getenv to retrieve environment variable values. Without an argument, getenv returns a read-only instance of java.util.Map , where the map keys are the environment variable names, and the map values are the environment variable values.

Why is system Getenv null?

getenv() returns null when the environment variable exists [duplicate]

Can system Getenv return null?

Return Value This method returns the string value of the variable, or null if the variable is not defined in the system environment.

Can I use .ENV in spring boot?

Spring Boot allows you to externalize your configuration so you can work with the same application code in different environments. You can use properties files, YAML files, environment variables and command-line arguments to externalize configuration.


2 Answers

Disclaimer !!!

First of all, as I mentioned in my comments, if someone requires you to read an ENV-Variable but also says that you can't mark the SonarQube warning as false-positive: Tell them (politely) that they'll have to live with that SonarQube warning.

However, if that is for any reason not an option, I will show you 2 ways that may not trigger the warning in SonarQube which are still much less verbose than calling cmd.exe for that purpose.

Example 1

Call the function via java.util.function.Function

private static String getenv(String variable) {
    return ((Function<String, String>) System::getenv).apply(variable);
}

Example 2

Call the function via reflection

    private static String getenv(String variable) {
        try {
            return (String) System.class.getMethod("getenv", String.class).invoke(null, variable);
        } catch (ReflectiveOperationException e) {
            throw new RuntimeException(e);
        }
    }
like image 137
Felix Avatar answered Oct 21 '22 09:10

Felix


All these "security hotspot" warnings are just "TODO" notifications and should be solved in three steps:

  1. Make sure that the value is really used securely.
    • In this particular case: you are invoking GET request to externally-supplied URL and then use the value from response. What happens when someone changes the environment variable value by some clandestine means and point it to their own web server? Is the response used for anything sensitive? Sometimes even the fact that the URL is invoked can be used for nefarious purposes (tracking). etc etc
  2. Add @SuppressWarnings({"squid:S5304"}) annotation, with proper description in a comment.
  3. Make sure that everything is properly reviewed, including the reasoning from step 1. Remember: Two heads are better than one (especially in security).
like image 27
Kamil Podlesak Avatar answered Oct 21 '22 09:10

Kamil Podlesak