Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Server-Side Request Forgery Fortify Fix

I'm trying to call a webservice. This webservice call depends on the user input as the URL.

The URL looks like follows:

https://someurl.com/somefunction/{userinput}

And my function looks like this

public async Task<Data> GetData(string input)
{
    try
    {
        Address = BaseAddress; // https://someurl.com/somefunction/{userinput}
        Address = Address.Replace("{userinput}", input);
        ....
        WebService ws = await base.GetData(httpClient, serverIPaddress);
        ....
    }
}

And I get the security error from Fortify

Server-Side Request Forgery (Input Validation and Representation, Data Flow)

The function GetAsync() on line 122 initiates a network connection to a third-party system using user-controlled data for resource URI. An attacker may leverage this vulnerability to send a request on behalf of the application server since the request will originate from the application server's internal IP address.

Here are the recommendations:

Recommendations:

Do not establish network connections based on user-controlled data and ensure that the request is being sent to the expected destination. If user data is necessary to build the destination URI, use a level of indirection: create a list of legitimate resource names that a user is allowed to specify, and only allow the user to select from the list. With this approach the input provided by the user is never used directly to specify the resource name.

In some situations this approach is impractical because the set of legitimate resource names is too large or too hard to keep track of. Programmers often resort to blacklisting in these situations. Blacklisting selectively rejects or escapes potentially dangerous characters before using the input. However, any such list of unsafe characters is likely to be incomplete and will almost certainly become out of date. A better approach is to create a whitelist of characters that are allowed to appear in the resource name and accept input composed exclusively of characters in the approved set.

Also, if required, make sure that the user input is only used to specify a resource on the target system but that the URI scheme, host, and port is controlled by the application. This way the damage that an attacker is able to do will be significantly reduced.

But the thing is that I really need to change {userinput} based on the supplied data from user. {userinput} will be a string with a certain maximum length. How to resolve this issue?

like image 522
rcs Avatar asked May 09 '26 10:05

rcs


1 Answers

After so much research and hit and try attempts, I finally got this working by appending the input in the BaseAddress

The sample code looks like

public async Task<Data> GetData(string input)
{
    try
    {
        var httpClient = new HttpClient();
        httpClient.BaseAddress = new Uri($"https://someurl.com/somefunction/{input}");
        var content = await httpClient.GetStringAsync("");
        return JsonConvert.DeserializeObject<Data>(content);
    }
}
like image 134
Hamza Khanzada Avatar answered May 11 '26 00:05

Hamza Khanzada



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!