大家知道$_SERVER["HTTP_REFERER"]可以获取当前链接的上一个连接的来源地址,即链接到当前页面的前一页面的 URL 地址,可以做到防盗链作用,只有点击超链接(即<A href=...> post表单提交) 打开的页面才有HTTP_REFERER环境变量, 其它如 window.open()、 window.location=...、window.showModelessDialog()等打开的窗口都没有HTTP_REFERER 环境变量。
写个函数吧 简单的可以、起到防盗链作用
<?
function checkurl(){
//如果直接从浏览器连接到页面,就连接到登陆窗口
//echo "referer:". $_SERVER["HTTP_REFERER"]
if(!isset( $_SERVER["HTTP_REFERER"]) {
header("location: login");
exit;
}
$urlar = parse_url( $_SERVER["HTTP_REFERER"]);
//如果页面的域名不是服务器域名,就连接到登陆窗口
if($_SERVER['HTTP_HOST'] != $urlar["host"] && $urlar["host"] != "202.102.110.204" && $urlar["host"] != " http://blog.163.com/fantasy_lxh/") {
header("location: login.php");
exit;
}
}
checkurl()
?>
写个函数吧 简单的可以、起到防盗链作用
<?
function checkurl(){
//如果直接从浏览器连接到页面,就连接到登陆窗口
//echo "referer:". $_SERVER["HTTP_REFERER"]
if(!isset( $_SERVER["HTTP_REFERER"]) {
header("location: login");
exit;
}
$urlar = parse_url( $_SERVER["HTTP_REFERER"]);
//如果页面的域名不是服务器域名,就连接到登陆窗口
if($_SERVER['HTTP_HOST'] != $urlar["host"] && $urlar["host"] != "202.102.110.204" && $urlar["host"] != " http://blog.163.com/fantasy_lxh/") {
header("location: login.php");
exit;
}
}
checkurl()
?>
倒找到一些防跨站的。
来源:
http://www.myhack58.com/Article/html/3/7/2012/35108.htm
在以前的防止跨站攻击的时候,使用了验证提交的页面是否是同一个站点,这样可以防止普通的攻击,ereg("blog.qita.in",$_SERVER['HTTP_REFERER'])
不过也不是很安全的,因为攻击者可以伪造HTTP Referer,如 header("Referer: blog.qita.in"); 或者在恶意脚本中伪造HTTP头
由于HTTP Referer是由客户端浏览器发送的,而不是由服务器控制的,因此你不应当将该变量作为一个信任源。
当然登录的时候可以使用验证码来解决,不过其他很多表单提交还是不适宜。
下面给出一个防止伪造表单提交的方案,还解决了同一个站点不同页面的非法调用!
//--------------- 代码 -------------//
session_start();
#随机取6位的散列值
function gen_token() {
$hash = md5(uniqid(rand(), true));
$n = rand(1, 26);
$token = substr($hash, $n, 6);
return $token;
}
function ck_form(){
if (_POST('qm_token')=='' || _SESSION('token')=='' || _POST('qm_token') != _SESSION('token')){
exit('请勿非法提交');
}
}
function token_input(){
$token = gen_token();
$_SESSION['token']= $token;
echo "<input type='hidden' name='qm_token' value='$token'/>";
}
//使用方法,注意先后顺序
if(_POST('add')!=''){
#提交表单的时候验证提交页面的合法性
ck_form();
正常CODE...
}
<form name="form1" action="" method="post">
<?php token_input();?>
其他HTML...
</form>
//------------ 代码结束 -------------//
原理:当不同的页面跨站或同站非法跨页提交表单的时候
跨站时获取的隐藏域和SESSION值都为空,可以判断是非法提交,因为合法页面的SESSION和隐藏域我赋了同样的散列值。
同站时SESSION值和POST得到的隐藏域的值不会相同,所以也可以判断是非法提交。
NOTE:
function _POST($str){
$val = !empty($_POST[$str]) ? $_POST[$str] : null;
return $val;
}
function _GET($str){
$val = !empty($_GET[$str]) ? $_GET[$str] : null;
return $val;
}
function _SESSION($str){
$val = !empty($_SESSION[$str]) ? $_SESSION[$str] : null;
return $val;
}
其实这行代码就是随机生成一个值放在隐藏域里,每次生成的都不一样。但这样的唯一不足登录页不能作缓存,挺好的思想,值得学习