V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zjsxwc
V2EX  ›  程序员

仅仅只是把单引号与反斜杠转义不用 prepare statement 能否避免 sql 注入?

  •  
  •   zjsxwc ·
    zjsxwc · 2017-05-10 13:26:32 +08:00 · 3676 次点击
    这是一个创建于 2754 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如我输入登录名 login_name 为 \' 就拼出这种 sql:

    SELECT * FROM account WHERE (1) AND (`account`.login_name = '\\\'')

    这样能否避免 sql 注入?

    23 条回复    2017-05-11 19:58:51 +08:00
    jybox
        1
    jybox  
       2017-05-10 13:48:17 +08:00   ❤️ 1
    可以看下 mysql client 的 escape 是怎么实现的,除了单引号还有其他的符号
    https://github.com/mysqljs/sqlstring/blob/master/lib/SqlString.js
    zjsxwc
        2
    zjsxwc  
    OP
       2017-05-10 14:03:44 +08:00
    @jybox 谢谢回复。

    对于你说的这些其他符号都是以反斜杠开头的,我已经转义了反斜杠,也就包括了对这些特殊符号转义。 因为参数最后会被 2 个单引号包裹,所以可以不对双引号转义
    grayon
        3
    grayon  
       2017-05-10 14:12:43 +08:00   ❤️ 1
    单引号、双引号、反斜杠、NULL 都要转义
    还要对数字进行处理,比如整形进行 intval
    还要防止 Unicode 编码的双字节绕过
    as463419014
        4
    as463419014  
       2017-05-10 14:17:03 +08:00
    用 ESAPI
    fy
        5
    fy  
       2017-05-10 14:49:37 +08:00
    什么年代了 为什么还要手动拼 sql
    zjsxwc
        6
    zjsxwc  
    OP
       2017-05-10 14:57:34 +08:00
    @fy
    就是在维护一个老系统,才来问的
    fy
        7
    fy  
       2017-05-10 14:58:23 +08:00
    @zjsxwc 233 那就没办法了,祝好运
    wdd2007
        8
    wdd2007  
       2017-05-10 14:59:59 +08:00
    不能。
    tomczhen
        9
    tomczhen  
       2017-05-10 15:00:46 +08:00 via iPhone
    老系统可以在 web server 做过滤请求参数来做防注入,理论上无需修改代码。

    如果判断逻辑复杂,可以考虑使用 openresty 或者直接上现成的开源项目。
    lianz
        10
    lianz  
       2017-05-10 15:01:39 +08:00
    只转移 \ 是不够的,三楼 @grayon 说得非常对。
    五楼 @fy 说得非常好:都什么年代了,为什么还要手动拼 sql ?
    在实践中,因为程序猿水平参差不齐,代码质量混杂,仅靠程序猿人力进行转义是完全不靠谱的,防得了一时,防不了一世,总会有一天会出漏洞,所以实际项目中除非绝对必要,否则绝对不要手动拼字符串。
    woshixiaohao1982
        11
    woshixiaohao1982  
       2017-05-10 15:06:59 +08:00
    @lianz 都什么年代了,还让程序员来解决这种 SQL 注入问题,我直接就是 ORM 往那里一套,
    谁能注入这些开源框架,我服
    102400
        12
    102400  
       2017-05-10 15:18:29 +08:00
    @woshixiaohao1982 ORM 也会有 SQL 注入漏洞
    woshixiaohao1982
        13
    woshixiaohao1982  
       2017-05-10 18:57:39 +08:00
    @102400 有些连接池自带防注入的功能,总而言之,集成一个开源过滤层进去就好了,这种代码 还自己来写,不是自找麻烦
    helica
        14
    helica  
       2017-05-10 19:00:44 +08:00 via iPhone
    可以了解一下二次注入
    ic3z
        15
    ic3z  
       2017-05-10 20:03:57 +08:00 via Android
    SELECT * FROM goods where id = 1
    bombless
        16
    bombless  
       2017-05-11 00:58:05 +08:00 via Android
    我印象中最大的坑是不同编码环境下哪些字符被等同于引号也是不同的。还有就是有时候可以通过不匹配的代理对或者类似的技术把右引号穿过去,那么在它后面的一对引号的左引号就被用来结束字面量,从这里开始就可以干坏事了
    realpg
        17
    realpg  
       2017-05-11 12:49:51 +08:00
    拼接 SQL 在很多复杂逻辑场景下是必须的
    statement 并不包治百病
    hoythan
        18
    hoythan  
       2017-05-11 13:51:36 +08:00
    麻烦问下楼上的,你们项目都用什么年代的方式才能都不用拼 sql
    Mitt
        19
    Mitt  
       2017-05-11 14:54:48 +08:00
    @hoythan ORM
    t333st
        20
    t333st  
       2017-05-11 16:52:24 +08:00
    这种做法是不行的
    1 如果你的 sql 语句没有单引号(select * from user where id =$id),那攻击者无需构造带单引号的语句攻击
    2 还有种注入叫宽字符注入,网站使用 gbk 编码情况下,攻击者提交%df' ,即可绕过(%df 和\ 组成%df%5c 形成汉字 縗)
    zjsxwc
        21
    zjsxwc  
    OP
       2017-05-11 17:11:22 +08:00
    @t333st
    谢谢回复。

    现在我在维护的这个系统,是 utf8 编码的,sql 参数也是单引号包裹的,我想找出个例子能 sql 注入这个系统来说服领导去重构它。
    t333st
        22
    t333st  
       2017-05-11 17:36:12 +08:00
    @zjsxwc 有用到 iconv() 这个方法吗。。。
    zjsxwc
        23
    zjsxwc  
    OP
       2017-05-11 19:58:51 +08:00 via Android
    @t333st 没有用 iconv
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1225 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 18:15 · PVG 02:15 · LAX 10:15 · JFK 13:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.