本文目录一览:
PHP网站要防哪几种常见方式攻击?
常见攻击方式:
- 命令注入
- eval注入
- 客户端脚本攻击
- 跨网站脚本攻击
- SQL注入攻击
- 跨网站请求伪造攻击
- Session 会话劫持
- Session 固定攻击
- HTTP响应拆分攻击
- 文件上传漏洞
- 目录穿越漏洞
- 远程文件包含攻击
- 动态函数注入攻击
- URL攻击
- 表单提交欺骗攻击
- HTTP请求欺骗攻击
PHP中SESSION的问题
Session 和 Cookie 有什么关系
Cookie 也是由于 HTTP 无状态的特点而产生的技术,用于保存访问者的身份标识和一些数据。每次客户端发起 HTTP 请求时,会将 Cookie 数据加到 HTTP header 中,提交给服务端。这样服务端就可以根据 Cookie 的内容知道访问者的信息了。
Session 和 Cookie 做着相似的事情,只是 Session 是将数据保存在服务端,通过客户端提交来的 session_id 来获取对应的数据;而 Cookie 是将数据保存在客户端,每次发起请求时将数据提交给服务端。
上面提到,session_id 可以通过 URL 或 cookie 来传递,由于 URL 的方式比 cookie 的方式更加不安全且使用不方便,所以一般是采用 cookie 来传递 session_id。
服务端生成 session_id,通过 HTTP 报文发送给客户端(比如浏览器),客户端收到后按指示创建保存着 session_id 的 cookie。cookie 是以 key/value 形式保存的,例如:PHPSESSID=e4tqo2ajfbqqia9prm8t83b1f2
。在 PHP 中,保存 session_id 的 cookie 名称默认叫作 PHPSESSID
,这个名称可以通过 php.ini
中 session.name
来修改,也可以通过函数 session_name()
来修改。
为什么不推荐使用 PHP 自带的 files 型 Session 处理器
在 PHP 中,默认的 Session 处理器是 files,处理器可以用户自己实现(参见:自定义会话管理器)。常见的成熟的 Session 处理器还有:Redis、Memcached、MongoDB 等。 PHP 官方手册中提到:
无论是通过调用函数
session_start()
手动开启会话,还是使用配置项session.auto_start
自动开启会话,对于基于文件的会话数据保存(PHP 的默认行为)而言,在会话开始的时候都会给会话数据文件加锁,直到 PHP 脚本执行完毕或者显式调用session_write_close()
来保存会话数据。在此期间,其他脚本不可以访问同一个会话数据文件。 为了验证这一点,我们创建两个文件: session1.php
<?php
session_start();
sleep(5);
var_dump($_SESSION);
?>
session2.php
<?php
session_start();
var_dump($_SESSION);
?>
实验发现,当在同一个浏览器中访问 session1.php
,然后在新标签页访问 session2.php
,session2.php
会等待 session1.php
执行完毕。而如果在不同浏览器中访问,则不会阻塞。
造成这种现象的原因是:默认使用 Cookie 来传递 session_id,且 Cookie 的作用域相同。当访问 session1.php
时,PHP 根据 session_id 在服务器保存 Session 文件的路径(默认为 /tmp
)中找到对应的 Session 文件,并对其加锁。如果不显式调用 session_write_close()
,那么直到当前 PHP 脚本执行完毕才会释放文件锁。
解决办法是:在使用完 Session 后,立刻调用 session_write_close()
。
例如:
<?php
session_start();
$_SESSION['name'] = 'Jing';
var_dump($_SESSION);
session_write_close();
sleep(5);
session_start();
$_SESSION['name'] = 'Mr.Jing';
var_dump($_SESSION);
?>
官方建议:对于大量使用 Ajax 或者并发请求的网站而言,这可能是一个严重的问题。解决这个问题最简单的做法是如果修改了会话中的变量,应该尽快调用 session_write_close()
来保存会话数据并释放文件锁。还有一种选择就是使用支持并发操作的会话保存管理器来替代文件会话保存管理器。
我推荐的方式是使用 Redis 作为 Session 的处理器。
为什么不能用 memcached 存储 Session
Memcached 不支持持久化,Session 数据可能会因为服务重启或内存不足而丢失,因此不适合用于存储 Session。
如何使用 Redis 作为 PHP Session handler
可以通过 PHP 的 session_set_save_handler()
函数实现自定义的 Session 处理器,将 Session 数据存储在 Redis 中。
Session 数据是什么时候被删除的
PHP 中通过以下配置项控制 Session 数据的过期和垃圾回收:
session.gc_maxlifetime
:指定过了多少秒之后数据就会被视为“垃圾”并被清除。session.gc_probability
与session.gc_divisor
:控制 GC 进程启动的概率,默认为 1/100,即 1% 的概率启动 GC。 Session 文件的删除机制并不是精准的,带有一定的或然性。某些会话存储处理模块不使用此设置项。 对于基于文件的 Session 处理器,GC 进程启动后会遍历 Session 文件列表,根据文件的修改时间判断是否过期并删除。这种方式效率较低,因此不推荐使用 PHP 自带的 files 型 Session 处理器。 Redis 或 Memcached 天生支持 key/value 过期机制,适合用于作为会话处理器。
为什么重启浏览器后 Session 数据就取不到了
session.cookie_lifetime
指定了发送到浏览器的 cookie 的生命周期。值为 0 表示“直到关闭浏览器”。默认为 0。
关闭浏览器时,保存 session_id 的 Cookie 会被清除,因此无法再访问对应的 Session 数据。同理,浏览器 Cookie 被手动清除也会造成这个结果。
为什么浏览器开着,我很久没有操作就被登出了
这是为了保护用户账户安全的“防呆”机制。长时间没有操作,服务端的 Session 文件过期被删除,导致用户被登出。
一个有意思的事情
在实验中发现,即使 Session 文件超过了过期时间,如果没有其他请求触发 GC,它也不会被删除。只有当其他请求触发 GC 时,该文件才会被清理。
PHP的网站主要攻击方式有哪些
- 命令注入 (Command Injection)
- eval注入 (Eval Injection)
- 客户端脚本攻击 (Script Insertion)
- 跨网站脚本攻击 (Cross Site Scripting, XSS)
- SQL注入攻击 (SQL injection)
- 跨网站请求伪造攻击 (Cross Site Request Forgeries, CSRF)
- Session 会话劫持 (Session Hijacking)
- Session 固定攻击 (Session Fixation)
- HTTP响应拆分攻击 (HTTP Response Splitting)
- 文件上传漏洞 (File Upload Attack)
- 目录穿越漏洞 (Directory Traversal)
- 远程文件包含攻击 (Remote Inclusion)
- 动态函数注入攻击 (Dynamic Variable Evaluation)
- URL攻击 (URL attack)
- 表单提交欺骗攻击 (Spoofed Form Submissions)
- HTTP请求欺骗攻击 (Spoofed HTTP Requests)