【问题标题】:Architecture: Where to sanitise uploaded file names?架构:在哪里清理上传的文件名?
【发布时间】:2010-10-22 13:25:37
【问题描述】:

我正在尝试更改我们在将上传文件存储到磁盘之前处理它们的方式。当来自非 Windows 操作系统的用户上传带有非法 Windows 文件名字符的文件时,我们遇到了一些问题。

  1. 我心中的理想主义者告诉我,文件名应该尽可能靠近 Web 层合法。因此,我们在整个业务逻辑和数据层中使用相同的正确文件名。 在实践中,这需要我们主动清理多个位置的文件名,然后稍后再信任它。这是一个问题,因为它更容易出现程序员错误,除非您只有一个来自网络的文件的入口点。

  2. 我看到的另一个选项是使用文件名上的清理方法来包装文件 IO。这是不可能的,因为我们有时需要将文件名存储在数据库中。如果文件名在存储到磁盘之前未更改,则 DB 将包含错误的文件名。如果对文件系统的所有调用都通过相同的文件名清理方法,这同样无关紧要,只是实际上您的运营部门有时会希望通过从 DB 中读取文件名来执行一些脚本化的工作来移动文件。

绕过选项二的一种方法是,如果新文件名被卫生设施更改,则返回新文件名。这要求该方法的用户意识到这一点并正确处理它。像这样:

public static FileStream CreateFile(string filename, out string newFileName)
{
    newFileName = FileNameSanitiser.GetSanitisedFullPath(filename);
    return System.IO.File.Create(newFileName);
}

关于选项 1,我们应该只有一个或两个文件上传端点。这将使该选项更加可行。我认为在这方面投入时间可能值得,但我不确定我的经理是否同意……

【问题讨论】:

    标签: c# architecture file-io input validation


    【解决方案1】:

    如果文件的上传(以及可能的重新下载)仅通过您的网站界面完成,您可以使用 GUID(或其他一些唯一实体)重命名每个文件,然后存储新的数据库中的名称和旧名称。

    或者,您可以将文件内容存储在数据库本身中,这将完全避免 Windows 文件命名限制。请注意,这不一定是您想要做的事情 - 两种文件存储方法(即磁盘与数据库)各有利弊。

    【讨论】:

      【解决方案2】:

      我们所做的非常简单 - 任何上传的文件都以系统生成的名称(我们使用 GUID)保存在 FileSystem 上,然后数据库表存储生成的名称和实际名称。因此 UI 将显示下载链接的实际名称,实际下载处理程序将在响应标头中使用相同的名称。

      【讨论】:

      • 这将是我的确切答案。
      • 这不是一个糟糕的解决方案。唯一的问题是我们现有的系统相当大,已经存在大量文件。切换到此解决方案将是一个重大变化。
      • 另外我认为保持文件名“人类可读”可能会很有用,以防万一出现任何问题并且磁盘上的文件和数据库文件名之间的连接应该丢失/损坏。
      • 对于人类可读的名称,一个简单但方便的算法是将任何非字母字符替换为下划线。尽管如此,您仍然需要附加一些盐(随机数)以保证文件名的唯一性。
      • @VinayC 是的,这就是上面的 GetSanitisedFullPath 方法的作用。架构级别的问题。正如两个答案所提供的,应该在哪里完成以及其他可能的解决方案。
      猜你喜欢
      • 2013-10-13
      • 1970-01-01
      • 1970-01-01
      • 2021-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-29
      • 2010-10-10
      相关资源
      最近更新 更多