首页 > 编程技术 > php

php 防跨站攻击测试例子(供学习使用)

发布时间:2016-11-25 15:22

跨站攻击就是利用程序上的一些细节或bug问题进行的了,那么我们要如何耿防止跨站攻击呢?下面我们费话不说多了来给大家整理一个防止跨站攻击例子,希望对各位有帮助。

代码是最好的语言。。

 代码如下 复制代码

<?php
#demo for prevent csrf

/**
* enc
*/
function encrypt($token_time) {
return md5(‘!@##$@$$#%43′ . $token_time);
}

$token_time = time();
$token = encrypt($token_time);
$expire_time = 10;

if ($_POST) {
$_token_time = $_POST['token_time'];
$_token = $_POST['token'];

if ((time() – $_token_time) > $expire_time) {
echo “expired token”;
echo “<br />”;
}

echo $_token;
echo “<br />”;
$_token_real = encrypt($_token_time);

echo $_token_real;
//compare $_token and $_token_real
}
?>

<!DOCTYPE html>
<html>
<head>
<meta http-equiv=”content-type” content=”text/html; charset=utf-8″ />
<title>test for csrf</title>
<meta http-equiv=”" content=”" />
</head>
<body>
<form method=”post” action=”">
<input type=”text” name=”text” id=”" value=”hello” />
<input type=”hidden” name=”token” id=”" value=”<?php echo $token ?>” />
<input type=”hidden” name=”token_time” id=”" value=”<?php echo $token_time ?>” />

<input type=”submit” name=”submit” id=”" value=”submit” />

</form>
</body>
</html>

 
通过在你的表单中包括验证码,你事实上已经消除了跨站请求伪造攻击的风险。可以在任何需要执行操作的任何表单中使用这个流程

当然,将token 存储到session更好,这儿只是简单示例下

简单分析:

token防攻击也叫作(令牌)了,我们在用户访问页面时就生成了一个随机的token保存session与表单了,用户提交时如果我们获取到的token与session不一样就可以提交重新输入提交数据了

防止站长提交表单无非就是对每一次打开表单或提交数据都会需要加一个token来进行验证了,这个其实与验证码做法没什么两样了,下面来看几个防止站外远程提交表单的例子。

例子一,我们每一次打开提交页面生成一个token然后保存在session中,当表单提交时我们来判断当前的token值与session是否一致,如果是的就是正常提交否则就是无效提交了。

代码

 代码如下 复制代码

<?php    
session_start();    
    
if ($_POST['submit'] == "go"){    
    //check token    
    if ($_POST['token'] == $_SESSION['token']){    
        //strip_tags    
        $name = strip_tags($_POST['name']);    
        $name = substr($name,0,40);    
        //clean out any potential hexadecimal characters    
        $name = cleanHex($name);    
        //continue processing....    
    }else{    
        //stop all processing! remote form posting attempt!    
    }    
}    
    
$token = md5(uniqid(rand(), true));    
$_SESSION['token']= $token;    
    
 function cleanHex($input){    
    $clean = preg_replace("![\][xX]([A-Fa-f0-9]{1,3})!", "",$input);    
    return $clean;    
}    
?>    
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">    
<p><label for="name">Name</label>    
<input type="text" name="name" id="name" size="20" maxlength="40"/></p>    
<input type="hidden" name="token" value="<?php echo $token;?>"/>    
<p><input type="submit" name="submit" value="go"/></p>    
</form>

还有一种比较明显的做法就是利用验证码了,这种验证码的方式与其它的方式是一样的哦,下面看个简单的例子

增加验证码

表单提交时候增加验证码,可以有效防止灌水机提交数据。但是随着图形图像识别程序变的更加强大,验证码识别也不断的在提高他的难度,有些验证码甚至加入了声音的识别,一些小站点可以采用这样的方式。

 代码如下 复制代码

if($_POST['vcode'] != get_vcode())
{
    exit('验证码校验失败,无法入库');
}

具体的例子就不介绍了网上很多验证的相关例子。

防止sql注入这些细节问题一般是出现在大意程序员或者是新手程序员了,他们未对用户提交过来的数据进行一些非常过滤从而导致给大家测试一下就攻破了你的数据库了,下面我来简单的一个用户登录未进行安全配置可能出现的sql注入方法,下面一起来看看吧。

比如以下一段登录的代码:

 代码如下 复制代码

if($l = @mysql_connect('localhost', 'root', '123')) or die('数据库连接失败');

mysql_select_db('test');

mysql_set_charset('utf8');

$sql = 'select * from test where username = "$username" and password = "$password"';

$res = mysql_query($sql);

if(mysql_num_rows($res)){

header('Location:./home.php');

}else{

die('输入有误');

}


注意上面的sql语句,存在很大的安全隐患,如果使用以下万能密码和万能用户名,那么可以轻松进入页面:

 代码如下 复制代码

1. $sql = 'select * from test where username = "***" and password = "***" or 1 = "1"';

很明显,针对这条sql语句的万能密码是: ***" or 1 = "1

 代码如下 复制代码

2. $sql = 'select * from test where username ="***" union select * from users/* and password = "***"';

正斜线* 表示后面的不执行,mysql支持union联合查询, 所以直接查询出所有数据; 所以针对这条sql语句的万能用户名是:***" union select * from users/*

 但是,此注入只针对代码中的sql语句,如果

 代码如下 复制代码
$sql = "select * from test where username = $username and password = $password";

上面的注入至少已经不管用了,不过方法是一样的;

在使用PDO之后,sql注入完全可以被避免,而且在这个快速开发的时代,框架横行,已然不用过多考虑sql注入问题了。

下面整理了两个防止sql注册函数

 代码如下 复制代码

/* 过滤所有GET过来变量 */
foreach ($_GET as $get_key=&gt;$get_var)
{
if (is_numeric($get_var)) {
$get[strtolower($get_key)] = get_int($get_var);
} else {
$get[strtolower($get_key)] = get_str($get_var);
}
}
/* 过滤所有POST过来的变量 */
foreach ($_POST as $post_key=&gt;$post_var)
{
if (is_numeric($post_var)) {
$post[strtolower($post_key)] = get_int($post_var);
} else {
$post[strtolower($post_key)] = get_str($post_var);
}
}
/* 过滤函数 */
//整型过滤函数
function get_int($number)
{
return intval($number);
}
//字符串型过滤函数
function get_str($string)
{
if (!get_magic_quotes_gpc()) {
return addslashes($string);
}
return $string;
}

还有一些博客会这样写

 代码如下 复制代码

<?php  
function post_check($post)
{
if (!get_magic_quotes_gpc()) // 判断magic_quotes_gpc是否为打开
{
$post = addslashes($post); // 进行magic_quotes_gpc没有打开的情况对提交数据的过滤
}
$post = str_replace("_", "\_", $post); // 把 '_'过滤掉
$post = str_replace("%", "\%", $post); // 把' % '过滤掉
$post = nl2br($post); // 回车转换
$post= htmlspecialchars($post); // html标记转换
return $post;
}
?>

防止sql注入不但是新学的程序员朋友需要深入了解的一个重要知识点之外,还是我们这些写了多年程序的朋友也必须注意的东西,下面给新手介绍php 防止查询的sql攻击的一些例子,希望对各位会有所帮助。

一个入门级别的例子

 代码如下 复制代码

$k = $_REQUEST['k'];

$k = addslashes($k);//转义:单引号,双引号,反斜线,NULL

$k = str_replace('%', '\%', $k);

$k = str_replace('_', '\_', $k);

$sql = "select * from users where name like '%$k%'";

if(!empty($k)){

$res = mysql_query($sql, $con) or die(mysql_error());

if($row = mysql_fetch_assoc($res)){

foreach($row as $k=>$v){

echo $row[$k].':'.$row[$v].'<br />';

}

}

}else{

echo '******';

}

补充

mysql_real_escape_string()

所以得SQL语句如果有类似这样的写法:

"select * from cdr where src =".$userId; 都要改成 $userId=mysql_real_escape_string($userId)

例子

 代码如下 复制代码

<?php
 
$clean = array();
$mysql = array();
 
$clean['last_name'] = "O'Reilly";
$mysql['last_name'] = mysql_real_escape_string($clean['last_name']);
 
$sql = "INSERT
      INTO   user (last_name)
      VALUES ('{$mysql['last_name']}')";
 
?>

所有有打印的语句如echo,print等 在打印前都要使用htmlentities() 进行过滤,这样可以防止Xss,注意中文要写出

 代码如下 复制代码

htmlentities($name,ENT_NOQUOTES,GB2312) 。

php 3des加密解密是一个在数据传输中常用的一个简单的加密方式了,下面我整理了一个php 3des加密解密类程序有需要了解的朋友可进入参考。

3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据块应用三次DES加密算法。由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解;3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。

 代码如下 复制代码


<?php
class Crypt3Des {
var $key;
function Crypt3Des($key){
$this->key = $key;
}

function encrypt($input){
$size = mcrypt_get_block_size(MCRYPT_3DES,'ecb');
$input = $this->pkcs5_pad($input, $size);
$key = str_pad($this->key,24,'0');
$td = mcrypt_module_open(MCRYPT_3DES, '', 'ecb', '');
$iv = @mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
@mcrypt_generic_init($td, $key, $iv);
$data = mcrypt_generic($td, $input);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
//$data = base64_encode($this->PaddingPKCS7($data));
$data = base64_encode($data);
return $data;
}

function decrypt($encrypted){
$encrypted = base64_decode($encrypted);
$key = str_pad($this->key,24,'0');
$td = mcrypt_module_open(MCRYPT_3DES,'','ecb','');
$iv = @mcrypt_create_iv(mcrypt_enc_get_iv_size($td),MCRYPT_RAND);
$ks = mcrypt_enc_get_key_size($td);
@mcrypt_generic_init($td, $key, $iv);
$decrypted = mdecrypt_generic($td, $encrypted);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
$y=$this->pkcs5_unpad($decrypted);
return $y;
}

function pkcs5_pad ($text, $blocksize) {
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}

function pkcs5_unpad($text){
$pad = ord($text{strlen($text)-1});
if ($pad > strlen($text)) {
   return false;
}
if (strspn($text, chr($pad), strlen($text) - $pad) != $pad){
   return false;
}
return substr($text, 0, -1 * $pad);
}

function PaddingPKCS7($data) {
$block_size = mcrypt_get_block_size(MCRYPT_3DES, MCRYPT_MODE_CBC);
$padding_char = $block_size - (strlen($data) % $block_size);
$data .= str_repeat(chr($padding_char),$padding_char);
return $data;
}
}

用法:

$crypt = new Crypt3Des('密钥');
$a = '待加密字符串';
$code = $crypt->encrypt($a);//加密
echo $crypt->decrypt($code);//解密

标签:[!--infotagslink--]

您可能感兴趣的文章: