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;所以定制的词条都是和芯测相关的。 动作词条播报串口输…

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

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

Python 读取写入excel文件

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

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

目录 文末获取源码 前台首页功能 管理员功能 租户功能 房屋租赁系统结构图 数据库设计 lunwen参考 概述 源码获取 文末获取源码 前台首页功能 管理员功能 租户功能 房屋租赁系统结构图 数据库设计 lunwen参考 概述 随着科学技术的飞速发展&#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;中使用终端编译 虚拟机安装…

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

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

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

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

【HarmonyOS】ArkTS-对象方法

目录 对象方法实例 对象方法 方法作用&#xff1a;描述对象的具体行为 约定方法类型 interface 接口名称 { 方法名: (参数:类型) > 返回值类型 }interface Person{dance: () > voidsing: (song: string) > void}添加方法&#xff08;箭头函数&#xff09; let ym: P…

微前端之再说无界的使用

运行模式 保活模式单例模式重建模式 生命周期改造 改造入口函数&#xff1a; 应用间通信 原理props 通信 主应用可以通过 props 注入数据和方法&#xff1a;子应用可以通过 $wujie 对象来获取数据&#xff1a; window 通信 主应用调用子应用的全局数据&#xff1a;子应用调用主…

lvs集群中NAT模式

群集的含义 由多台主机构成&#xff0c;但对外表现为一个整体&#xff0c;只提供一个访问入口&#xff0c;相当于一台大型的计算机。 横向发展:放更多的服务器&#xff0c;有调度分配的问题。 垂直发展&#xff1a;升级单机的硬件设备&#xff0c;提高单个服务器自身功能。 …

如何保证消息不丢之MQ重试机制消息队列

1. 简介 死信队列&#xff0c;简称&#xff1a;DLX&#xff0c;Dead Letter Exchange&#xff08;死信交换机&#xff09;&#xff0c;当消息成为Dead message后&#xff0c;可以被重新发送到另外一个交换机&#xff0c;这个交换机就是DLX 那么什么情况下会成为Dead message&a…

波卡 Alpha 计划启动,呼唤先锋创新者重新定义 Web3 开发

原文&#xff1a;https://polkadot.network/blog/the-polkadot-alpha-program-a-new-era-for-decentralized-building-collaboration/ 编译&#xff1a;OneBlock 区块链领域不断发展&#xff0c;随之而来的是发展和创新机会的增加。而最新里程碑是令人振奋的 Polkadot Alpha …

【刷题记录】详谈设计循环队列

下题目为个人的刷题记录&#xff0c;在本节博客中我将详细谈论设计循环队列的思路&#xff0c;并给出代码&#xff0c;有需要借鉴即可。 题目&#xff1a;LINK 循环队列是线性表吗&#xff1f;或者说循环队列是线性结构吗&#xff1f; 对于这个问题&#xff0c;我们来看一下线…

【Linux进阶之路】网络 —— “?“ (下)

文章目录 前言一、概念铺垫1.TCP2.全双工 二、网络版本计算器1. 原理简要2. 实现框架&&代码2.1 封装socket2.2 客户端与服务端2.3 封装与解包2.4 请求与响应2.5 对数据进行处理2.6 主程序逻辑 3.Json的简单使用 总结尾序 前言 在上文我们学习使用套接字的相关接口进行了…

Tomcat的安装

下载Tomcat&#xff08;这里以Tomcat8.5为例&#xff09; 直接进入官网进行下载&#xff0c;Tomcat官网 选择需要下载的版本&#xff0c;点击下载这里一定要注意&#xff1a;下载路径一定要记住&#xff0c;并且路径中尽量不要有中文&#xff01;&#xff01;&#xff01;&…