TWilliamson173102 (Community Member) asked a question.

How to hard code a URL you can't know in advance?

I am attempting to remediate a CWE 918 flaw (Server Side Request Forgery) where I have to validate the URL I am sending a request to:

 

return restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(headers), clazz);

 

I have tried a Regex and other developers worked on this before me, creating checks for protocol, domain suffix, etc.

 

After some searching I found this in the knowledge base: https://community.veracode.com/s/article/allowlist-helps-fix-cwe

 

Here's the key part:

 

"The reason is the $zodiac variable is still considered tainted because of the origin of the value that is assigned to the variable. Being read from the HttpRequest object makes it tainted and will remain tainted until it is modified to an untainted value for e.g., hardcoded value."

<snip>

"We strongly recommend using the approach of using Allow list as expressed above. This is not only a legit solution for Input validation, but it also helps the scanner recognize this as Fix and would not flag certain CWEs."

 

 

The way I read this, you cannot remediate this CWE without resorting to hard-coding values and picking from those. However, this routine will be used for inter-server communication and it's impossible to know what the eventual server names will be.

 

So do I have to ask for a Mitigation By Design on this one since I cannot hard code this string?


  • Hi @TWilliamson173102 (Community Member)​ ,

     

    Veracode Static Analysis supports detection of Server-Side Request Forgery by reviewing for all requests made by the application if data from outside of the application (for example from a users http request, but also from the database, file or another service response).

    Veracode Static Analysis will only automatically close this flaw if it no longer sees this input coming from an outside source (for example by hardcoding the data).

     

    If you need more flexibility in using outside data in composing a request the Veracode Application Security Consulting group typically recommends the following:

    * Be very careful with any dynamic data allowed in the host part of a URL, have a list of allowed hosts only.

    * Use absolute hosts only, guard ensure you throw an exception if the hostname is empty.

    * Be very careful with any dynamic data allowed in the path part of a URL, have a list of allowed paths only.

    * URLEncode any dynamic data going into the query string or after the # symbol.

     

    In your example it seems you have a utility function, validating these 'dangerous functions' is notoriously hard, typically it tends to be much easier applying validation before the utility function is called.

     

    For example:

    ```

    public void goodCallService() {

    doRestCall(config.getApiEndpoint() + "/info")

    }

     

    public void badCallService(HttpServletRequest request) {

    doRestCall(request.getParameter("url"))

    }

     

    public void mitigatedCallService(HttpServletRequest request) {

    doRestCall(config.getApiEndpoint() + "/user/" + request.getParameter("username"))

    }

     

    public void doRestCall(String url) {

    ....

    return restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(headers), clazz);

    }

    ```

    In this example applying validation in `doRestCall` is very hard because `goodCallService` is configurable.

    Instead it's better to look at the usages.

     

    `goodCallService` is fine, it might still be reported depending on what your source for configuration is, if this is the *only* type of request you do, we'd recommend documenting this in a mitigation and doing a manual review with your security team.

     

    `badRestCall` is clearly wrong and needs to be refactored, perhaps into something a little bit more like `mitigatedRestCall`

     

    `mitigatedRestCall` takes some data from configuration (good), some hardcoded data (good) and some unvalidated data from the users HTTP request.

    You probably won't be able to hardcode all usernames, so in this case you may need to settle for validation (with a regex like ^[a-zA-Z0-9]$) and URL encoding, but neither will be automatically detected (because our analysis can't see which part of the URL is dynamic).

    So for this we'd recommend documenting in a mitigation proposal ( https://help.veracode.com/r/improve_mitigation ) what controls (validation + encoding) you have in place.

    An example of a good Mitigation Proposal would be:

     

    Technique: M2 Establish and maintain control over all of your outputs.

    Specifics: HTTP Request done to verify address. Host name originates from profile based property file (for example production.properties), if no hostname is set a RuntimeException is thrown. All other data is passed in query string an is encoded with URLEncode and username is validated to be ^[0-9a-zA-Z]$.

    Remaining Risk: None

    Verification: Manual source code review & unit tests on AddressVerificationService

     

    Please note that it is your organization that reviews and accepts or rejects these, so do check with them for best practices if you have any questions or concerns.

    You then need to contact your organizations security team (this is not done automatically) and request a mitigation approver to review your mitigation proposal.

     

    Thank you,

    Boy Baukema

    Veracode Application Security Consulting

    Expand Post

Topics (2)

No articles found
Loading

Ask the Community

Get answers, share a use case, discuss your favorite features, or get input from the community.