安全开发
PHP
基础
增:insert into 表名(
列名 1
,列名 2
) value('列 1 值 1', '列 2 值 2');删:delete from 表名 where 列名 = '条件';
改:update 表名 set 列名 = 数据 where 列名 = '条件';
查:select * from 表名 where 列名='条件';
mysqli_connect() 打开一个到 MySQL 的新的连接。mysqli_select_db() 更改连接的默认数据库。
mysqli_query() 执行某个针对数据库的查询。
mysqli_fetch_row() 从结果集中取得一行,并作为枚举数组返回。 mysqli_close() 关闭先前打开的数据库连接。
参考:https://www.runoob.com/php/php-ref-mysqli.html
全局变量参考:https://www.w3school.com.cn/php/php_superglobals.asp#google_vignette
$_SERVER['PHP_SELF'] | 返回当前执行脚本的文件名。 |
---|---|
$_SERVER['GATEWAY_INTERFACE'] | 返回服务器使用的 CGI 规范的版本。 |
$_SERVER['SERVER_ADDR'] | 返回当前运行脚本所在的服务器的 IP 地址。 |
$_SERVER['SERVER_NAME'] | 返回当前运行脚本所在的服务器的主机名(比如 www.w3school.com.cn)。 |
$_SERVER['SERVER_SOFTWARE'] | 返回服务器标识字符串(比如 Apache/2.2.24)。 |
$_SERVER['SERVER_PROTOCOL'] | 返回请求页面时通信协议的名称和版本(例如,"HTTP/1.0")。 |
$_SERVER['REQUEST_METHOD'] | 返回访问页面使用的请求方法(例如 POST)。 |
$_SERVER['REQUEST_TIME'] | 返回请求开始时的时间戳(例如 1577687494)。 |
$_SERVER['QUERY_STRING'] | 返回查询字符串,如果是通过查询字符串访问此页面。 |
$_SERVER['HTTP_ACCEPT'] | 返回来自当前请求的请求头。 |
$_SERVER['HTTP_ACCEPT_CHARSET'] | 返回来自当前请求的 Accept_Charset 头( 例如 utf-8,ISO-8859-1) |
$_SERVER['HTTP_HOST'] | 返回来自当前请求的 Host 头。 |
$_SERVER['HTTP_REFERER'] | 返回当前页面的完整 URL(不可靠,因为不是所有用户代理都支持)。 |
$_SERVER['HTTPS'] | 是否通过安全 HTTP 协议查询脚本。 |
$_SERVER['REMOTE_ADDR'] | 返回浏览当前页面的用户的 IP 地址。 |
$_SERVER['REMOTE_HOST'] | 返回浏览当前页面的用户的主机名。 |
$_SERVER['REMOTE_PORT'] | 返回用户机器上连接到 Web 服务器所使用的端口号。 |
$_SERVER['SCRIPT_FILENAME'] | 返回当前执行脚本的绝对路径。 |
$_SERVER['SERVER_ADMIN'] | 该值指明了 Apache 服务器配置文件中的 SERVER_ADMIN 参数。 |
$_SERVER['SERVER_PORT'] | Web 服务器使用的端口。默认值为 "80"。 |
$_SERVER['SERVER_SIGNATURE'] | 返回服务器版本和虚拟主机名。 |
$_SERVER['PATH_TRANSLATED'] | 当前脚本所在文件系统(非文档根目录)的基本路径。 |
$_SERVER['SCRIPT_NAME'] | 返回当前脚本的路径。 |
$_SERVER['SCRIPT_URI'] | 返回当前页面的 URI。 |
身份验证-Cookie 使用
1、客户端向服务器发送 HTTP 请求。
2、服务器检查请求头中是否包含 cookie 信息。
3、如果请求头中包含 cookie 信息,则服务器使用该 cookie 来识别客户端,否则服务 器将生成一个新的 cookie。
4、服务器在响应头中设置 cookie 信息并将其发送回客户端。
5、客户端接收响应并将 cookie 保存在本地。
6、当客户端发送下一次 HTTP 请求时,它会将 cookie 信息附加到请求头中。
7、服务器收到请求并检查 cookie 的有效性。
8、如果 cookie 有效,则服务器响应请求。否则,服务器可能会要求客户端重新登录。
setcookie(): 设置一个 cookie 并发送到客户端浏览器。
unset(): 用于删除指定的 cookie。
身份验证-Session 使用
1、客户端向服务器发送 HTTP 请求。
2、服务器为客户端生成一个唯一的 session ID,并将其存储在服务器端的存储器中 (如文件、数据库等)。
3、服务器将生成的 session ID 作为一个 cookie 发送给客户端。
4、客户端将 session ID 保存为一个 cookie,通常是在本地浏览器中存储。
5、当客户端在发送下一次 HTTP 请求时,它会将该 cookie 信息附加到请求头中,以便 服务器可以通过该 session ID 来识别客户端。
6、服务器使用 session ID 来检索存储在服务器端存储器中的与该客户端相关的 session 数据,从而在客户端和服务器之间共享数据。
session_start(): 启动会话,用于开始或恢复一个已经存在的会话。
$_SESSION: 用于存储和访问当前会话中的所有变量。
session_destroy(): 销毁当前会话中的所有数据。
session_unset(): 释放当前会话中的所有变量。
Session 存储路径:PHP.INI 中 session.save_path 设置路径
唯一性判断-Token 使用
1、生成 Token 并将其存储在 Session
2、生成 Token 并将其绑定在 Cookie 触发
3、尝试登录表单中带入 Token 验证逻辑
示例
gbook.php
php
<script src="/ueditor/ueditor.config.js">/*引入配置文件*/</script>
<script src="/ueditor/ueditor.all.js">/*引入源码文件*/</script>
<form id="form1" name="form1" method="post" action="">
用户名:<input type="text" name="username" maxlength="2000"><br>
内容:
<textarea id="content" rows="10" cols="70" name="content" style="border:1px solid #E5E5E5;">
</textarea>
<script type="text/javascript">
UE.getEditor("content");
//实例化编辑器传参,id为将要被替换的容器。
</script>
<input type="submit" name="submit" id="submit" value="提交">
</form>
<?php
include 'config.php';
function add_gbook($con){
$u = @$_POST['username'];
if (isset($u)) {
$c = @$_POST['content'];
$i = @$_SERVER['REMOTE_ADDR'];
$ua = @$_SERVER['HTTP_USER_AGENT'];
$sql = "insert into gbook(`username`, `content`,`ipaddr`,`uagent`) value('$u', '$c','$i','$ua');";
if (mysqli_query($con, $sql)) {
echo "<script>alert('留言成功!')</script>";
}
}
}
function show_gbook($con,$del){
$sql1="select * from gbook";
$data=mysqli_query($con,$sql1);
while ($row=mysqli_fetch_row($data)) {
echo '<hr>';
echo '用户名:'.$row[0].'<br>';
echo '内容:'.$row[1].'<br>';
echo 'IP地址:'.$row[2].'<br>';
echo 'UA浏览器:'.$row[3].'<br>';
if($del=='del'){
echo "<a href='gbook-admin.php?del=$row[0]'>删除</a>";
}
}
}
add_gbook($con);
show_gbook($con,'x');
//if (!$con)
//{
// die("连接错误: " . mysqli_connect_error());
//}else{
// $u=@$_POST['username'];
// if(isset($u)){
// $c=@$_POST['content'];
// $i=@$_SERVER['REMOTE_ADDR'];
// $ua=@$_SERVER['HTTP_USER_AGENT'];
// $sql="insert into gbook(`username`, `content`,`ipaddr`,`uagent`) value('$u', '$c','$i','$ua');";
// if(mysqli_query($con,$sql)){
// echo "<script>alert('留言成功!')</script>";
// $sql1="select * from gbook";
// $data=mysqli_query($con,$sql1);
// while ($row=mysqli_fetch_row($data))
// {
// echo '<hr>';
// echo '用户名:'.$row[0].'<br>';
// echo '内容:'.$row[1].'<br>';
// echo 'IP地址:'.$row[2].'<br>';
// echo 'UA浏览器:'.$row[3].'<br>';
// }
//
// }else{
// echo "<script>alert('留言失败!')</script>";
// }
//
// }
//
//}
?>
demo01
php
<?php
$dbip='localhost';
$dbuser='root';
$dbpass='123456';
$dbname='demo01';
$con=mysqli_connect($dbip,$dbuser,$dbpass,$dbname);
gbook-admin.php
php
<?php
include '../config.php';
include '../gbook.php';
show_gbook($con,'del');
$delstr=@$_GET['del'];
if(isset($delstr)){
$sql2="delete from gbook where username = '$delstr';";
if(mysqli_query($con,$sql2)){
echo "<script>alert('删除成功!')</script>";
}
}
文件管理模块-上传-过滤机制
$_FILES:PHP
中一个预定义的超全局变量,用于在上传文件时从客户端接收文件,并将其保存到服务器上。它是一个包含上传文件信息的数组,包括文件名、类型、大小、临时文件名等信息。
$_FILES["表单值"]["name"]
获取上传文件原始名称
$_FILES["表单值"]["type"]
获取上传文件 MIME 类型
$_FILES["表单值"]["size"]
获取上传文件字节单位大小
$_FILES["表单值"]["tmp_name"]
获取上传的临时副本文件名
$_FILES["表单值"]["error"]
获取上传时发生的错误代码
move_uploaded_file() 将上传的文件移动到指定位置的函数
is_dir() 函数用于检查指定的路径是否是一个目录
opendir() 函数用于打开指定的目录,返回句柄,用来读取目录中的文件和子目录
readdir() 函数用于从打开的目录句柄中读取目录中的文件和子目录
open_basedir:PHP.INI 中的设置用来控制脚本程序访问目录
文件包含:
include() 在错误发生后脚本继续执行
require() 在错误发生后脚本停止执行
include_once() 如果已经包含,则不再执行
require_once() 如果已经包含,则不再执行
示例
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)){
// echo "文件上传成功!";
//}
//上传文件后缀过滤 黑名单机制
//$black_ext=array('php','asp','jsp','aspx');
xxx.jpg xxx.png
//$fenge = explode('.',$name);
//$exts = end($fenge);
//if(in_array($exts,$black_ext)){
// echo '非法后缀文件'.$exts;
//}else{
// move_uploaded_file($tmp_name,'upload/'.$name);
// echo '<script>alert("上传成功")</script>';
//}
//上传文件后缀过滤 白名单机制
//$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文件类型过滤
$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>';
}
?>
filemange.php
php
<?php
ini_set('open_basedir',__DIR__);
$path=$_GET['path'] ?? './';
$action = isset($_GET['a'])?$_GET['a']:'';
$path = isset($_GET['path'])?$_GET['path']:'.';
if(is_file($path))
{
//获得文件名
$file = basename($path);
//获得路径
$path = dirname($path);
}
//判断,不是目录
elseif(!is_dir($path))
{
echo '我只会吃瓜!';
}
function getlist($path){
$hd=opendir($path);
while(($file_name=readdir($hd) )!== false){
if($file_name != '.' && $file_name != '..'){
$file_path = "$path/$file_name";
$file_type = filetype($file_path);
}
$list[$file_type][] = array( //$file_type = dir 和 file $list['dir'] 和 $list['file']
'file_name'=>$file_name, //文件名存储键值file_name
'file_path'=>$file_path, //文件路径存储键值file_path
'file_size'=>round(filesize($file_path)/1024), //通过换算文件大小存储键值file_path
'file_time'=>date('Y/m/d H:i:s',filemtime($file_path)), //获取文件时间并存储键值file_path
);
}
closedir($hd);
return $list;
}
$list=getlist($path);
//接受方法 判断是怎么操作
//echo $action;
switch ($action){
case 'del':
unlink($file);
//$cmd="del $file";
//system($cmd);
//echo $cmd;
break;
case 'down':
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"" . $file . "\"");
header("Content-Length: " . filesize($file));
readfile($file);
break;
case 'edit':
$content=file_get_contents($file);
echo '<form name="form1" method="post" action="">';
echo "文件名:".$file."<br>";
echo "文件内容:<br>";
echo '<textarea name="code" style="resize:none;" rows="100" cols="100"">'.$content.'</textarea><br>';
echo '<input type="submit" name="submit" id="submit" value="提交">';
echo '</form>';
break;
}
//检测编辑后提交的事件 进入文件重新写入
if(isset($_POST['code'])){
$f=fopen("$path/$file",'w+');
fwrite($f,$_POST['code']);
fclose($f);
}
?>
<table width="100%" style="font-size: 10px;text-align: center;">
<tr>
<th>图标</th>
<th>名称</th>
<th>日期</th>
<th>大小</th>
<th>路径</th>
<th>操作</th>
</tr>
<?php foreach ($list['dir'] as $v): ?>
<tr>
<td><img src="./img/list.png" width="20" height="20"></td>
<td><?php echo $v['file_name']?></td>
<td><?php echo $v['file_time']?></td>
<td>-</td>
<td><?php echo $v['file_path']?></td>
<td><a href="?path=<?php echo $v['file_path']?>">打开</a></td>
</tr>
<?php endforeach;?>
<?php foreach ($list['file'] as $v): ?>
<tr>
<td><img src="./img/file.png" width="20" height="20"></td>
<td><?php echo $v['file_name']?></td>
<td><?php echo $v['file_time']?></td>
<td><?php echo $v['file_size']?></td>
<td><?php echo $v['file_path']?></td>
<td>
<a href="?a=edit&path=<?php echo $v['file_path']?>">编辑</a>
<a href="?a=down&path=<?php echo $v['file_path']?>">下载</a>
<a href="?a=del&path=<?php echo $v['file_path']?>">删除</a>
</td>
</tr>
<?php endforeach;?>
</table>