Day24:安全开发-PHP应用文件管理模块显示上传黑白名单类型过滤访问控制

目录

文件管理模块-上传-过滤机制

文件管理模块-显示-过滤机制

思维导图


PHP知识点

功能:新闻列表,会员中心,资源下载,留言版,后台模块,模版引用,框架开发等

技术:输入输出,超全局变量,数据库操作,逻辑架构,包含上传&下载删除;

技术:JS&CSS混用,Cookie,Session操作,MVC架构,ThinkPHP引用等。

文件管理模块-上传-过滤机制

PHP文件上传

$_FILES:PHP中一个预定义的超全局变量,用于在上传文件时从客户端接收文件,并将其保存到服务器上。它是一个包含上传文件信息的数组,包括文件名、类型、大小、临时文件名等信息。
$_FILES["表单值"]["name"] 获取上传文件原始名称
$_FILES["表单值"]["type"] 获取上传文件MIME类型
$_FILES["表单值"]["size"] 获取上传文件字节单位大小
$_FILES["表单值"]["tmp_name"] 获取上传的临时副本文件名
$_FILES["表单值"]["error"] 获取上传时发生的错误代码
move_uploaded_file() 将上传的文件移动到指定位置的函数

过滤的类型:

1、无过滤机制

2、黑名单过滤机制

3、白名单过滤机制

4、文件类型过滤机制

AI生成前端代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>文件上传页面</title><style>body {font-family: Arial, sans-serif;background-color: #f2f2f2;padding: 20px;}h1 {text-align: center;margin-top: 50px;}form {background-color: #fff;border-radius: 10px;padding: 20px;margin-top: 30px;max-width: 600px;margin: 0 auto;}input[type="file"] {margin-top: 20px;margin-bottom: 20px;}button {background-color: #4CAF50;color: #fff;padding: 10px 20px;border: none;border-radius: 5px;cursor: pointer;}button:hover {background-color: #3e8e41;}</style>
</head>
<body>
<h1>文件上传</h1>
<form action="upload.php" method="POST" enctype="multipart/form-data"><label for="file">选择文件:</label><br><input type="file" id="file" name="f"><br><button type="submit">上传文件</button>
</form>
</body>
</html>

无过滤机制

upload.php代码如下:

<?php$name=$_FILES['f']['name'];          // 文件原名
$type=$_FILES['f']['type'];          // 文件类型
$size=$_FILES['f']['size'];          // 文件大小
$tmp_name=$_FILES['f']['tmp_name'];  // 上传临时目录
$error=$_FILES['f']['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)){   // 转移到网站目录/upload/echo "文件上传成功!";
}
?>

../www/demo3/upload/xxx.png

黑名单过滤机制

upload.php代码如下:

<?php$name=$_FILES['f']['name'];          // 文件原名
$type=$_FILES['f']['type'];          // 文件类型
$size=$_FILES['f']['size'];          // 文件大小
$tmp_name=$_FILES['f']['tmp_name'];  // 上传临时目录
$error=$_FILES['f']['error'];        // 成功/失败// 上传文件后缀过滤 黑名单机制
$black_ext=array('php','asp','jsp','aspx');
//xxx.jpg xxx.png
// explode('.', $name) 使用点号作为分隔符,将 $name 字符串拆分成一个数组。
// 拆分后的结果存储在变量 $fenge 中,每个元素代表一个分隔后的部分。
$fenge = explode('.',$name);
// end($fenge) 返回数组 $fenge 的最后一个元素,即最后一部分的文件扩展名。
// 将最后一个元素赋给变量 $exts,即获取到文件的扩展名。
$exts = end($fenge);
if(in_array($exts,$black_ext)){echo '非法后缀文件'.$exts;
}else{move_uploaded_file($tmp_name,'upload/'.$name);echo '<script>alert("上传成功")</script>';
}?>

根据环境不同有不同的绕过,如这里可尝试上传 php5

缺陷:若未考虑到各种变形后缀,则可能被绕过

白名单过滤机制

upload.php代码如下:

<?php$name=$_FILES['f']['name'];          // 文件原名
$type=$_FILES['f']['type'];          // 文件类型
$size=$_FILES['f']['size'];          // 文件大小
$tmp_name=$_FILES['f']['tmp_name'];  // 上传临时目录
$error=$_FILES['f']['error'];        // 成功/失败//上传文件后缀过滤 白名单机制
$allow_ext=array('png','jpg','gif','jpeg');
//xxx.jpg xxx.png
$fenge = explode('.',$name);
$exts = end($fenge);
if(!in_array($exts,$allow_ext)){echo '非法后缀文件'.$exts;
}else{move_uploaded_file($tmp_name,'upload/'.$name);echo '<script>alert("上传成功")</script>';
}?>

MIME文件类型过滤机制

upload.php代码如下:

<?php$name=$_FILES['f']['name'];          // 文件原名
$type=$_FILES['f']['type'];          // 文件类型
$size=$_FILES['f']['size'];          // 文件大小
$tmp_name=$_FILES['f']['tmp_name'];  // 上传临时目录
$error=$_FILES['f']['error'];        // 成功/失败//MIME文件类型过滤
$allow_type=array('image/png','image/jpg','image/jpeg','image/gif');
if(!in_array($type,$allow_type)){echo '非法后缀文件';
}else{move_uploaded_file($tmp_name,'upload/'.$name);echo '<script>alert("上传成功")</script>';}
?>

Content-Type: application/octet-stream 改为 Content-Type: image/png

文件管理模块-显示-过滤机制

功能:显示 上传 下载 删除 编辑 包含等
1.打开目录读取文件列表
2.递归循环读取文件列表
3.判断是文件还是文件夹
4.PHP.INI目录访问控制

is_dir() 函数用于检查指定的路径是否是一个目录
opendir() 函数用于打开指定的目录,返回句柄,用来读取目录中的文件和子目录
readdir() 函数用于从打开的目录句柄中读取目录中的文件和子目录
open_basedir:PHP.INI中的设置用来控制脚本程序访问目录

示例代码如下:

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>文件列表</title><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"><style type="text/css">ul {list-style: none;padding: 0;margin: 0;}li {margin-bottom: 10px;}i {margin-right: 10px;}a {text-decoration: none;color: #333;}</style>
</head>
<body>
<h1>当前目录下的文件列表</h1>
<ul></ul>
</body>
</html><?php
$dir = $_GET['path'] ?? './';  // 读取 GET 提交的参数 path=//1.打开目录,读取文件列表 opendir
//2.循环读取文件列表 while readdir
//3.判断是文件还是文件夹 is_dir//打开目录,读取文件列表 opendir
function filelist($dir){if($dh = opendir($dir)){  // 打开文件夹//循环读取文件列表 while readdirwhile(($file=readdir($dh) )!== false){  // 循环读取每一个文件//判断是文件还是文件夹 is_dirif(is_dir($file)){// PHP 后端先对变量进行替换,在发送前端代码echo "<li><i class='fa fa-folder'></i> <a href='?path=$file'>" . $file . '</a></li>';  // . 拼接起来}else{echo '<li><i class="fa fa-file"></i> <a href="#">' . $file . '</a></li>';}}}
}filelist($dir);// 文件删除
function del($file){if(!is_dir($file)){unlink($file);    // unlink($file) 是一个 PHP 内置函数,用于删除指定的文件。echo "<script>alert('删除成功')</script>";}
}if(isset($_GET['del'])){del($_GET['del']);
}// 文件下载
function down($filepath){// basename($filepath) 是一个 PHP 内置函数,用于从文件路径中提取文件名部分。$fileName = basename($filepath);// 设置响应头,指定下载文件的 MIME 类型为 application/octet-stream,表示通用的二进制流。header("Content-Type: application/octet-stream");// 设置响应头,指定下载时的文件名,并将其设置为 $fileName。header("Content-Disposition: attachment; filename=\"" . $fileName . "\"");// 设置响应头,指定下载文件的大小。header("Content-Length: " . filesize($filepath));// 用于将指定文件的内容输出到浏览器,实现文件下载。readfile($filepath);
}if(isset($_GET['down'])){down($_GET['down']);
}
?>

需要限制对文件/文件夹的访问权限

方式一:黑名单过滤

// 将filelist($dir);替换为下面的代码即可
//黑名单过滤
$black_filepath=array('../');
if(in_array($dir,$black_filepath)){echo '<script>alert("禁止跨目录访问!")</script>';
}else{filelist($dir);
}
  • 禁止了../ 即当 url 中传入?path=../ 时,会弹窗禁止跨目录访问!,但是这里可以输入改为..\, 即可绕过该黑名单。

方式二:PHP.INI目录访问控制

网站根目录设置为D:\phpStudy\PHPTutorial\WWW\blog,无法利用进行目录遍历

思维导图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/731363.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[java基础揉碎]方法的重写/覆盖

重写介绍 简单的说:方法覆盖(重写)就是子类有一个方法,和父类(也可能是爷爷,更上一级)的某个方法的名称、返回类型、参数一样&#xff0c;那么我们就说子类的这个方法 覆盖了父类的方法 重写重载对比

语音模块学习——LSYT201B模组(实际操作篇)

目录 一、定制词条 二、直接用串口通信 三、使用单片机通信 理论篇在这&#xff0c;依旧是深圳雷龙发展的语音模块。 http://t.csdnimg.cn/2SzJL 一、定制词条 因为我想后面加到我的毕设上加个语音模块&#xff0c;所以定制的词条都是和芯测相关的。 动作词条播报串口输…

List--splice使用技巧

splice : 拼接两个list api: void dump(list<int>& li) {for(auto & i :li)cout<<i<< " ";cout<<endl; } int main() { list<int> li1 {1,3,5};list<int> li2 {2,4,6}; }1 c.splice(pos,c2); // li的开头插入li2链表…

深入理解锁的升级与降级

深入理解锁的升级与降级 在并发编程中&#xff0c;锁是一种非常重要的同步机制&#xff0c;用于协调多个线程对共享资源的访问。为了提高性能和减少线程间的竞争&#xff0c;现代操作系统和编程语言运行时通常提供了多种类型的锁&#xff0c;并支持锁的升级和降级策略。本文将…

排序(6)——快速排序算法之挖坑版&前后指针版

目录 挖坑版 基本思路 代码实现 注意点 前后指针版 基本思路 代码实现 注意点 由于hoare版本的快速排序有很多坑和需要注意的地方&#xff0c;就会导致代码写起来不容易&#xff0c;这里我们给出两种不同的单趟排序思路&#xff1a;挖坑版&#xff06;前后指针版。 挖坑…

Python 读取写入excel文件

使用Python读取和写入excel的xlsx、xls文件 目录 读取xlsx文件 安装三方库 引入三方库 读取数据 打开文件 表名 最大行数 最大列数 读取一张表 读取整个文件 返回xls整体内容 安装三方包 读取内容 写入xls文件 引入三方库 创建文件并写入数据 报错及解决 报错…

一、系统架构

1系统架构师概述和意义&#xff1a; 系 统 架 构 是 系 统 的 一 种 整 体 的 高 层 次 的 结 构 表 示 &#xff0c; 是 系 统 的 骨 架 和 根 基 &#xff0c; 其 决 定 了 系 统 的 健 壮 性 和 生 命 周 期 的 长 短 。 2定义 项 目 的 总 设 计 师 &#xff0c; 他 是 …

房屋租赁系统|基于 Mysql+Java+JSP技术的房屋租赁系统设计与实现(可运行源码+数据库+设计文档+部署说明+视频演示)

目录 文末获取源码 前台首页功能 管理员功能 租户功能 房屋租赁系统结构图 数据库设计 lunwen参考 概述 源码获取 文末获取源码 前台首页功能 管理员功能 租户功能 房屋租赁系统结构图 数据库设计 lunwen参考 概述 随着科学技术的飞速发展&#xff0c;社会的方方面面…

SQL语言(数据库编程)

一.select查询 在数据库编程中,SQL(Structured Query Language,结构化查询语言)是一种用于管理关系数据库管理系统(RDBMS)的标准编程语言。其中,SELECT 是 SQL 中最常用的查询语句,用于从数据库表中检索数据。 下面是一个基本的 SELECT 查询的示例: SELECT column1…

说一下HTML5有哪些新特性?

新增语义化标签&#xff0c;音频视频标签 新增DOM查询 --- querySelector() 、 querySelectorAll() canvas绘图 --- 用js绘制图像&#xff0c;可绘制一些基本图形、动画&#xff0c;适合做游戏 SVG绘图 --- 可缩放矢量图形&#xff0c;可绘制一些基本图形&#xff0c;适合做地图…

Flutter APP下载更新

由于我做的项目不是放在APP商店&#xff08;公司内部用&#xff09;的&#xff0c;一些flutter的第三方库不合适我&#xff0c;我需要用的是从网上下载再安装&#xff08;从服务下&#xff09;&#xff0c;网上也找了花了我好几天时间。不全又乱&#xff0c;这我自己做一下备份…

ODI报错

三月 08, 2024 1:20:09 下午 oracle.odi.mapping 信息: Start generation of map physical design: MapPhysicalDesign New_Mapping.物理 三月 08, 2024 1:20:09 下午 oracle.odi.mapping 信息: Finished generation of map physical design: MapPhysicalDesign New_Mapping.物…

HTML—基本介绍

HTML是一种超文本标记语言(HyperText Markup Language)&#xff0c;用于创建网页的标记语言超文本&#xff1a;是指页面内可以包含图片、链接、声音、视频等内容标记&#xff1a;HTML富含大量的标签供程序员使用&#xff0c;通过标记符号来规定指定内容的样式 浏览器最终根据不…

HybridCLR热更新介绍

官方文档 参照视频 HybridCLR介绍 HybridCLR是一个特性完整、零成本、高性能、低内存的近乎完美的Unity全平台原生c#热更方案 HybridCLR与ToLua/XLua、ILRuntime有什么不同 什么是游戏热更新&#xff1a;有热更的游戏更新流程 游戏热更新的种类 资源热更新&#xff1a;主要…

内存分区与具体介绍:

1. 内存分区图&#xff1a; 2. 分区介绍&#xff1a; 2.1. 栈区&#xff1a; 存放&#xff1a;临时的局部变量、函数的传参 特点&#xff1a;占用内存小&#xff0c;速度快 数据的存储和释放采用栈式结构&#xff0c;先入后出&#xff0c;类似于C下类的构造析构函数 2.2. 堆区&…

在Linux(Ubuntu)中使用终端编译 vscode安装

文章目录 &#x1f4da;在Linux&#xff08;Ubuntu&#xff09;中使用终端编译&#x1f407;.cpp程序编译&#x1f407;.py程序编译&#x1f407;查看Python、C编程环境 &#x1f4da;vscode安装 &#x1f4da;在Linux&#xff08;Ubuntu&#xff09;中使用终端编译 虚拟机安装…

【硬件工程师面经整理25_AD】

文章目录 1 AD设计电路全流程2 ad和cadence区别-逻辑上的区别 1 AD设计电路全流程 软件AD or 模拟数字&#xff1f; 软件AD&#xff1a;AD设计电路全流程包括以下步骤&#xff1a;选择AD库和添加、画原理图、PCB布局、PCB布线、PCB打样、PCB加工 模拟数字&#xff1a; 需求分…

实现HttpServletRequest下多次获取流数据

HttpServletRequest下多次获取流数据 背景示例错误的尝试全局替换执行顺序 背景 ​众所周知request的输入流只能读取一次&#xff0c;不能重复读取。而在HttpServletRequest中&#xff0c;获取请求体数据的流&#xff08;通过getInputStream()方法&#xff09;默认只能被读取一…

移动端精准测试之跨版本覆盖率合并

一&#xff0c;项目简介 在移动端项目测试过程中&#xff0c;尤其是发版前的回归测试阶段&#xff0c;会遇到这样的情况&#xff0c;在测试过程中测试不断地发现问题&#xff0c;开发就进行修改&#xff0c;然后打包测试。而测试完成后呢&#xff0c;业务测试同学想知道整个回归…

Qt 5.14.2 网络编程揭秘:构建高效HTTP客户端与文件下载器

引言 在当今的软件开发世界中&#xff0c;网络通信已成为不可或缺的一部分。Qt&#xff0c;作为一个跨平台的C框架&#xff0c;为我们提供了强大的网络编程能力。本文将带你深入Qt的网络模块&#xff0c;探索如何使用QNetworkAccessManager、QNetworkRequest和QNetworkReply等核…