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 readdir
        while(($file=readdir($dh) )!== false){  // 循环读取每一个文件
            //判断是文件还是文件夹 is_dir
            if(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,无法利用进行目录遍历

思维导图

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

泛微OA服务器获取 token

泛微OA服务器获取 token 文章目录 泛微OA服务器获取 token一、泛微官方方法1 ecology 系统配置2 发放/生成许可证(appid)3 限制许可证使用ip地址&#xff08;该步骤也可以跳过&#xff09;4 使用 postman 注册5 获取 token6 访问业务系统接口 二、java 代码获取 token三、封装到…

【Redis项目实战】使用Springcloud整合Redis分布式锁+RabbitMQ技术实现高并发预约管理处理系统

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《Redis实战与进阶》 本专栏带你Redis从入门到入魔 这是苏泽的个…

一次生产环境上的dockerd启动失败原因分析

今夜原计划对 生产环境 上的 SDN 组件进行一次紧急扩容操作的&#xff0c;但业务基础环境中的 Docker-Engine 启动不起来了、原定计划也就无法继续进行了。 尽管查清了基础业务环境中的故障原因&#xff0c;但金主DD说今天先不干了&#xff0c;那就整理整理思路写篇流水账吧 。…

Linux环境下使用线程方式操作UART读写功能

目录 概述 1 Linux环境下UART设备 2 轮询方式操作UART功能实现 2.1 打开串口函数&#xff1a;usr_serial_open 2.2 关闭串口函数&#xff1a; usr_serial_close 2.3 发送数据函数&#xff1a; usr_serial_sendbytes 2.4 接收数据函数&#xff1a; thread_uart_readbytes …

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

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

生态,带给用友新机会? | ToB产业观察

ITValue 近年来&#xff0c;不少厂商都将生态调整到战略级别&#xff0c;但做生态往往需要实打实、接地气的生态策略。 作者&#xff5c;杨丽 首发&#xff5c;钛媒体APP ITValue 3月初&#xff0c;用友召开了新一年的首场生态发布会&#xff0c;为接下来一年动作定调&#xff…

17、电源管理入门之Power supply子系统

目录 1. Power supply框架都做些什么 2. 相关数据结构和接口 2.1 数据结构 2.2 接口 3. 充电驱动 3.1 Charger Manager 3.2 Fuel Gauge 3.3 Charger IC 4. 怎样基于power supply class编写PSY driver 参考资料: 对于便携设备来说,电源管理更加的重要,因为电池电量…

数据库系统概念(第一周)

⚽前言 &#x1f3d0;四个基本概念 一、数据 定义 种类 特点 二、数据库 三、数据库管理系统&#xff08;DBMS&#xff09; 四、 数据库系统&#xff08;DBS&#xff09; &#x1f3c0;数据库系统和文件系统对比 文件系统的弊端 &#x1f94e;数据视图 数据抽象 …

jeecgboot 新建子模块 使用@EXCEL实现实现导入导出功能

一&#xff0c;用框架生成增删改查模块 二&#xff0c;在实体类entity 需要导入导出的字段上加上注解Excel 三&#xff0c;在controller类上继承jeecgboot通用controller JeecgController 并且在JeecgController里增加导出模板的方法 /*** 导出excel空模板** param req…

融资项目——网关微服务

1. 网关的路由转发功能 在前后端分离的项目中&#xff0c;网关服务可以将前端的相关请求转发到相应的后端微服务中。 2. 网关微服务的配置 首先需要创建一个网关微服务&#xff0c;并添加依赖。 <!-- 网关 --><dependency><groupId>org.springframework.cl…

相似矩阵及其对角化

目录 相似矩阵 矩阵的相似对角化 对称矩阵的相似对角化 相似矩阵 矩阵的相似对角化 对称矩阵的相似对角化

循序渐进丨MogDB 数据库新特性之SQL PATCH绑定执行计划

1 SQL PATCH 熟悉 Oracle 的DBA都知道&#xff0c;生产系统出现性能问题时&#xff0c;往往是SQL走错了执行计划&#xff0c;紧急情况下&#xff0c;无法及时修改应用代码&#xff0c;DBA可以采用多种方式针对于某类SQL进行执行计划绑定&#xff0c;比如SQL Profile、SPM、SQL …

鸿蒙实战多媒体运用:【音频组件】

音频组件用于实现音频相关的功能&#xff0c;包括音频播放&#xff0c;录制&#xff0c;音量管理和设备管理。 图 1 音频组件架构图 基本概念 采样 采样是指将连续时域上的模拟信号按照一定的时间间隔采样&#xff0c;获取到离散时域上离散信号的过程。 采样率 采样率为每…

macos m1 arm芯片 使用jpype报错 FileNotFoundError: [Errno 2] JVM DLL not found

startJVM(jpype.getDefaultJVMPath()) 报错 Traceback (most recent call last):File "/Users/thomas990p/PycharmProjects/tuya/volcano-biz-scripts/WenKongFa/FinalCode/java2python/CallJavaAPI.py", line 12, in <module>startJVM(jpype.getDefaultJVMPa…

寻找两个正序数组的中位数[困难]

优质博文IT-BLOG-CN 一、题目 给定两个大小分别为m和n的正序&#xff08;从小到大&#xff09;数组nums1和nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为O(log (mn)) 。 示例 1&#xff1a; 输入&#xff1a;nums1 [1,3], nums2 [2] 输出&…

【漏洞复现】帮管客 CRM jiliyu SQL注入漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

用 Axios 提升前端异步请求的效率

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

代码随想录 -- 栈和队列

文章目录 栈实现队列描述题解 用队列实现栈描述题解 有效的括号描述题解 删除字符串中的所有相邻重复项描述题解 逆波兰表达式求值描述题解 滑动窗口最大值描述题解&#xff1a;暴力题解&#xff1a;单调队列 前 K 个高频元素描述题解 栈实现队列 题目链接 描述 使用两个栈实…

WPF开源的一款免费、开箱即用的翻译、OCR工具

前言 今天大姚给大家分享一款由WPF开源的、免费的&#xff08;MIT License&#xff09;、即开即用、即用即走的翻译、OCR工具&#xff1a;STranslate。 WPF介绍 WPF 是一个强大的桌面应用程序框架&#xff0c;用于构建具有丰富用户界面的 Windows 应用。它提供了灵活的布局、…

TCP包头、TCP为什么安全可靠、UDP和TCP的区别、http协议

我要成为嵌入式高手之3月8日Linux高编第十八天&#xff01;&#xff01; __________________________________________________ 学习笔记 TPC包头 1、序号 发送端发送数据包的编号 2、确认号 已经确认接收到的数据的编号&#xff0c;只有当ACK为1时&#xff0c;该位才有用 …