javascript - 客户端与服务器端的文件名清理

标签 javascript c# jquery asp.net-mvc

从许多单独的网页和 Controller 上传文件时,当上传名称中包含 HTML 实体的文件时,我的 C# 后端会中断:

An exception of type 'System.Web.HttpRequestValidationException' occurred in System.Web.Mvc.dll but was not handled in user code

Additional information: A potentially dangerous Request.Files value was detected from the client (filename="...for_files_#US2023103...").

注意名称中的 HTML 实体 #,它应该只是 #。我可以遍历每个网页的 JS 并强制 JS 在客户端更改/解码 HTML 实体(很多小的更改)或者我可以更改服务器端代码来处理这个问题,但我不确定服务器端方法可以在不使服务器暴露于漏洞的情况下完成。

为了防止这是一个自以为是的问题,我明确地问:

有没有什么方法可以在服务器端转义/验证文件名,而不会抛出异常,也不会使服务器暴露在漏洞之下?

这是我尝试用来替换文件名的代码:

        if (requestContext.HttpContext.Request.Files.Count > 0)
        {
            foreach (HttpPostedFileBase file in requestContext.HttpContext.Request.Files)
            {
                file.FileName = System.Net.WebUtility.HtmlDecode(file.FileName);
            }
        }

这当然是不允许的,因为 FileName 是 HttpPostedFileBase 的只读属性。我认为检查文件名可能是明智的,如果它有 HTML 实体或分号,然后用更正的名称实例化一个新的 HttpPostedFileBase 对象。

最佳答案

我不知道您使用的是哪个 .net 框架,但您可以尝试使用 HttpUtility.HtmlDecode方法。

关于安全性的注意事项:清理/验证必须在服务器端进行。客户端用于用户体验。你在客户端做的任何事情都不是真正安全的,因为如果不在服务器上重新做,你就无法确保它确实完成了(这是我对标题的提示)

你可以试试

if (requestContext.HttpContext.Request.Files.Count > 0)
{
    var finalDir = "path/to/dir"
    foreach (HttpPostedFileBase file in requestContext.HttpContext.Request.Files)
    {
        var decodedFileName = System.Net.WebUtility.HtmlDecode(file.FileName);

        try
        {
            // Will not overwrite if the destination file already exists.
            if(filename.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
                throw new Exception('invalid name');
            else
                File.Copy(decodedFileName , Path.Combine(finalDir, Guid.NewGuid()));
        }

        // Catch exception if the file was already copied.
        catch (IOException copyError)
        {
            Console.WriteLine(copyError.Message);
        }
    }
}

或者更简单,根据 this SO post

if (requestContext.HttpContext.Request.Files.Count > 0)
{
    foreach (HttpPostedFileBase file in requestContext.HttpCont
    {
        file.SaveAs(Path.Combine("destination/path/", Guid.NewGuid());
    }
}

关于javascript - 客户端与服务器端的文件名清理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46916290/

相关文章:

javascript - 像图像一样拖放 Canvas

javascript - 如何终止 SignalR 连接?

c# - 更新条目时出错。有关详细信息,请参阅内部异常

javascript - 计算在输入字段中接受空格

javascript - 样式化 JQuery UI 自动完成

javascript - 动态更新 Bootstrap 工具提示

javascript - 从 websocket 接收看似封装的 JSON。我该如何处理这种格式?

javascript - 谷歌浏览器 "Application Shortcut": How to auto-load JavaScript?

javascript - 使用新的 html5 表单属性在 IE 中序列化失败

c# - RouteValues 与 QueryString MVC?