PHP中SQL注入与跨站攻击的防范

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介:

SQL injection即SQL注入是我们每个WEB程序员都需要面对的问题,一个WEB应用假如没有起码的安全性,那么其它的一切就可以免谈了。注入问题在ASP上可谓是闹得沸沸扬扬,当然还有不少PHP程序“遇难”。至于SQL injection的详情,网上的文章很多,在此就不作赘述。追其罪恶之源,就是我们误以为用户提交的数据是可靠的。 

    无论你是否有足够的PHP安全开发经验,本文的目的就是用来帮助你构建更为安全的在线应用程序。针对不同的情况,我们可以使用下面的一种或几种方法来对SQL注入的风险进行预防。 

    1、在书写SQL语句时不要省略单引号,即使是整型字段也应该加上单引号。 
    首先,从技术上讲,引号对于数字值来说是不需要使用的。但是,假如你不使用引号把例如书籍数量这样的一个值括起来,并且假如你的用户把一个空值输入到你的表单中,那么,你将会看到一个类似下面的查询: 
SELECT * FROM books WHERE num = 
    当然,这个查询从语法上讲是无效的;但是,下面的语法却是有效的: 
SELECT * FROM books WHERE num = '' 
    第二个查询虽然也不会返回任何结果,但是至少它不会返回一个错误消息。 
    其次,单引号可以增加注入者的难度,第二句由于把变量放在一对单引号中,这样使得我们所提交的变量都变成了字符串,即使包含了正确的SQL语句,也不会正常执行,而第一句不同,由于没有把变量放进单引号中,那我们所提交的一切,只要包含空格,那空格后的变量都会作为SQL语句执行,因此,我们要养成给SQL语句中变量加引号的习惯。 

    2、检查用户提交的值的类型,对接收到的整型参数使用intval()强制转换成整形。 
    我们知道SQL注入的主要来源往往出在一个意料之外的表单提交或URL参数中,所以当你接受一个由用户提交的参数时,你应该有相当的权利来确定你想取得什么样的输入内容。在以前的学习中我们已经讨论过很多这样或那样的校验问题。因此我们只要简单的总结当时我们讨论的要点即可比较轻易的检查用户提交数据的有效性。假如你期望得到的是一个数值,那么你可以使用下面这些技术之一来确保你得到的参数的安全性。 
使用is_int()函数(或is_integer()或is_long())。 
使用gettype()函数。 
使用intval()函数。 
使用settype()函数。 
    我们通常把传送过来的整型参数使用intval()函数强制转换成整形,因为假如不这样做,接收到的查询子句很可能会附带着其它一些我们并不愿看到的语句,比如原本应该是“nid=17”可能会成为“nid=17 or 1=1”,这会使我们预计的SQL语句变成这样: 
SELECT * FROM news WHERE nid=17 or 1=1 
这对于一个新闻表中的信息可能不会造成什么大的危害,但假如是在显示某个用户的信息时呢? 
    此外,为了检查用户输入内容的长度,你可以使用strlen()函数。为了检查一个期望的时间或日期是否有效,你可以使用strtotime()函数。它似乎一定能够确保一位用户的提交参数中没有包含分号字符(除非标点符号可以被合法地包括在内)。你可以借助于strpos()函数轻易地实现这一点,如下所示: 
if( strpos( $variety, ';' ) ) exit ( "$variety is an invalid value for variety!" ); 
正如我们在前面所提到的,只要你仔细分析你的用户输入期望,那么,你应该能够很轻易地检查出其中存在的许多问题。 

    3、使用mysql_real_escape_string()函数从查询字符串中过滤掉危险字符 
    尽管有很多文章已经讨论过如何过滤掉危险字符的问题,但是在本文中还是让我们再次简单的强调并归纳一下这个问题: 
    不要使用magic_quotes_gpc指令或它的搭挡addslashes()函数,此函数在程序开发中应该是被限制使用的,在PHP的下一个版本PHP6中已经取消了对此函数的支持,并且此函数还要求使用额外的步骤stripslashes()函数。相比之下,mysql_real_escape_string()函数更为适合,受此函数影响的字符包括:\x00,\n,\r,\,',",\x1a。这二个函数的功能类似,但addslashes()函数无法转换以十六进制形式提交的字符,另外需要注重的是,mysqli_real_escape_string()函数需要先建立数据库连接,因为需要考虑到连接的当前字符集,通常防止数据库被攻击的使用方法如下: 
<?php 
function check_input($value) 

// 去除斜杠 
if (get_magic_quotes_gpc()) 
  { 
  $value = stripslashes($value); 
  } 
// 假如不是数字则加引号 
if (!is_numeric($value)) 
  { 
  $value = "'" . mysqli_real_escape_string($value) . "'"; 
  } 
return $value; 

?> 

    4、对用户输入的字符进行HTML编码以防止跨站攻击 
    对于数据库防止SQL注入的问题,通过前面三点所述综合的运用我们似乎全部解决,但假如用户提交的内容中有一些不良的HTML标签则可能会导致页面变形,严重的还可能会出现跨站攻击之类的安全问题,所以对带有HTML的内容增加过滤检查是很有必要的。 
    例如一段接收用户的输入并显示的功能代码,一但恶意用户输入:<script type='text/javascript'>location.href='http://xxx.com';</script>这样的一条数据,网页在显示该条数据时,用户的浏览器将会跳转到恶意代码指定的地址,这就是最简单的跨站攻击,我们试想一下,假如跳转的地址是一个伪造原网站来骗取用户密码或银行信息的页面,那么会是什么样的后果? 
    对于这类攻击行为,就需要我们在接收用户提交的数据时在服务器端进行过滤,我们可以编写一个过滤函数用来查询提交数据中有害字符并将之替换掉,还有一种较简便的方式就把用户所提交的内容中“<”,“>”,“&”等符号转换成正确的HTML编码,而函数htmlspecialchars()正是干这个活的。 
htmlspecialchars() 
功能:将“'"&<>”五个字符转换成HTML字符串。 
语法:string htmlspecialchars(string,quotestyle,character-set); 
参数:ENT_NOQUOTES,不对任何引号进行格式化;ENT_QUOTES,对单引号及双引号进行格式化;默认为ENT_COMPAT,仅编码双引号。 
返回值:字符串 

因此,用户提交的数据经过格式化后为: 
&lt;script type=&#039;text/javascript&#039;&gt;location.href=&#039;http://xxx.com&#039;;&lt;/script&gt; 
这样代码就失去了原有的攻击功能,可以基本预防脚本攻击的潜在危险,假如不明白这之间的区别,可以测试下面这段代码: 
<?php 
$str="<a href='http://www.php3c.com'>PHP3C技术分享社区</a>"; 
echo $str; 
echo "<br>"; 
echo htmlspecialchars($str); 
?> 
    另外,转换非凡字符为HTML字符串还可以使用函数htmlentities(),使用方法相同,它与htmlspecialchars在格式化带有英文字符的html代码的时候没有什么区别,但是htmlentities对中文字符也不放过,所以同样的调用方法得出来的结果是由于没有指定字符集而默认由 ISO-8859-1 代替,中文字符部分变为一堆乱码,因此我们在使用的时候,需要指定参数character-set为我们页面使用的字符集,例如'UTF-8'或'GB2312'。 

    SQL注入攻击是针对服务器端的数据库实行的,而跨站脚本攻击是把恶意javascript代码在用户的客户端运行,但他们的相同之处在于攻击者必须通过互联网的输入区域插入恶意的数据,因此我们只要做好用户提交数据的过滤以及合法性验证就能从源头上制止这二类攻击,但这种过滤及验证被很多程序员所忽视的,希望本文能能引起大家的重视。 


XSS(Cross Site Scripting),意为跨网站脚本攻击,为了和样式表css(Cascading Style Sheet)区别,缩写为XSS

跨站脚本主要被攻击者利用来读取网站用户的cookies或者其他个人数据,一旦攻击者得到这些数据,那么他就可以伪装成此用户来登录网站,获得此用户的权限。

跨站脚本攻击的一般步骤:

1、攻击者以某种方式发送xss的http链接给目标用户

2、目标用户登录此网站,在登陆期间打开了攻击者发送的xss链接

3、网站执行了此xss攻击脚本

4、目标用户页面跳转到攻击者的网站,攻击者取得了目标用户的信息

5、攻击者使用目标用户的信息登录网站,完成攻击


 









本文转自ljianbing51CTO博客,原文链接:http://blog.51cto.com/ljianbing/1603851 ,如需转载请自行联系原作者




相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
SQL 安全 数据库
Python Web开发者必学:SQL注入、XSS、CSRF攻击与防御实战演练!
【7月更文挑战第26天】在 Python Web 开发中, 安全性至关重要。本文聚焦 SQL 注入、XSS 和 CSRF 这三大安全威胁,提供实战防御策略。SQL 注入可通过参数化查询和 ORM 框架来防范;XSS 则需 HTML 转义用户输入与实施 CSP;CSRF 防御依赖 CSRF 令牌和双重提交 Cookie。掌握这些技巧,能有效加固 Web 应用的安全防线。安全是持续的过程,需贯穿开发始终。
59 1
Python Web开发者必学:SQL注入、XSS、CSRF攻击与防御实战演练!
|
30天前
|
SQL 安全 API
PHP代码审计示例(一)——淡然点图标系统SQL注入漏洞审计
PHP代码审计示例(一)——淡然点图标系统SQL注入漏洞审计
48 4
|
7天前
|
Java 开发者 前端开发
Struts 2:如何在大型项目中力挽狂澜,成就企业级应用开发的巅峰之作!
【8月更文挑战第31天】在本案例研究中,我们探讨了Struts 2框架在国际贸易管理系统(ITMS)中的应用,展示了其在大型项目中的优势与实践经验。Struts 2凭借其强大的表单处理、灵活的Action配置、拦截器机制及国际化支持,成为构建可扩展、高性能Web应用的理想选择。文章详细介绍了RESTful URL设计、Ajax集成、文件上传与下载等功能实现,并分享了性能优化、安全措施及遇到的问题与解决方案,为开发者提供了宝贵的参考。通过持续集成与新技术的应用,我们不断优化系统,提升开发效率与竞争力。
17 0
|
16天前
|
SQL 程序员 PHP
PHP网页下的注入原理
PHP网页下的注入原理
|
17天前
|
SQL 监控 安全
在Linux中,如何检测和防止SQL注入和跨站脚本(XSS)攻击?
在Linux中,如何检测和防止SQL注入和跨站脚本(XSS)攻击?
|
2月前
|
SQL 安全 数据库
深度揭秘:Python Web安全攻防战,SQL注入、XSS、CSRF一网打尽!
【7月更文挑战第27天】在 Web 开发中,Python 面临着如 SQL 注入、XSS 和 CSRF 等安全威胁。
55 0
|
2月前
|
SQL 安全 Go
SQL注入不可怕,XSS也不难防!Python Web安全进阶教程,让你安心做开发!
【7月更文挑战第26天】在 Web 开发中, SQL 注入与 XSS 攻击常令人担忧, 但掌握正确防御策略可化解风险. 对抗 SQL 注入的核心是避免直接拼接用户输入至 SQL 语句. 使用 Python 的参数化查询 (如 sqlite3 库) 和 ORM 框架 (如 Django, SQLAlchemy) 可有效防范. 防范 XSS 攻击需严格过滤及转义用户输入. 利用 Django 模板引擎自动转义功能, 或手动转义及设置内容安全策略 (CSP) 来增强防护. 掌握这些技巧, 让你在 Python Web 开发中更加安心. 安全是个持续学习的过程, 不断提升才能有效保护应用.
40 1
|
2月前
|
SQL 安全 前端开发
Web安全新纪元:Python如何筑起SQL注入、XSS、CSRF的铜墙铁壁?
【7月更文挑战第26天】在Web开发中,安全性至关重要。Python提供强大工具来抵御SQL注入、XSS和CSRF等威胁。使用ORM如Django和SQLAlchemy可防SQL注入; Django等框架自动转义输出防XSS; CSRF通过自动及手动验证令牌来阻止。开发者须持续学习最新安全实践以保护用户数据。迈向Web安全新纪元,Python助你一臂之力。
32 1
|
2月前
|
SQL 安全 数据库
Python Web开发者必看!SQL注入、XSS、CSRF全面解析,守护你的网站安全!
【7月更文挑战第27天】在 Python Web 开发中, 安全至关重要。
43 0
下一篇
DDNS