浅析SQL注入

简介:

一、SQL注入原因

SQL漏洞出现的原因大家都应该知道了,还是哪一句熟悉的话:用户输入的数据被SQL解释器执行。

SQL注入的原因和分类都是很简单的,难的是对可能出现SQL注入的地方进行细致拼接测试。


二、SQL注入漏洞分类

2.1 数字型注入

数字型注入是最初级的注入,常出现在ASP、PHP等弱类型语言之中,因为弱类型语言会自动推导变量类型。

示例:

1
http: //localhost/sql .php? id =8 AND 1=1

上述的示例多是进行自动化的“盲注”。在后台执行的SQL为:SELECT * FROM test where id  8 AND 1=1。

PS:盲注是在服务器没错误回显时完成的注入攻击。服务器没有错误回显,对于攻击者而言缺少了非常重要的“调式信息”,所以攻击者需要找一个一个方法来验证注入的SQL是否已经执行。盲注是根据多给条件进行判断,如果页面没有出错则表示存在注入点。


2.2 字符型注入

字符型与数字型的最大区别在于,前者一般要是有单引号来闭合,后者不需要。

示例:

1
http: //localhost/sql .php?name=admin and 1=1

这样是无效,因为后端的SQL为:

     

1
SELECT  FROM  test  where  name  'admin and 1=1'

如果改为:

1
http: //localhost/sql .php?name= 'admin'  and 1=1

此时后端SQL:SELECT * FROM test where name = 'admin' and 1=1

该类型的注入是公司扫雷重点照顾对象,大家可以看看扫雷的日志多是各种拼接的SQL。


总结一下,字符型注入还可以细分出一下不同的类型,如POST注入、Cookie注入、搜索注入、BASE64注入。。。本质上还是字符型注入,数字型注入也是可以说是特殊的字符型注入。

因为公司已经存在强大的扫雷工具了所以在此就不再介绍别的工具了。


三、防止SQL注入

防SQL注入总结就一句话:有输入的地方就有存在SQL的风险。

3.1 统一输入处理,严格类型判断

金融知心的大多数的项目使用的PHP,弱类型的语言没有强制要求处理数据类型。但防御数字型注入还是很简单的,一个函数 intval ($param);就可以。

1
$param   intval  ( $param );

3.2 特殊字符转义

对于字符类型,他们都是string,所以很难判断输入的是否存在恶意攻击。现在通用的防御方法就是对特殊符号进行转义。

1
$paramStr  = mysql_real_escape_string( $paramStr );

最好是框架或者类库在底层提供了而不需要开发人员在业务代码中混合在一起了。

3.3 使用预编译

PHP的PDO也提供了预编译的功能了,只是在我们金融项目中很少使用,因为使用起来不算方便。

3.4 使用框架

在PHP中很多框架都是提供了好用而且安全的数据库操作类库了,知心普遍使用的Topaz使用的mysqli而且SQL语句都是拼接的,所以最近扫雷就会出现类似SQL注入的出现。

3.5 使用存储过程

不建议使用了,虽然使用存储过程可以提高执行效率,因为使用存储过程需要精通SQL,而且不方便经常变更和会出现移植问题。


四、举例说明

最近扫雷经常出现提示有SQL注入的情况,也有的是误报的。也执行到了数据库,仅是此次组装的SQL是错误的(谁知道如果是人工构造时候会不会出现真的注入了呢)。为了安全的考虑,是不允许不符合格式的SQL进入数据库执行的,不论这个语句是否可以真的注入。有可能是SQL漏洞被发觉的是因为我们异常错误的处理不当,不应该再给前端返回后端数据库异常的信息。

出现多次扫雷问题,主要是对参数校验不足和库类使用的方式造成。

如我们看一段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  public  static  function  getLoanArticle ( $input array  $arrIds $bsPriceList $cate $nestId  = 22){
         $rtn  array ();
         
         $db  = Env::getDB( 'fnbiz' );
         
         $ids  array ();
         foreach  ( $arrIds  as  $id )
         {
             $id  $db ->real_escape( $id );
             if  (! empty ( $id )) {
                 $ids [] =  $id ;
             }
         }
 
         if  ( empty ( $ids ))
         {
             Env::getLogger()->warning( 'DB' 'empty parameter arrIds' );
             return  $rtn ;
         }
 
         //TODO delete note 
         $tbl  'knowledge_loan_article' ;
         $strId  = implode( ',' $ids );
          //TODO: select count
         $sql  "SELECT articleId, keywords, source, title, brief, lastUpdateTime, articleLink, content, ext FROM $tbl WHERE articleId IN ($strId) AND isDelete = 0 AND nestId = $nestId" ;
         Env::getLogger()->trace(
                 "get articel from db [sql:$sql] [articleId count:"  count ( $ids ) .
                          "]" );
         
         //$rs = $db->fetchAll($sql);
         ...  ...


       

    为什么写成这样SQL拼接的方式,是因为Topaz要求这么写的,但在这个SQL语句之前没有对$id进行校验就会有SQL注入。很庆幸,扫雷发现并进行处理了。参数的校验包含了参数类型和参数长度等多种属性的校验。注:安全与成本是成反比的,注意平衡!

    使用UI的一段代码来看看:

    

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public  static  function  getByProductIds( array  $arrIds ) {
         if  ( empty ( $arrIds )) {
             Env::getLogger()->warning( 'DB' 'empty parameter arrIds' );
             return  array () ;
         }
         $db  = Env::getDB( 'fnbiz' );
         $ids  array () ;
         foreach ( $arrIds  as  $id  ){
             $ids [] =  $db ->real_escape( $id ) ;
         }
 
         $strIds  = implode( "," , $ids ) ;
         $tb  "product" ;
         $sql  "SELECT * FROM `$tb` WHERE productId IN ( $strIds )" ;
         $res $db ->fetchAll( $sql ) ;
 
         $mapRes  array () ;
         foreach ( $res  as  $item ){
             $mapRes [ $item [ 'productId' ]] =  $item ; // json_decode($item['productInfo'], true) ;
         }
         $rtn  array () ;
         foreach ( $ids  as  $id ){
             if ( !isset( $mapRes [ $id ]) ) {
                 Env::getLogger()->warning( 'DB' , "product $id not found in db" ) ;
             } else {
                  $rtn [ $id ] =  $mapRes [ $id ] ;
            
         }
         return  $rtn  ;
     }

    可以发现参数的转义已经和业务的代码混合在一起了,每一个人的代码风格都不一样这并不可怕,可怕的是每一个人开发人员的安全意识都不一样。有的有参数的转义有的却没有!

    

    建议使用PDO库类替换Topaz并统一语法。



本文转自 梦朝思夕 51CTO博客,原文链接:http://blog.51cto.com/qiangmzsx/1662639

相关文章
|
2月前
|
SQL 安全 数据库
惊!Python Web安全黑洞大曝光:SQL注入、XSS、CSRF,你中招了吗?
在数字化时代,Web应用的安全性至关重要。许多Python开发者在追求功能时,常忽视SQL注入、XSS和CSRF等安全威胁。本文将深入剖析这些风险并提供最佳实践:使用参数化查询预防SQL注入;通过HTML转义阻止XSS攻击;在表单中加入CSRF令牌增强安全性。遵循这些方法,可有效提升Web应用的安全防护水平,保护用户数据与隐私。安全需持续关注与改进,每个细节都至关重要。
106 5
|
2月前
|
SQL 安全 数据库
深度揭秘:Python Web安全攻防战,SQL注入、XSS、CSRF一网打尽!
在Web开发领域,Python虽强大灵活,却也面临着SQL注入、XSS与CSRF等安全威胁。本文将剖析这些常见攻击手段,并提供示例代码,展示如何利用参数化查询、HTML转义及CSRF令牌等技术构建坚固防线,确保Python Web应用的安全性。安全之路永无止境,唯有不断改进方能应对挑战。
56 5
|
2月前
|
SQL 安全 数据安全/隐私保护
Python Web安全大挑战:面对SQL注入、XSS、CSRF,你准备好了吗?
在构建Python Web应用时,安全性至关重要。本文通过三个真实案例,探讨了如何防范SQL注入、XSS和CSRF攻击。首先,通过参数化查询替代字符串拼接,防止SQL注入;其次,利用HTML转义机制,避免XSS攻击;最后,采用CSRF令牌验证,保护用户免受CSRF攻击。这些策略能显著增强应用的安全性,帮助开发者应对复杂的网络威胁。安全是一个持续的过程,需不断学习新知识以抵御不断变化的威胁。
90 1
|
2月前
|
SQL 安全 数据库
Python Web开发者必看!SQL注入、XSS、CSRF全面解析,守护你的网站安全!
在Python Web开发中,构建安全应用至关重要。本文通过问答形式,详细解析了三种常见Web安全威胁——SQL注入、XSS和CSRF,并提供了实用的防御策略及示例代码。针对SQL注入,建议使用参数化查询;对于XSS,需对输出进行HTML编码;而防范CSRF,则应利用CSRF令牌。通过这些措施,帮助开发者有效提升应用安全性,确保网站稳定运行。
43 1
|
2月前
|
SQL 安全 数据库
深度揭秘:Python Web安全攻防战,SQL注入、XSS、CSRF一网打尽!
在Web开发领域,Python虽强大灵活,但安全挑战不容小觑。本文剖析Python Web应用中的三大安全威胁:SQL注入、XSS及CSRF,并提供防御策略。通过示例代码展示如何利用参数化查询、HTML转义与CSRF令牌构建安全防线,助您打造更安全的应用。安全是一场持久战,需不断改进优化。
38 3
|
2月前
|
SQL 安全 数据库
从入门到精通:Python Web安全守护指南,SQL注入、XSS、CSRF全防御!
【9月更文挑战第13天】在开发Python Web应用时,安全性至关重要。本文通过问答形式,详细介绍如何防范SQL注入、XSS及CSRF等常见威胁。通过使用参数化查询、HTML转义和CSRF令牌等技术,确保应用安全。附带示例代码,帮助读者从入门到精通Python Web安全。
75 6
|
2月前
|
SQL 安全 JavaScript
告别Web安全小白!Python实战指南:抵御SQL注入、XSS、CSRF的秘密武器!
【9月更文挑战第12天】在Web开发中,安全漏洞如同暗礁,尤其对初学者而言,SQL注入、跨站脚本(XSS)和跨站请求伪造(CSRF)是常见挑战。本文通过实战案例,展示如何利用Python应对这些威胁。首先,通过参数化查询防止SQL注入;其次,借助Jinja2模板引擎自动转义机制抵御XSS攻击;最后,使用Flask-WTF库生成和验证CSRF令牌,确保转账功能安全。掌握这些技巧,助你构建更安全的Web应用。
41 5
|
4月前
|
SQL 安全 数据库
Python Web开发者必学:SQL注入、XSS、CSRF攻击与防御实战演练!
【7月更文挑战第26天】在 Python Web 开发中, 安全性至关重要。本文聚焦 SQL 注入、XSS 和 CSRF 这三大安全威胁,提供实战防御策略。SQL 注入可通过参数化查询和 ORM 框架来防范;XSS 则需 HTML 转义用户输入与实施 CSP;CSRF 防御依赖 CSRF 令牌和双重提交 Cookie。掌握这些技巧,能有效加固 Web 应用的安全防线。安全是持续的过程,需贯穿开发始终。
80 1
Python Web开发者必学:SQL注入、XSS、CSRF攻击与防御实战演练!
|
4月前
|
SQL 运维 安全
WAF如何防御SQL注入?
【7月更文挑战第25天】WAF如何防御SQL注入?
274 9