wso2 / product-is

Welcome to the WSO2 Identity Server source code! For info on working with the WSO2 Identity Server repository and contributing code, click the link below.
http://wso2.github.io/
Apache License 2.0
727 stars 713 forks source link

System environment variable values are not quoted and leads to `IllegalArgumentException: Illegal group reference` #20515

Closed vfraga closed 3 days ago

vfraga commented 4 weeks ago

Describe the issue: The IllegalArgumentException: Illegal group reference error occurs when using String::replaceAll because it treats the replacement string as a regular expression replacement pattern. In regular expressions, certain characters such as $, \, and others have special meanings. If these characters are present in the replacement string, they are interpreted as regex references unless properly escaped.

In our code, we are replacing environment variable placeholders with their corresponding values from the system environment. If any of these values contain special characters, they need to be properly escaped to avoid misinterpretation by the regex engine.

Some common special regex characters that need to be escaped in replacement strings:

To fix this, we need to escape the replacement string using Matcher.quoteReplacement, which ensures that all special characters are treated as literals.

private static String resolveStringWithEnvVarPlaceholders(String value, Map<String, String> resolvedEnvironmentVariables)
        throws ConfigParserException {

    String[] envRefs = StringUtils.substringsBetween(value, ENV_VAR_PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX);
    if (envRefs != null) {
        for (String ref : envRefs) {
            String resolvedValue = System.getenv(ref);
            if (resolvedValue != null) {
                resolvedEnvironmentVariables.put(ref, resolvedValue);
                value = value.replaceAll(Pattern.quote(ENV_VAR_PLACEHOLDER_PREFIX + ref + PLACEHOLDER_SUFFIX),
                        Matcher.quoteReplacement(resolvedValue));
            } else {
                throw new ConfigParserException("Environment variable " + ref + " not defined in system");
            }
        }
    }
    return value;
}

Source [1]

How to reproduce:

  1. Setup an Identity Server instance and add the configuration below to the deployment.toml file:
    [server]
    . . . [omitted for brevity] . . .
    dummy_key = "$env{DUMMY_ENV_VAL}"
  2. Export a value for the DUMMY_ENV_VAL environment variable:
    export DUMMY_ENV_VAL='"~!(@%_<[$%_)%£?;~()~~>*)(")_*$@_+#`"+{*{-#&+_<'
  3. Start the server and observe the stack trace below:
    . . . [omitted for brevity] . . .
    Caused by: java.lang.IllegalArgumentException: Illegal group reference
    at java.base/java.util.regex.Matcher.appendExpandedReplacement(Matcher.java:1068)
    at java.base/java.util.regex.Matcher.appendReplacement(Matcher.java:998)
    at java.base/java.util.regex.Matcher.replaceAll(Matcher.java:1182)
    at java.base/java.lang.String.replaceAll(String.java:2126)
    at org.wso2.config.mapper.ReferenceResolver.resolveStringWithEnvVarPlaceholders(ReferenceResolver.java:362)
    at org.wso2.config.mapper.ReferenceResolver.resolveEnvVariables(ReferenceResolver.java:263)
    at org.wso2.config.mapper.ReferenceResolver.resolve(ReferenceResolver.java:90)
    at org.wso2.config.mapper.ReferenceResolver.resolve(ReferenceResolver.java:71)
    at org.wso2.config.mapper.ConfigParser.parse(ConfigParser.java:253)
    at org.wso2.config.mapper.ConfigParser.deploy(ConfigParser.java:217)
    at org.wso2.config.mapper.ConfigParser.deployAndStoreMetadata(ConfigParser.java:180)
    at org.wso2.config.mapper.ConfigParser.parse(ConfigParser.java:127)
    at org.wso2.carbon.server.Main.handleConfiguration(Main.java:236)
    at org.wso2.carbon.server.Main.main(Main.java:107)
    ... 6 more

Expected behavior: The Identity Server should be able to use any environment variable value.

Environment information:

JayaShakthi97 commented 3 days ago

Fixed via;