接口防sql注入的调研

注入的来源

http请求的路径、参数和header,比如cookie等都可能作为sql注入的来源。
在实际的开发工作中,因为现有框架中header、路径作为参数直接查询数据库的使用比较少。因此,主要处理参数sql注入。

防止sql注入PHP已知方案

未经转义的参数直接作为sql语句发给db就会发生sql注入,防止sql注入主要有以下几种方式:

  1. 强类型参数校验和转义,禁止特殊字符的参数传递。
  2. 框架和数据库统一提供的PREPARE, EXECUTE语法。
  3. 读写分离。

需要注意的是addslashes和mysql_real_escape_string都不能作为防SQL注入的方式。原因请参考:

https://blog.csdn.net/qq_36705093/article/details/79865601

详细说明

强类型参数校验和转义

1. thinkphp框架input()帮助函数提供了以下几种参数转义:`d`:转义int类型,`a`:转义数组类型,`f`: 转义浮点类型, `b`:转义bool类型,`s`: 转义字符串类型.
2. 也可以用intval, doubleval, floatval相关的函数进行参数过滤。识别无效的参数返回。

prepare, EXECUTE语法

thinkphp框架提供了prepare, execute语法来处理参数。详细的mysql prepare语法可以查看:

sql-prepared-statements

执行步骤:

  1. 发送sql语句。
  2. 设置变量。
  3. 使用变量执行语句。

举个例子:

prepare example from 'select * from sdb_user where id=?';
set @a=1;
EXECUTE example USING @a;

步骤1中的sql语句会被mysql认为是需要执行的部分。步骤2, 3的语句传入的变量不会被mysql执行。因此这种方式是最安全的mysql防注入的方式。对于thinkphp框架来说,是语句部分还是需要绑定的参数,是根据是否是变量来标识的。对于直接字符串拼接的部分,框架会认为是是sql语句而直接在步骤1发送给mysql,如果这部分有参数拼接就可能发生sql注入。

读写分离

thinkphp提供了方便的读写分离的配置。对于大部分业务来说,读的接口都是在其中占据较大的部分,因此可以使用读写分离的方式来降低sql注入时对db造成严重破坏的概率,比如改写数据,删库等。

主要包含以下database.php配置

<?php

return [
    "hostname":[
          "127.0.0.1",   //master
          "127.0.0.1"    //readonly
     ],
     "username": [
           "foo_write",   //master 
           "foo_read",    //readonly
     ],
     "password": [
            "bar_write",   //master
            "bar_read",    //readonly
     ],
     'hostport'    => '3306',
    
    'deploy'      => 1,
    'rw_separate' => true,
];

因此使用tp框架防止sql注入可以做以下改进:

  1. 强类型参数校验。
  2. 使用参数的方式传递查询条件,禁止直接拼接参数。
  3. 读写分离。

by: zhangfeng

原文地址:https://www.cnblogs.com/widgetbox/p/12989200.html