Tornado的防注入应该怎么做? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
nichan
V2EX    Tornado

Tornado的防注入应该怎么做?

  •  
  •   nichan 2013-04-14 19:41:22 +08:00 8241 次点击
    这是一个创建于 4622 天前的主题,其中的信息可能已经有所发展或是发生改变。
    在网上查到的教程中说应该使用:
    cursor.execute("SELECT * FROM user_info WHERE email = %s", youremail)

    而不是:
    cursor.execute("SELECT * FROM user_info WHERE email = %s" % youremail)

    但是第一种形式似乎不能够处理自定义表名,如:
    cursor.execute("SELECT * FROM %s WHERE email = %s", (user_info, youremail)
    会自动把表名加上双引号变成
    SELECT * FROM "user_info" WHERE email = "youremail"

    我想,能不能在get_argument处下手,通过过滤某些字符以达到防注入的效果?或者有没有其他更好的方法?
    9 条回复    1970-01-01 08:00:00 +08:00
    lilian57
        1
    lilian57  
       2013-04-15 11:46:10 +08:00   1
    简单说一下
    1.首先要理解为什么能防止sql注入:参数化查询,sql能重用查询计划(有助于提高性能)。而表名是不能参数化查询的
    2.如果你用的sql模块的paramstyle不是'format', 'pyformat',也就是你的sql 形式是"SELECT * FROM user_info WHERE email = ?" 之类的你会更好的理解代码为什么是这样的。
    3.自定义表名的时候应该先拼接表名(因为表名是安全的),再参数化查询(用户输入条件不安全)。不建议转义或过滤特殊字符。 cursor.execute("SELECT * FROM %s WHERE email = ?" % user_info, youremail) 或者 cursor.execute("SELECT * FROM %s WHERE email = %%s" % user_info, youremail)
    alexrezit
        2
    alexrezit  
       2013-04-15 12:25:15 +08:00   1
    之前也遇到过这个问题, 我来说一下吧: 表名都要自己过滤的, 包括其他语言例如 C 的也一样, 只能 bind 参数.
    如果一定要用参数的话请去掉除去 a-Z, 0-9 之外的字符.

    ```
    def scrub(table_name):
    return ''.join( chr for chr in table_name if chr.isalnum() )

    scrub('); drop tables --') # returns 'droptables'
    ```

    ref: http://stackoverflow.com/questions/3247183/variable-table-name-in-sqlite
    Livid
        3
    Livid  
    MOD
    PRO
       2013-04-15 12:32:29 +08:00   1
    如果用了一个 ORM 框架的话,大部分这类细节 ORM 框架会搞定的。
    1ang
        4
    1ang  
       2013-04-16 16:24:59 +08:00   1
    1. 如果你的SQL表名都是从HTML FORM里提交过来的话,说明这个设计已经不是很好了,想一下如何做的更好把
    2. 如果一定要这样做的话,先自己过滤表名,只允许0-9a-zA-Z$_这些字符,然后 sql = "SELECT * FROM %s WHERE email = %%s" % tablename,最后再cursor.execute(sql, yourmail)

    这个use case 大部分ORM也解决不了,自己做就好了。
    nichan
        5
    nichan  
    OP
       201304-16 17:52:35 +08:00
    感谢各位回复~

    事实上我的表名并不是直接从html里提交过来的,我会对每一个用户提交过来的表名做一次类似于base64的加密,以保证最终执行的sql语句符合语法,这样从表名处进行注入也似乎是不太可能了。但是转换过的表名依然是一个变量,依然要使用第二种(不安全的)语句带入到sql语句中。
    非常感谢@lilian57 @alexrezit @1ang 提供的思路!已实验成功~
    binux
        6
    binux  
       2013-04-16 17:54:55 +08:00   2
    @nichan base64不是加密算法!即使用了base64也能被注入
    nichan
        7
    nichan  
    OP
       2013-04-16 18:08:21 +08:00
    @binux 嗯~base64不是,只是类似于base64。
    不过即使是base64应该也很难被注入吧?加密后的字符只有a-z和0-9
    1ang
        8
    1ang  
       2013-04-17 04:37:38 +08:00
    所以你的这个应用总共会有多少个表?
    nichan
        9
    nichan  
    OP
       2013-04-17 09:20:07 +08:00
    @1ang 大概有十几个。
    面向内部用户使用,不考虑seo,所以在尝试一些新的东西,Tornado基本上自己不主动生成页面,主体页面的布局、内容由储存在用户本地的js通过ajax请求生成。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     919 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 23ms UTC 22:06 PVG 06:06 LAX 14:06 JFK 17:06
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86