无法在 ASP.NET 中纠正 VeraCode CWE ID 918 - (s-s-rF)

Posted

技术标签:

【中文标题】无法在 ASP.NET 中纠正 VeraCode CWE ID 918 - (s-s-rF)【英文标题】:Unable to rectify VeraCode CWE ID 918 - (s-s-rF) in ASP.NET 【发布时间】:2020-01-14 16:03:51 【问题描述】:

长话短说,无论我尝试什么,VeraCode 都会继续将我的 8 行代码标记为 CWE 918 的缺陷。这是旧代码,所以我不确定为什么它会突然被标记。

这是一个示例 [违规] 方法,标记的行以粗体显示

  public virtual async Task<HttpResponseMessage> Put(string controller = "", Dictionary<string, object> parameters = null, object body = null)
        
            if (string.IsNullOrWhiteSpace(ApiBaseUrl)) return null;
            HttpResponseMessage response = null;

            using (var client = GetHttpClient())
            
                client.BaseAddress = new Uri(ApiBaseUrl);

                if (!string.IsNullOrEmpty(Token)) client.DefaultRequestHeaders.Add("Token-Key", Token);
                if (!string.IsNullOrEmpty(DeviceId)) client.DefaultRequestHeaders.Add("DeviceId", DeviceId);

                var url = GenerateUrl(controller, parameters);

                var requestBody = GeneratedHttpContent(body);
                if (requestBody == null) requestBody = new StringContent("");

                **response = await client.PutAsync(url, requestBody);**

                await LogError(response);
                return response;
            
        

这是我提出的使用扩展方法来验证 URL 的修复方法

var url = GenerateUrl(controller, parameters);

                var requestBody = GeneratedHttpContent(body);
                if (requestBody == null) requestBody = new StringContent("");

                **if (url.IsValidUrl())
                
                    response = await client.PutAsync(url, requestBody);
                
                else
                
                    response = new HttpResponseMessage(HttpStatusCode.BadRequest);
                **

                await LogError(response);
                return response;

这是带有 VeraCode 属性的扩展方法

        [RedirectUrlCleanser]
        public static bool IsValidUrl(this string source)
        
            return Uri.TryCreate(source, UriKind.RelativeOrAbsolute, out Uri uriResult) && Uri.IsWellFormedUriString(source, UriKind.RelativeOrAbsolute);
        

我可以让 VeraCode 根据属性自动缓解,但我们的客户将执行他们自己的扫描,当然不会启用该设置。

任何关于我如何解决这个问题的想法都将不胜感激。

【问题讨论】:

【参考方案1】:

漏洞的真正根源在于您的 GenerateUrl 方法内部,遗憾的是没有显示,但这里是 Veracode 抱怨的一般概念。

对于 CWE ID 918,除非您有静态 URL,否则很难让 Veracode 识别您的修复。您需要验证成为请求 URL 一部分的所有输入。 以下是我在 Veracode 网站上找到的内容: https://community.veracode.com/s/question/0D52T00004i1UiSSAU/how-to-fix-cwe-918-veracode-flaw-on-webrequest-getresponce-method

完整的解决方案仅适用于您有单个或少量可能的输入值(白名单)的情况:

public WebResponse ProxyImage(string image_host, string image_path)

    string validated_image_host = AllowedHosts.Host1;
    if (image_host.Equals(AllowedHosts.Host2))
        validated_image_host = AllowedHosts.Host2;

    string validated_image = AllowedImages.Image1;
    if (image_path.Equals(AllowedImages.Image2))
        validated_image = AllowedImages.Image2;

    string url = $"http://validated_image_host.example.com/validated_image";

    return WebRequest.Create(url).GetResponse();

如果可能的有效值集对于这种验证来说太大了,那么您需要通过使用正则表达式实现输入的动态验证来修复该缺陷。不幸的是,Veracode 不够聪明,无法识别这种修复,因此仍然需要“通过设计缓解”。

public WebResponse ProxyImage(string image_host, string image_path)

    var image_host_regex = new System.Text.RegularExpressions.Regex("^[a-z]1,10$");
    if (!image_host_regex.Match(image_host).Success)
        throw new ArgumentException("Invalid image_host");

    var image_path_regex = new System.Text.RegularExpressions.Regex("^/[a-z]1,10/[a-z]1,255.png$");
    if (!image_path_regex.Match(image_path).Success)
        throw new ArgumentException("Invalid image_host");

    string url = $"http://image_host.example.com/image_path";
    return WebRequest.Create(url).GetResponse();

【讨论】:

【参考方案2】:

解决此问题的另一种方法(这是一种 hack)是将您的查询字符串参数附加到 HttpClient 的 baseAddress 中,这样 veracode 就不会将其视为缺陷。

解决方案如下所示

public async Task<Data> GetData(string input)

    try
    
        var httpClient = new HttpClient();

        //Appended the parameter in base address to
        //to fix veracode flaw issue
        httpClient.BaseAddress = new Uri($"https://someurl.com/somefunction/input");

        //passing empty string in GetStringAsync to make sure
        //veracode doesn't treat it like modifying url 
        var content = await httpClient.GetStringAsync("");

        return JsonConvert.DeserializeObject<Data>(content);
    

【讨论】:

这实际上是一个糟糕的建议。如果攻击者以../bad-function(或../admin-function?action=format-c)的形式发送输入,您的服务器将使用其身份验证和授权数据调用https://someurl.com/bad-function。这正是 CWE-918 向我们发出的警告。 实际上我不是从请求数据中动态决定函数,我只是将它用于查询字符串参数,比如要获取的记录的 id。因此,进行此 hack 并没有什么坏处

以上是关于无法在 ASP.NET 中纠正 VeraCode CWE ID 918 - (s-s-rF)的主要内容,如果未能解决你的问题,请参考以下文章

在微服务架构中使用 API 网关模式时无法修复 veracode cwe id 918 缺陷 (s-s-rF)

ASP.NET MVC 4 模型验证

ASP.NET MVC 4 模型验证

ASP.NET 发布问题 [关闭]

在 ASP.NET Core RC2 中使用 AddAuthentication 时的不明确调用

WCF => MVC 作为 ASP.NET WebServices => ASP.NET Web 应用