怎么用Copilot修复PHP文件上传漏洞详细步骤

冬萱同学_8038

冬萱同学_8038

2026-10-23

123人浏览

原创

用copilot修复php上传漏洞,要一起检查上传身份、文件内容、保存位置与访问方式。下面以仅允许png的头像入口为例,给出可运行校验测试和带会话校验的上传处理代码。

GitHub Copilot官方Agent使用文档真实截图

文件上传完成后,记得让Copilot同步校验访问路径

文件上传风险不止存在于表单校验。若用户能指定保存路径、上传目录允许脚本执行,或者下载接口绕过权限,单独限制后缀仍可能留下问题。先整理上传路由、存储目录、下载处理器及服务器配置。

本文只处理已登录用户上传PNG头像的场景,不扩展到压缩包、文档或任意图片格式。生产项目还需要配额、限流和必要的内容处理,这些要求应在任务开始时交代,不能靠补丁自行猜测。

另外最好额外加两层限制:单个账号最多能传多少个文件、累计总大小不能超过多少,而且用户替换新头像的时候,必须明确写好旧头像的删除逻辑,不然时间长了存储目录里会堆大量没人用的冗余文件。

后缀、MIME和存储隔离分别解决什么

原始文件名与请求中的Content-Type都由客户端提供,不能直接证明文件内容。服务端检测MIME、检查图片结构与尺寸,可以收紧允许输入的范围,但不是病毒扫描或绝对安全证明。

随机命名减少路径操控和覆盖风险,私有目录则避免上传物被当作站点脚本执行。身份校验和CSRF保护还要在读取文件前完成,防止未授权消耗存储资源。

在VS Code里把整套校验任务拆成4步落地执行

  1. 在项目副本中打开Copilot Chat,选择Agent工作方式。把上传控制器、表单和访问文件的代码加入上下文,明确只能审查测试项目,不连接对象存储生产桶。

  2. 要求先输出风险清单,逐项回答身份从哪里取得、支持哪些文件、最终路径谁决定、文件如何下载。缺少服务器配置时,标记待确认,不默认上传目录不可执行。

    btpanel phpsite 宝塔面板PHP网站
    btpanel phpsite 宝塔面板PHP网站

    宝塔面板 PHP 网站管理:站点创建、删除、启停、PHP 版本切换、域名管理、SSL证书管理、伪静态管理、数据库管理

    下载
  3. 确认方案后让Copilot生成小范围补丁。检查保存路径是否只由服务端生成,错误响应是否泄露绝对路径,是否误删原有会话和权限条件。

  4. 先运行校验单元测试,再在测试Web服务发送真实multipart上传。逐条核对正常头像、伪装文本、超限文件和未登录请求;不得把命令行临时文件当成HTTP上传成功证据。

修复当前PHP头像上传入口,只允许登录用户上传PNG。
先检查认证、CSRF、上传错误、真实大小、扩展名、服务端MIME、图片尺寸和最终访问路径。
保存名使用随机值,存储目录必须在Web根目录之外;不要相信原始文件名和客户端MIME。
先给最小修改差异与测试,再列出Nginx/Apache和下载处理器需要人工核验的条件。
不更改生产存储、不开放任意后缀,不把MIME检测描述成病毒扫描。

完整上传处理器实现,附带可直接运行的校验测试代码

下面给出的代码文件,既可以直接在命令行跑单元测试,收到HTTP请求的时候也会自动走上传处理分支。

接入这套逻辑之前,要确保站点本身的登录流程已经正常把用户身份写入会话、能生成随机CSRF令牌,前端上传表单用avatar做文件字段名、csrf做令牌字段名,后台由管理员提前配置好站点根目录外的私有存储路径。

<?php declare(strict_types=1);
const MAX_BYTES = 2 * 1024 * 1024;
function inspectPng(string $name, string $bytes): string {
    if (strlen($bytes) < 1 || strlen($bytes) > MAX_BYTES ||
        strtolower(pathinfo($name, PATHINFO_EXTENSION)) !== 'png') {
        throw new InvalidArgumentException('Invalid size or extension');
    }
    $mime = (new finfo(FILEINFO_MIME_TYPE))->buffer($bytes);
    $image = @getimagesizefromstring($bytes);
    if ($mime !== 'image/png' || $image === false || $image[2] !== IMAGETYPE_PNG ||
        $image[0] > 4096 || $image[1] > 4096) {
        throw new InvalidArgumentException('Invalid PNG');
    }
    // 原始文件名不参与保存路径;返回随机服务端名称。
    return bin2hex(random_bytes(16)) . '.png';
}
if (!in_array(PHP_SAPI, ['cli', 'phpdbg', 'wasm'], true)) {
    // 接入项目时,user_id必须由登录流程写入服务端会话。
    session_start();
    header('Content-Type: application/json; charset=UTF-8');
    try {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_SESSION['user_id']) ||
            !is_int($_SESSION['user_id']) || $_SESSION['user_id']  $name], JSON_THROW_ON_ERROR);
    } catch (Throwable $e) {
        if (http_response_code() ['a.png','not an image'], 'wrong_extension'=>['a.php',$png],
    'oversize'=>['a.png',str_repeat('A',MAX_BYTES+1)]] as $case => [$filename,$data]) {
    try { inspectPng($filename, $data); }
    catch (InvalidArgumentException $e) { echo $case, ': PASS rejected', PHP_EOL; continue; }
    throw new RuntimeException('FAIL: ' . $case);
}
if (!preg_match('/^[a-f0-9]{32}\.png$/D', $name)) { throw new RuntimeException('FAIL: name'); }
echo 'random_name: PASS', PHP_EOL;
echo 'Runtime: PHP ', PHP_VERSION, ' / ', PHP_SAPI, PHP_EOL;
php audit.php

本次实际环境是macOS上的PHP 8.5.10 WebAssembly,已执行内容与命名测试。会话、真实上传来源校验、文件移动和目录权限尚未在Web服务器联调;下图不代表已经完成生产上传验收。

PNG上传校验函数的五条真实测试结果

头像上传和文档上传别共用同一份宽松的后缀白名单

业务 内容处理 提供访问
PNG头像 尺寸限制,按需安全解码后重编码 隔离域或受控图片响应
合同文档 独立类型白名单、配额与内容检测 鉴权下载,默认附件方式

示例没有实现图片重编码与恶意内容扫描,不能据此接收所有业务文件。私有文件的下载也要重新鉴权,服务器不得仅凭猜到文件名就返回内容;文件标识应与数据库中的所属用户对应。

正式上线前重点排查四类校验失效场景

  • 正常头像也被拒绝:检查fileinfo扩展、PHP上传限制和PNG策略是否一致。
  • 请求中没有文件:核对表单编码及post_max_size,区分传输失败和内容不合格。
  • 命令行移动测试失败:move_uploaded_file只接受真正的PHP上传文件,不要用普通临时文件绕过校验。
  • 上传成功却能作为脚本访问:立即停止放行,复核真实存储路径与Web服务器映射,不能只靠后缀限制。

php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2023.09.01

11344

6

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

6581

5

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

2175

5

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

2023.10.23

4168

4

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

2023.10.23

4874

6

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.03

3831

9

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.09

5517

8

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.13

4322

8

sprintf函数用法详解
sprintf函数用法详解

sprintf函数的用法:1、格式化字符串;2、指定输出宽度和精度;3、返回值。更多关于sprintf函数用法详解的内容,大家可以阅读下面的文章。

2023.11.27

12262

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
墨刀帮助中心
墨刀帮助中心

共0课时 | 0人学习

MyEclipse学习中心
MyEclipse学习中心

共0课时 | 0人学习

Apache Subversion 官方手册
Apache Subversion 官方手册

共0课时 | 0人学习