You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fortify常见误用:文件上传问题修复方案咨询

解决Fortify扫描出的「文件上传误用」问题

原代码存在的核心问题

你的前端验证逻辑存在多处无效校验,这是Fortify持续告警的原因:

  1. 文件类型检查逻辑错误:fileInput.type是输入框的类型(固定为file),不是上传文件的MIME类型,数组里的.pdf是扩展名,两者完全不匹配,导致这个校验形同虚设。
  2. 文件内容校验未生效:仅读取文件内容打印日志,没有实际验证是否为合法PDF文件。
  3. 缺少文件名/扩展名校验:虽然input设置了accept=".pdf",但攻击者可以轻松绕过这个前端限制,必须手动校验文件名后缀。
  4. 前端校验维度不全:Fortify要求覆盖「文件名、扩展名、内容、大小」全维度校验,同时会提示后端必须同步校验(前端校验可被绕过)。

修复后的完整代码

<!DOCTYPE html>
<html>
<head>
    <script>
        function fileValidation(fileInput) {  
            const file = fileInput.files[0];
            if (!file) return false;

            // 1. 校验文件名扩展名
            const fileName = file.name;
            const allowedExtensions = /(\.pdf)$/i;
            if (!allowedExtensions.test(fileName)) {
                console.log('仅支持PDF格式文件');
                fileInput.value = '';
                return false;
            }

            // 2. 校验文件MIME类型
            const allowedMimeType = 'application/pdf';
            if (file.type !== allowedMimeType) {
                console.log('文件MIME类型不符合要求');
                fileInput.value = '';
                return false;
            }

            // 3. 校验PDF文件内容(检查文件头标识)
            const reader = new FileReader();
            reader.onload = function(evt) {
                const arrayBuffer = evt.target.result;
                const uint8Array = new Uint8Array(arrayBuffer.slice(0, 5));
                const header = new TextDecoder().decode(uint8Array);
                // PDF文件标准开头为%PDF-
                if (header !== '%PDF-') {
                    console.log('文件内容不是合法的PDF');
                    fileInput.value = '';
                    return false;
                }
            };
            reader.onerror = function(evt) {
                console.log('文件读取失败:', reader.error);
                fileInput.value = '';
                return false;
            };
            // 读取前5个字节即可验证PDF头,无需读取整个文件
            reader.readAsArrayBuffer(file.slice(0, 5));

            // 4. 校验文件大小(限制2MiB)
            const fileSize = file.size / 1024 / 1024;
            if (fileSize > 2) {
                console.log('文件大小不能超过2MiB');
                fileInput.value = '';
                return false;
            }

            return true;
        }
    </script>
</head>
 
<body>
    <label for="botFile">文件上传</label>
    <input type="file" id="botFile" onchange="fileValidation(this)" maxlength="255" name="botFile" accept=".pdf" />
</body>
</html>

关键修复点说明

  • 扩展名校验:用正则严格匹配文件名后缀,通过i标识忽略大小写适配不同命名习惯。
  • MIME类型校验:直接读取文件的type属性,验证是否为标准PDF的MIME类型application/pdf。
  • 内容校验:读取文件前5个字节,检查是否符合PDF标准的%PDF-开头,避免伪装成PDF的恶意文件。
  • 逻辑优化:先获取文件对象并判空,每个校验不通过时都清空输入框并终止流程。

必须补充的后端校验

Fortify的告警不会仅靠前端修复完全消除,必须在后端同步执行以下校验:

  • 再次校验文件名扩展名和MIME类型。
  • 验证文件内容的PDF头标识,甚至可以用专业PDF处理库(如Java的iText、Python的PyPDF2)验证文件合法性。
  • 限制文件大小,避免超大文件攻击。
  • 上传后的文件存储时,重命名为随机文件名,避免路径遍历攻击。

内容的提问来源于stack exchange,提问作者Naveen Korakoppa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 02:54:25