服务器端请求伪造 Fortify 修复

3

我想调用一个webservice。这个webservice的调用依赖于用户输入,因为它是URL。

URL的格式如下:

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

我的功能看起来像这样:
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);
        ....
    }
}

我从Fortify中收到了安全错误。
服务器端请求伪造(输入验证和表示,数据流):
第122行上的GetAsync()函数使用用户控制数据进行资源URI的网络连接,可能导致攻击者代表应用程序服务器发送请求,因为该请求将源自应用程序服务器的内部IP地址。
以下是建议:
建议:
不要基于用户控制数据建立网络连接,并确保请求被发送到预期的目标。如果需要使用用户数据构建目标URI,请使用一定级别的间接性:创建一个合法资源名称列表,允许用户从列表中选择。使用此方法,用户提供的输入永远不直接用于指定资源名称。
在某些情况下,这种方法并不实际,因为合法资源名称集太大或太难以跟踪。在这些情况下,程序员经常采用黑名单。黑名单会有选择地拒绝或转义使用输入之前具有潜在危险的字符。但任何此类不安全字符列表都很可能是不完整的,并且几乎肯定会过时。更好的方法是创建一个白名单,其中允许出现在资源名称中的字符,并接受仅由批准集合中的字符组成的输入。
此外,如有必要,请确保仅使用用户输入来指定目标系统上的资源,而URI方案、主机和端口由应用程序控制。这样,攻击者能够造成的损害将显着降低。
但问题是我确实需要根据用户提供的数据更改{userinput}。 {userinput}将是具有一定最大长度的字符串。 如何解决此问题?

你能解决这个问题吗? - Hamza Khanzada
@HamzaKhanzada,最终我会将输入与数据库进行验证,并提供从数据库返回的值以分配给用户输入。 - rcs
我发现了另一个解决方法,可以避免访问数据库。让我把它发布为答案。 - Hamza Khanzada
1个回答

1
经过大量的研究和尝试,我最终通过将输入附加到 BaseAddress 中使其正常工作。
示例代码如下:
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);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接