Day24 XD安全学习笔记--PHP 应用文件管理模块显示上传黑白名单类型过滤访问控制
目录一.文件上传1.代码实现1upload.html2upload.php2.遇到的问题及解决二.文件管理1.代码实现2.遇到的问题及解决实现简单的上传文件后缀黑名单过滤、上传文件后缀白名单过滤和文件类型白名单过滤MIME。从开发视角来看可能存在的漏洞绕过黑名单不包含文件类型改包。最安全的是多种过滤一起用增加攻击者的门槛。代码附详细的注释。B站免费课程链接 www.bilibili.com/video/BV12om2YTEgW/?spm_id_from333.788.videopod.episodesvd_source7d8464f1ea919ffdc1761c211c6d1c4ep25一.文件上传1.代码实现1upload.html!--用deepseek写一个纯html精致的文件上传表单-- !DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title文件上传/title style * { box-sizing: border-box; } html, body { height: 100%; } body { margin: 0; padding: 24px; display: flex; align-items: center; justify-content: center; font-family: -apple-system, BlinkMacSystemFont, Segoe UI, PingFang SC, Hiragino Sans GB, Microsoft YaHei, sans-serif; background: radial-gradient(circle at 15% 15%, rgba(255, 255, 255, .18), transparent 45%), radial-gradient(circle at 85% 85%, rgba(255, 255, 255, .12), transparent 45%), linear-gradient(135deg, #667eea 0%, #764ba2 100%); } /* 卡片 */ .card { width: 100%; max-width: 440px; padding: 38px 34px 34px; background: #ffffff; border-radius: 22px; box-shadow: 0 30px 60px -18px rgba(23, 20, 70, .45), 0 0 0 1px rgba(255, 255, 255, .6) inset; animation: rise .5s ease both; } keyframes rise { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); } } /* 头部 */ .head { text-align: center; } .badge { width: 60px; height: 60px; margin: 0 auto; display: flex; align-items: center; justify-content: center; border-radius: 18px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); box-shadow: 0 12px 24px -8px rgba(102, 126, 234, .85); } h1 { margin: 20px 0 8px; font-size: 22px; font-weight: 700; color: #1f2937; letter-spacing: .5px; } .subtitle { margin: 0; font-size: 13.5px; line-height: 1.7; color: #6b7280; } /* 文件选择框 */ .file-input { display: block; width: 100%; margin-top: 28px; padding: 10px; font-family: inherit; font-size: 13.5px; color: #6b7280; background: #f8f9ff; border: 2px dashed #cdd5f5; border-radius: 14px; cursor: pointer; transition: border-color .25s, background .25s, box-shadow .25s; } .file-input:hover { border-color: #8b95f0; background: #f2f4ff; } .file-input:focus { outline: none; border-color: #667eea; background: #f2f4ff; box-shadow: 0 0 0 4px rgba(102, 126, 234, .16); } /* 美化选择文件按钮标准写法 */ .file-input::file-selector-button { margin-right: 14px; padding: 10px 18px; border: 0; border-radius: 10px; font-family: inherit; font-size: 13.5px; font-weight: 600; color: #ffffff; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); box-shadow: 0 8px 16px -8px rgba(102, 126, 234, .95); cursor: pointer; transition: filter .2s, transform .15s; } .file-input::file-selector-button:hover { filter: brightness(1.08); } .file-input::file-selector-button:active { transform: scale(.97); } /* 兼容旧版 WebKit 内核 */ .file-input::-webkit-file-upload-button { margin-right: 14px; padding: 10px 18px; border: 0; border-radius: 10px; font-family: inherit; font-size: 13.5px; font-weight: 600; color: #ffffff; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); cursor: pointer; } /* 提示文字 */ .tip { margin: 14px 0 0; text-align: center; font-size: 12.5px; color: #9ca3af; line-height: 1.6; } /* 提交按钮 */ .btn { display: block; width: 100%; margin-top: 24px; padding: 15px; border: 0; border-radius: 13px; font-family: inherit; font-size: 16px; font-weight: 600; letter-spacing: 1px; color: #ffffff; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); box-shadow: 0 14px 26px -10px rgba(102, 126, 234, .95); cursor: pointer; transition: transform .2s, box-shadow .2s, filter .2s; } .btn:hover { transform: translateY(-2px); filter: brightness(1.06); box-shadow: 0 18px 30px -12px rgba(102, 126, 234, 1); } .btn:active { transform: translateY(0); box-shadow: 0 10px 18px -10px rgba(102, 126, 234, .95); } .btn:focus-visible { outline: 3px solid rgba(102, 126, 234, .45); outline-offset: 3px; } /* 移动端适配 */ media (max-width: 420px) { .card { padding: 30px 22px 26px; border-radius: 18px; } h1 { font-size: 20px; } } /style /head body form classcard action/upload.php methodpost enctypemultipart/form-data !-- 头部图标与标题 -- div classhead div classbadge svg width26 height26 viewBox0 0 24 24 fillnone stroke#ffffff stroke-width2 stroke-linecapround stroke-linejoinround path dM21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4/ polyline points17 8 12 3 7 8/ line x112 y13 x212 y215/ /svg /div h1上传文件/h1 p classsubtitle选择需要上传的文件然后点击下方按钮提交/p /div !-- 文件选择 -- input classfile-input typefile namefile idfile multiple required p classtip支持 PDF / Word / Excel / 图片等格式单个文件不超过 10MB/p !-- 提交 -- button classbtn typesubmit开始上传/button /form /body /html2upload.php?php $name$_FILES[file][name];//第一个参数是表单提交文件的name值也就是file。获取表单提交文件的名字 $type$_FILES[file][type];//获取表单提交文件的类型 $size$_FILES[file][size];//获取表单提交文件的大小 $tmp_name$_FILES[file][tmp_name];// 获取服务器上的临时文件路径 $error$_FILES[file][error];// 错误码 //echo $name.br; //echo $type.br; //echo $size.br; //echo $tmp_name.br; //echo $error.br; //if(move_uploaded_file($tmp_name,upload/.$name)){ ////move_uploaded_file函数是把临时文件移动到指定目录 // echo 文件上传成功; //} //文件后缀黑名单过滤(特定环境可以用类似php5来绕过但是也执行) //$black_extarray(php,asp,jsp,aspx);//将禁止上传文件的后缀写入数组 ////xxx.jpg xxx.jpg //$fengeexplode(.,$name);//将文件名用.分隔然后变成数组。比如上传的文件名为xxx.jpg分隔之后变成数组存储。等价于$fenge[xxx,jpg] //$extsend($fenge);//提取数组$fenge中最后一个元素传给变量$exts //if(in_array($exts,$black_ext)){ ////in_array函数用来判断黑名单数组$black_ext里面包不包含上传文件后缀$exts // echo 非法后缀文件.$exts; //}else{ // move_uploaded_file($tmp_name,,$name); // echo scriptalert(上传成功)/script; //} //文件后缀白名单过滤和上面的黑名单差不多只是判断条件不一样 $allow_extarray(png,jpg,gif,jpeg); //xxx.jpg xxx.png $fengeexplode(.,$name); $extsend($fenge); if(!in_array($exts,$allow_ext)){ echo 非法后缀文件.$exts; }else{ move_uploaded_file($tmp_name,upload/.$name); echo scriptalert(上传成功)/script; } //MIME白名单过滤(和上面的文件后缀白名单过滤差不多可以通过抓包将php后缀的文件类型改成image/png的) $allow_typearray(image/png,image/jpg,image/jpeg,image/gif); if(!in_array($type,$allow_type)){ echo 非法文件.$type; }else{ move_uploaded_file($tmp_name,upload/.$name); echo scriptalert(上传成功)/script; }2.遇到的问题及解决调试访问上传的文件报错可以用小皮的环境访问改文件类型绕过MIME将application/octet-stream改为image/png绕过文件后缀黑名单绕过test.php5解析?php phpinfo();?二.文件管理1.代码实现file-manage.php?php $dir$_GET[path] ?? ./; //获取路径默认./ //$dir./; function show_file($dir){ $dopendir($dir);//opendir() 函数用于打开指定的目录返回句柄用来读取目录中的文件和子目录 while(($filereaddir($d))!false){ //readdir() 函数用于从打开的目录句柄中读取目录中的文件和子目录 echo br; if(is_dir($file)){ //is_dir() 函数用于检查指定的路径是否是一个目录 echo 文件夹.a href?path$file$file/abr; //通过url地址栏加上path参数好让$dir接收 }else{ echo 文件.$file; } } } $black_filepatharray(../,..\\);//可以用./或者././等绕过太灵活了 if(in_array($dir,$black_filepath)){ echo scriptalert(禁止跨目录访问)/script; }else{ show_file($dir);//将函数filelist改为show_file() }2.遇到的问题及解决获取路径错误$dir$_GET[path] ?? ./;的空字符加入./怎么都是1遍历目录和文件while(($filereaddir($d))!false)里面的$filereaddir($d)要括起来不然按照运算符优先级先执行readdir($d)!false运算的结果为布尔赋值给$file了。为什么filelist函数报错因为filelist是小迪之前就写好的代码文件有这个函数用show_file替换就好了。可以找到小皮的php.ini文件来限制目录的访问

相关新闻

mlx-serve 推理协议深挖:6 种思考格式如何与受限 JSON 解码共存不翻车

mlx-serve 推理协议深挖:6 种思考格式如何与受限 JSON 解码共存不翻车

【免费下载链接】mlx-serve Native LLM inference server for Apple Silicon. OpenAI Anthropic API compatible. No Python. Zig backend, Swift frontend macOS app with chat, music, voice, video generation. 项目地址: https://gitcode.com/gh_mirrors/ml/ml…

2026/10/11 8:48:40 阅读更多 →
车载系统开发面试高频考点:从AOSP裁剪到CarService实战解析

车载系统开发面试高频考点:从AOSP裁剪到CarService实战解析

做车载系统开发这行,面试和普通App开发面试完全不是一个画风。这几年汽车智能化加速,一线车机厂商对候选人的要求已经从“能写界面、能调接口”升级到“懂AOSP裁剪、懂CarService通信、能扛稳定性专项”。我最近帮部门整理题库时,翻出这些年面…

2026/10/11 8:48:40 阅读更多 →
Euro-Office DocumentServer首次体验:在线创建与编辑Word、Excel和PowerPoint

Euro-Office DocumentServer首次体验:在线创建与编辑Word、Excel和PowerPoint

【免费下载链接】DocumentServer 项目地址: https://gitcode.com/gh_mirrors/doc/DocumentServer 点击查看 免费下载 Euro-Office DocumentServer 是一款开源自托管的在线文档服务器:部署后,你可以在浏览器里直接在线创建与编辑 Word&#x…

2026/10/11 8:48:40 阅读更多 →

最新新闻

深度学习OCR系统实战:基于PyTorch的CRNN+CTC文字识别

深度学习OCR系统实战:基于PyTorch的CRNN+CTC文字识别

简介:基于深度学习的文字识别系统完整项目包,面向毕业设计、课程设计与期末大作业场景,适合需要快速搭建OCR系统的计算机相关专业学生。项目采用CNN与RNN结合实现文字检测与识别,覆盖图像预处理、模型训练、后端接口与移动端展示全…

2026/10/11 10:25:10 阅读更多 →
使用 claude-howto 的 blog-draft 技能与草稿模板,系统化产出高质量技术博客

使用 claude-howto 的 blog-draft 技能与草稿模板,系统化产出高质量技术博客

教程文档 【免费下载链接】claude-howto A visual, example-driven guide to Claude Code — from basic concepts to advanced agents, with copy-paste templates that bring immediate value. 项目地址: https://gitcode.com/GitHub_Trending/cl/claude-howto 点…

2026/10/11 10:25:10 阅读更多 →
Excel自动评分:用LOOKUP和IF函数实现体育成绩折算自动化

Excel自动评分:用LOOKUP和IF函数实现体育成绩折算自动化

简介:这份资源是一份面向体育教师及学校教务人员的Excel实用教程文档,聚焦体育测试成绩换算这一高频痛点,帮助读者用公式与函数替代人工比对,降低错漏率。文档围绕学生成绩空表搭建、跳远与跳绳评分标准表制作、LOOKUP近似匹配与I…

2026/10/11 10:25:10 阅读更多 →
Legendary OSINT 海事篇:AIS 船舶追踪工具全景对比

Legendary OSINT 海事篇:AIS 船舶追踪工具全景对比

Legendary OSINT 海事篇:AIS 船舶追踪工具全景对比 【免费下载链接】Legendary_OSINT A list of OSINT tools & resources for (fraud-)investigators, CTI-analysts, KYC, AML and more. 项目地址: https://gitcode.com/GitHub_Trending/le/Legendary_OSINT…

2026/10/11 10:25:10 阅读更多 →
ProxCenter热迁移深度解析:VDDK+nbdkit实现虚拟机零停机迁移的原理与调优

ProxCenter热迁移深度解析:VDDK+nbdkit实现虚拟机零停机迁移的原理与调优

【免费下载链接】proxcenter-ui ProxCenter is an alternative to VMware vCenter for Proxmox environments. It provides a modern, intuitive web interface to manage multiple Proxmox VE clusters and Proxmox Backup Server instances from a single pane of glass. 项目…

2026/10/11 10:25:10 阅读更多 →
2025年AI IDE实战测评榜:从个人开发到企业部署的完整选型攻略(TaoToken统一API接入篇)

2025年AI IDE实战测评榜:从个人开发到企业部署的完整选型攻略(TaoToken统一API接入篇)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:24:10 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →