怎么用ChatGPT批量修复PHP项目里的多处漏洞(附可执行代码)

大明吖_3792

大明吖_3792

2026-10-23

646人浏览

原创

用chatgpt批量修复php漏洞,应先形成人工复核的问题与补丁清单,再分批应用和测试。下面的脚本会校验文件哈希,默认只预览,显式应用时保存备份,用于降低重复替换与误覆盖的风险。

ChatGPT官方文件检查与交付文档真实页面截图

第一步:把零散漏洞整理成可逐一核验的问题清单

别上来就直接让ChatGPT修改整站代码,很容易把不同风险等级的漏洞、业务逻辑调整、无关的格式改动混在一起,后续很难挨个核对清楚。

你可以按访问入口、涉及文件、输入来源、危险操作类型、修复目标、测试编号这几个维度列清单,每一条都能单独说清修改原因和改动位置。

把SQL注入、输出编码和权限问题分批处理,同一批只包含关系清楚的变更。秘密泄露和依赖漏洞还需要轮换或升级流程,不能仅靠代码文本替换解决。

注意:批量应用补丁不等于自动发现修复漏洞

同一个函数名在不同上下文中可能有不同含义,正则批量替换缺少数据流和业务权限信息,很容易产生错误补丁。AI应先提出带依据的候选差异,人工批准后再应用。

文件哈希与唯一匹配用于确认补丁针对的原始内容没有变化,并不能证明补丁本身正确;应用后的语法、安全回归与业务测试仍是独立验收环节。

ChatGPT操作流程里,把漏洞审查和补丁落地拆成两个独立环节

  1. 新建项目或会话,提供允许对外处理的脱敏代码和目录说明,明确只读审查范围。让ChatGPT按文件列出问题、证据与不确定项,不提交环境秘密,也不默认上传整个生产仓库。

  2. 选择同一类问题,要求输出最小差异与对应测试。逐项核对认证条件、返回格式和正常业务,删除与本次修复无关的重构,必要时让模型解释具体行。

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

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

    下载
  3. 人工批准后,按脚本的file、sha256、before、after结构整理清单。哈希从本地原文件计算,不能让模型猜;先预览所有目标,再核对没有重复文件和不唯一匹配。

  4. 只在独占的离线副本中应用,执行项目语法检查与测试。失败立即停止后续批次,保留日志与备份;所有变更验收后再按正常发布流程部署。

只读审查这批PHP文件,按“文件→输入来源→危险操作→依据→最小补丁→回归测试”输出。
按SQL、XSS、授权等类型分批,不混入无关重构,不修改vendor、上传文件和环境秘密。
不能确认的风险标记待核实;保留认证、租户与资源条件。
先给差异和完整测试,人工批准后才准备精确替换清单。
哈希由本地计算,不猜测;不承诺全站漏洞清零,不自动部署。

完整脚本规则说明:默认先预览效果,正式应用前核对原文件

这个脚本仅支持处理src目录下第一层的PHP文件,单批最多执行20个补丁,同时要求项目的离线备份副本做好明确标识。

不带参数运行脚本的时候,只会生成两个临时演示文件,走完预览、打补丁、回归测试的全流程之后自动清理临时测试资源,完全不会碰你本地的真实项目代码。

<?php declare(strict_types=1);
function reviewedPatch(string $directory,array $plan,bool $apply=false): array {
    $root=realpath($directory);
    if ($root===false || !is_file($root.'/.repair-sandbox') || count($plan)<1 || count($plan)>20) {
        throw new RuntimeException('An explicitly marked offline project copy is required');
    }
    $changes=[];
    foreach ($plan as $entry) {
        $relative=$entry['file'] ?? null;
        // 教学脚本只允许src下单层PHP文件,拒绝vendor、目录穿越及重复目标。
        if (!is_string($relative) || !preg_match('~^src/[A-Za-z0-9_-]+\.php$~D',$relative) || isset($changes[$relative])) {
            throw new RuntimeException('Unsupported or duplicate target');
        }
        $path=$root.'/'.$relative; $real=realpath($path);
        if ($real===false || is_link($path) || !is_file($real) ||
            !str_starts_with($real,$root.DIRECTORY_SEPARATOR) || filesize($real)>1024*1024) {
            throw new RuntimeException('Unsafe target');
        }
        $old=file_get_contents($real);
        $sha=$entry['sha256'] ?? null; $before=$entry['before'] ?? null; $after=$entry['after'] ?? null;
        if (!is_string($old) || !is_string($sha) || !preg_match('/^[a-f0-9]{64}$/D',$sha) ||
            !hash_equals($sha,hash('sha256',$old)) || !is_string($before) || $before==='' ||
            !is_string($after) || $after===$before || substr_count($old,$before)!==1) {
            throw new RuntimeException('Precondition mismatch');
        }
        $new=str_replace($before,$after,$old);
        $changes[$relative]=['path'=>$real,'old'=>$old,'new'=>$new,'sha'=>$sha];
    }
    if (!$apply) { return ['mode'=>'dry_run','files'=>array_keys($changes)]; }
    $backups=[];
    foreach ($changes as $change) {
        // 离线副本须独占使用;再次校验,避免覆盖预检后已变化的文件。
        if (!hash_equals($change['sha'],hash_file('sha256',$change['path']) ?: '')) {
            throw new RuntimeException('File changed after preflight');
        }
        $backup=$change['path'].'.before-'.substr($change['sha'],0,12).'.bak';
        $handle=fopen($backup,'x'); // 不覆盖已有备份。
        if ($handle===false) { throw new RuntimeException('Backup already exists or cannot be created'); }
        chmod($backup,0600);
        $written=fwrite($handle,$change['old']); fclose($handle);
        if ($written!==strlen($change['old'])) { throw new RuntimeException('Incomplete backup'); }
        $backups[]=$backup;
        $temporary=tempnam(dirname($change['path']),'.repair_');
        if ($temporary===false) { throw new RuntimeException('Cannot stage file'); }
        try {
            if (file_put_contents($temporary,$change['new'])!==strlen($change['new']) ||
                !chmod($temporary,fileperms($change['path']) & 0777) ||
                !rename($temporary,$change['path'])) { throw new RuntimeException('Cannot replace file'); }
        } finally { if (is_file($temporary)) { unlink($temporary); } }
    }
    return ['mode'=>'applied','files'=>array_keys($changes),'backups'=>$backups];
}
if (isset($argv[1])) {
    if (count($argv)4 || (isset($argv[3]) && $argv[3]!=='--apply')) {
        throw new RuntimeException('Usage: php batch-repair.php PROJECT_COPY PLAN.json [--apply]');
    }
    if (!is_file($argv[2]) || filesize($argv[2])>2*1024*1024) { throw new RuntimeException('Invalid plan'); }
    $json=file_get_contents($argv[2]);
    if ($json===false) { throw new RuntimeException('Cannot read plan'); }
    $plan=json_decode($json,true,32,JSON_THROW_ON_ERROR);
    if (!is_array($plan) || !array_is_list($plan)) { throw new RuntimeException('Plan must be a list'); }
    echo json_encode(reviewedPatch($argv[1],$plan,($argv[3] ?? '')==='--apply'),JSON_THROW_ON_ERROR),PHP_EOL;
    exit;
}
// 无参数仅演示自建临时夹具;不读取或修改真实项目。
$root=sys_get_temp_dir().'/repair_demo_'.bin2hex(random_bytes(8));
if (!mkdir($root,0700) || !mkdir($root.'/src',0700)) { throw new RuntimeException('Cannot create fixture'); }
$view='<?php function demo_render(string $name): string { return $name; }';
$query=<<<'PHP_SOURCE'
<?php function demo_lookup(PDO $db,string $term): array {
    return $db->query("SELECT id FROM items WHERE name = '$term'")->fetchAll(PDO::FETCH_COLUMN);
}
PHP_SOURCE;
$querySafe=prepare('SELECT id FROM items WHERE name = ?');
    $stmt->execute([$term]);
    return $stmt->fetchAll(PDO::FETCH_COLUMN);
}
PHP_SOURCE;
$plan=[['file'=>'src/view.php','sha256'=>hash('sha256',$view),'before'=>'return $name;',
    'after'=>"return htmlspecialchars(\$name, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');"],
    ['file'=>'src/search.php','sha256'=>hash('sha256',$query),'before'=>$query,'after'=>$querySafe]];
$owned=[$root.'/src/view.php',$root.'/src/search.php',$root.'/.repair-sandbox',
    $root.'/src/view.php.before-'.substr(hash('sha256',$view),0,12).'.bak',
    $root.'/src/search.php.before-'.substr(hash('sha256',$query),0,12).'.bak'];
function check(bool $value,string $name,string $detail=''): void {
    if (!$value) { throw new RuntimeException('FAIL: '.$name); }
    echo $name, ': PASS', $detail, PHP_EOL;
}
try {
    file_put_contents($owned[0],$view); file_put_contents($owned[1],$query); file_put_contents($owned[2],'teaching only');
    $dry=reviewedPatch($root,$plan);
    check($dry['mode']==='dry_run' && file_get_contents($owned[0])===$view,'dry_run',' unchanged');
    $result=reviewedPatch($root,$plan,true);
    check(count($result['files'])===2,'approved_apply',' 2 files');
    require $owned[0]; require $owned[1];
    check(demo_render('<b>A</b>')==='<b>A</b>','render_escape');
    $db=new PDO('sqlite::memory:',null,null,[PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION]);
    $db->exec('CREATE TABLE items(id INTEGER PRIMARY KEY,name TEXT)');
    $insert=$db->prepare('INSERT INTO items VALUES(?,?)'); $insert->execute([1,"O'Reilly"]);
    check(array_map('intval',demo_lookup($db,"O'Reilly"))===[1],'query_normal');
    check(demo_lookup($db,"' OR 1=1 --")===[],'query_shape');
    try { reviewedPatch($root,$plan); throw new LogicException('Stale plan accepted'); }
    catch (RuntimeException $e) { echo 'stale_plan: PASS rejected',PHP_EOL; }
} finally {
    foreach ($owned as $path) { if (is_file($path)) { unlink($path); } }
    rmdir($root.'/src'); rmdir($root); // 仅清理本脚本创建的精确夹具路径。
}
echo 'Runtime: PHP ',PHP_VERSION,' / ',PHP_SAPI,' / isolated fixtures only',PHP_EOL;
# 先运行隔离教学测试。
php batch-repair.php
# 以下仅用于已备份、人工批准的离线副本;默认不写入。
php batch-repair.php /absolute/project-copy reviewed-plan.json
# 核对预览和清单后,显式应用。
php batch-repair.php /absolute/project-copy reviewed-plan.json --apply

本次在macOS上的PHP 8.5.10 WebAssembly执行临时文件补丁与SQLite回归,没有调用ChatGPT,也没有修改真实项目。程序会拒绝再次使用旧哈希清单,避免在已变更文件上重复叠加补丁。

批量补丁脚本预检、应用与回归的实际输出

脚本仅用于落地已经过审核的补丁,不支持推导未知业务规则

变更 处理方式 关键验证
已确认的小范围代码补丁 精确清单、预检后逐文件应用 原始哈希、唯一匹配和回归测试
跨模块授权或数据结构调整 单独设计与人工评审 业务规则、迁移兼容与恢复能力

标记文件名为.repair-sandbox,只应在已确认的项目副本创建。此脚本不是数据库迁移器,不保留文件所有权、ACL和扩展属性,也不保证多文件整体事务;某个文件应用失败时,之前的文件可能已经更新。

正式运行脚本之前,记得先给整个项目生成完整的版本快照。脚本会按单个文件存储原始备份,也不会覆盖已经生成过的备份文件;如果运行过程中部分补丁执行失败,先回滚恢复,把所有改动核对清楚后,再整理新的补丁清单重新执行,不要直接重复运行同一批任务。

遇到四类失败场景,第一时间停止批量操作

  • 哈希不一致:重新读取当前文件并复核差异,不强行更新清单绕过检查。
  • 匹配不唯一或目标重复:拆小补丁并确定上下文,不替换所有同名片段。
  • 新增权限回归:检查是否误删认证或资源条件,先恢复该批次再重新设计。
  • 测试通过但覆盖不完整:补充真实业务和框架集成测试,不把教学用例当作全站安全证明。

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

相关文章

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

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

下载

相关标签:

php chatgpt

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

相关专题

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

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

2023.09.01

11244

6

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

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

2023.10.11

6521

5

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

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

2023.10.11

2155

5

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

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

2023.10.23

4128

4

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

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

2023.10.23

4834

6

html怎么上传
html怎么上传

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

2023.11.03

3791

9

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

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

2023.11.09

5457

8

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

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

2023.11.13

4282

8

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

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

2023.11.27

12222

4

热门下载

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

精品课程

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

共0课时 | 0人学习

MyEclipse学习中心
MyEclipse学习中心

共0课时 | 0人学习

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

共0课时 | 0人学习