Python+MongoDB 写的一个简单(虽然业务都很简单但是有九百多个接口,选型用 Python+MongoDB 就是为了往上面堆各种奇怪格式的简单接口方便)网站,拉日志排查发现有人提交了类似这种 Payload {"password":{"$ne":"111"}},登录接口好解决,直接 str 转换一下字段,剩下九百多个接口过一遍工作量太大了还容易有漏,有人了解如果我加一个中间件遍历提交的 JSON 把 $ 开头的 key 全部过滤掉就安全了吗?
每次用新技术必被坑,上次是被 Tauri 浪费了一整天
     1 
                    
                    jeesk      2024-06-09 22:06:00 +08:00 via Android 
                    
                    技术方案评估你找 chatgpt ,也许比你自己决定好 
                 | 
            
     2 
                    
                    illl      2024-06-09 22:28:40 +08:00 via iPhone 
                    
                    $ne 应该是 MongoDB 这种非关系型数据库注入的手段,建议还是多搜索了解一下相关的手段和正确防护方式。光检测了$,貌似可以使用 Unicode 编码绕过。先知上有相关的文章,可以看看。 
                 | 
            
     3 
                    
                    HFX3389      2024-06-09 22:30:02 +08:00    先上 WAF ,什么南墙、雷池之类的,先让 WAF 过滤一遍再说 
                 | 
            
     5 
                    
                    sagaxu      2024-06-09 22:40:16 +08:00 
                    
                    用户输入不是 str? 
                 | 
            
     6 
                    
                    fzls      2024-06-09 22:59:50 +08:00 
                    
                    客户端传入的参数你在服务器不校验,直接写入数据库的嘛? 
                 | 
            
     7 
                    
                    cnevil      2024-06-09 23:06:24 +08:00 
                    
                    只有个$ne 不是注入漏洞吧。。我觉得你应该是存在别的漏洞 
                比如越权啥的  | 
            
     8 
                    
                    lambdaq      2024-06-09 23:16:24 +08:00 
                    
                    不是哥们。。。。mongo 也能被注入??? 
                 | 
            
     9 
                    
                    drymonfidelia   OP @fzls 接口太多了,校验起来工作量翻倍 
                 | 
            
     10 
                    
                    drymonfidelia   OP @lambdaq 按照 2 楼的查一下,mongodb 注入花样还很多 
                 | 
            
     11 
                    
                    NewYear      2024-06-10 00:39:09 +08:00 
                    
                    可能是我的知识太贫瘠了。 
                我一般认为丢到数据库里的数据就两种, 非字符串和字符串。 字符串就用引号包起来,做个转义,,,,非字符串就判断一下类型对不对。 这是不用“参数化查询”、“绑定数据”的方法,如果用上绑定数据,就不用转义数据了(数据库会做这一步)。 所以我迷茫了,你的问题在哪呀。(不太熟悉这个数据库)  | 
            
     12 
                    
                    zeusho871      2024-06-10 00:42:40 +08:00 
                    
                    django 好像有个 mongo 库 啥都给你封装好的 
                 | 
            
     13 
                    
                    drymonfidelia   OP  | 
            
     14 
                    
                    Masterlxj      2024-06-10 01:00:53 +08:00 
                    
                    不用 ORM ? 
                 | 
            
     15 
                    
                    hdben      2024-06-10 01:22:27 +08:00 
                    
                    听起来像是,没有对数据做任何处理, 直接把前段给的内容作为查询语句的一部分? 
                 | 
            
     16 
                    
                    drymonfidelia   OP  | 
            
     17 
                    
                    dayeye2006199      2024-06-10 01:29:57 +08:00 via Android 
                    
                    自己搞不定就 ODM 
                 | 
            
     18 
                    
                    sagaxu      2024-06-10 02:07:00 +08:00 via Android 
                    
                    @drymonfidelia 用户请求参数构造成 map 了,框架层面可以禁用这个特性么?比如写个拦截器,所有参数统一转成 str ,特殊情况再特殊处理 
                 | 
            
     20 
                    
                    vituralfuture      2024-06-10 03:05:07 +08:00 via Android 
                    
                    web 框架基本都有数据类型校验的功能吧,或者用 pydantic 也行,fastapi 自带这个功能。另外后端基本常识,不信任前端传来的任何数据 
                 | 
            
     21 
                    
                    laminux29      2024-06-10 07:51:22 +08:00    楼主举的注入例子:Payload {"password":{"$ne":"111"}} 
                这正是参数化查询模块要去处理的事情,如果这还没注入了,你确定你正确使用了参数化查询模块? 建议用 AI 把你的代码检查一遍。  | 
            
     22 
                    
                    msg7086      2024-06-10 08:10:02 +08:00    用户输入的密码为什么能传进 mongo ?换我的话会先取出 password hash 然后再在本地对比。 
                这系统谁开发的啊这么简单的坑也能中的吗。 输入参数校验是基本要求吧,这不叫工作量翻倍,这是之前为了走捷径把大动脉砍了,现在在亡羊补牢。 再还有,你们的测试代码呢,这种场景不写 behavior test 的吗。  | 
            
     23 
                    
                    hlwjia   PRO 既然你觉得用 ORM 怕麻烦,那现在处理这些问题你觉得麻烦不? 
                如果 ORM 光是麻烦,没别的好处,也不会有人一直用吧 还有 #9 楼你写的,“接口太多,校验起来工作量翻倍”,不知道你现在的工作量翻倍了没有  | 
            
     24 
                    
                    Kinnice      2024-06-10 08:23:23 +08:00 via Android 
                    
                    1. 先上 waf 
                2. 没正确使用参数校验模块  | 
            
     25 
                    
                    among      2024-06-10 08:49:24 +08:00 
                    
                    mongoengine 用了吗 
                 | 
            
     26 
                    
                    vincent7245      2024-06-10 09:08:23 +08:00    "接口太多了,校验起来工作量翻倍" 
                那还能说什么呢,最基础的防护都不做,没被删库也算攻击者仁慈了  | 
            
     27 
                    
                    MMM25O7lf09iR4ic      2024-06-10 09:19:48 +08:00 
                    
                    普通程序员除了依赖框架没有什么好手段,因为他们连相关的概念都没有,谈什么防御。简单的过滤字符串可不代表能解决问题,某个知名库一个特殊字符改了三次才解决问题。 
                 | 
            
     28 
                    
                    EndlessMemory      2024-06-10 10:55:24 +08:00 
                    
                    你这个管理起来问题不小 
                 | 
            
     29 
                    
                    walkeronway      2024-06-10 12:34:41 +08:00 
                    
                    嫌麻烦?这会儿被教做人了吧?你以为为啥大家都在做安全防护,是闲着没事干还是喜欢? C 端产品要直面所有可能的恶意,敢偷懒? 
                话说静态扫描能扫出来你这些安全漏洞吗?  | 
            
     30 
                    
                    awolf      2024-06-10 12:38:57 +08:00 
                    
                    LZ 开善堂的,大家可以散了 
                 | 
            
     31 
                    
                    kneo      2024-06-10 12:54:58 +08:00 via Android    啥叫用新技术必被坑?我看你就是最大的坑…… 
                 | 
            
     32 
                    
                    uiiytwyfsdtr      2024-06-10 13:53:40 +08:00 
                    
                    网络攻防 其实防不胜防 
                只能靠你自己的 经验 和 安全意识  | 
            
     33 
                    
                    yidinghe      2024-06-10 14:08:07 +08:00 via Android 
                    
                    你把调用方的参数直接透传给数据库,不死才怪。首先防住登录接口,然后其他接口要有状态,根据调用方权限添加对应的查询条件,而且禁止调用方通过参数覆写这些条件。最后每个接口设置参数白名单,不在白名单中的参数过滤掉。 
                 | 
            
     34 
                    
                    drymonfidelia   OP @msg7086 这系统只支持短信验证,password 字段存的其实是短信验证码,所以没加密 
                这套系统需求太杂了都是手动测试  | 
            
     35 
                    
                    hefish      2024-06-10 15:31:54 +08:00    大佬 A:哎呀。。。没搞了,来帮帮我啊。。 
                大佬 B:你这个要这么这么这么。。。 大佬 A:那太麻烦了,谁有更好的办法吗? 大佬 C:那你先这么这么这么。。。不然会有问题 大佬 A:我觉着没问题。。 大佬 D:你不写个 ORM 吗? 大佬 A:写 ORM 太麻烦了。。。谁能帮帮我啊。。。 。。。。  | 
            
     36 
                    
                    gwy15      2024-06-10 15:39:53 +08:00 via iPhone 
                    
                    你不会是从 req json.loads 读一个 object 然后直接传给 mongodb 吧 
                 | 
            
     37 
                    
                    rb6221      2024-06-10 15:41:31 +08:00    哈哈哈,出现安全问题了,然后说别人的方法麻烦。。。 
                安全就是麻烦的啊,你以为飞机起飞前一遍遍教人使用救生衣是干什么的?  | 
            
     38 
                    
                    GG5332      2024-06-10 16:12:40 +08:00 
                    
                    没有必要冷嘲热讽,安全从来都是一种取舍,只要被黑带来得损失都没有比写 ORM 的麻烦大,那就大可不必写,而且还更好,黑客也很开心,你也很开心。何尝不是一种 win ,win 。现实就是很多业务就是跟羊毛党黑产党相互依存,不离不弃。 
                 | 
            
     39 
                    
                    lneoi      2024-06-10 16:16:28 +08:00 
                    
                    懒的话就上 web 防火墙,或者其他服务器防护软件,多多少少能处理大部分情况 
                 | 
            
     40 
                    
                    gongquanlin      2024-06-10 16:16:55 +08:00 
                    
                    想起来接的一个擦屁股的活,大哥前后端全栈开发,查询语句直接前端拼 where 后端查询 
                到现在 bug 一堆还没上线,到了上线之后还不知道咋甩锅呢,哈哈哈  | 
            
     41 
                    
                    yjxjn      2024-06-10 16:42:22 +08:00 
                    
                    @drymonfidelia #9 你现在看看,工作量不仅翻倍,损失也在翻倍。 
                 | 
            
     42 
                    
                    fangxiaoning      2024-06-10 18:00:31 +08:00 
                    
                    要么就是有地方没有参数化,要么就是有其他漏洞吧,参数化了注入不了的 
                 | 
            
     43 
                    
                    bunny189      2024-06-10 18:12:58 +08:00 via iPhone 
                    
                    早用我们 laravel P 事没有,所有东西都给你集成好了,开箱即用爽得很 
                 | 
            
     44 
                    
                    drymonfidelia   OP @fangxiaoning 按二楼提供的关键词,参数化了还有一堆花样能注入 
                 | 
            
     45 
                    
                    009694      2024-06-10 18:20:49 +08:00 via iPhone 
                    
                    password 字段应该接受的是一个字符串 你是怎么把 dict 传递进去的? 
                 | 
            
     46 
                    
                    drymonfidelia   OP @009694 直接读的 json ,没有数据模型 
                 | 
            
     47 
                    
                    leegradyllljjjj      2024-06-10 19:41:17 +08:00 
                    
                    啥时代了还在被 sql 注入,就像 2024 一个计算机系大大学生说我的智能手机键盘坏了 
                 | 
            
     48 
                    
                    LeeReamond      2024-06-10 21:10:04 +08:00 
                    
                    @hlwjia 这和 ORM 有什么关系,ORM 也是调底层驱动的。正常来说应该是用参数化查询就不会被按对象解析,只能说可能它这个 mongodb 比较奇怪吧。。 
                 | 
            
     49 
                    
                    sagaxu      2024-06-10 21:20:50 +08:00    @LeeReamond mongodb 查询时传入的 value 可以是 bson(list/map),driver 是分不清这个 bson 是你自己构造的还是被注入的,想不被注入,代码里要保证所有传入的 value 都是 str 或者 number ,str 里无论怎么写都不会被注入 
                 | 
            
     50 
                    
                    des      2024-06-10 21:42:01 +08:00 via iPhone 
                    
                    @drymonfidelia 参数化还能被注入,那就说明你写的不对 
                 | 
            
     51 
                    
                    MrKrabs      2024-06-10 22:02:39 +08:00 
                    
                    神人 
                 | 
            
     52 
                    
                    podel      2024-06-10 22:37:24 +08:00 
                    
                    接入 ORM 
                 | 
            
     53 
                    
                    yunye      2024-06-10 22:39:27 +08:00 
                    
                    这项目质量也能有用户充钱? 
                 | 
            
     54 
                    
                    drymonfidelia   OP @yunye 因为这个项目只有我们在做。项目质量差就是因为急着上线,招了一堆临时工赶进度 
                 | 
            
     55 
                    
                    drymonfidelia   OP @drymonfidelia 九百多个接口从立项到上线只用了一个月多一点 
                 | 
            
     56 
                    
                    scriptB0y      2024-06-10 23:01:06 +08:00 
                    
                    不明白怎么注入的,假设 `{"$ne":"111"}` 这个字符串传回来,这也是个 string 吧,拿它来和真正的密码对比,肯定是不想等的呀? (做 hash 之后对比就更不想等了) 
                 | 
            
     57 
                    
                    drymonfidelia   OP @scriptB0y 因为 password 字段实际存的是短信验证码,我们偷懒直接三个条件(手机号 短信验证码 有效期)查出来有记录就登录成功 
                 | 
            
     58 
                    
                    drymonfidelia   OP 卧槽怎么好像又被黑了,数据库有大上传流量 
                 | 
            
     59 
                    
                    Belmode      2024-06-10 23:06:14 +08:00 
                    
                    离谱...... 
                如果不想每个接口上都单独校验,可以在中间件或者框架的过滤器上把正常接口的入参全部审查一遍。  | 
            
     60 
                    
                    drymonfidelia   OP @Belmode 就是这么做的,目前会遍历 dict 每个 key ,只允许 number 、string 、list 的 value ,list 的 value 会再次过滤,只允许 string 和 number 的成员,希望不会再出问题 
                 | 
            
     61 
                    
                    drymonfidelia   OP @drymonfidelia 还有 boolern 和 null(None),也允许 忘写了 
                 | 
            
     62 
                    
                    scriptB0y      2024-06-10 23:13:49 +08:00 
                    
                    @drymonfidelia 但是如果攻击者使用这个 {"$ne":"111"} 传进来,你查数据的内容不应该是: 
                {"password": {"$eq": {\"$ne\":\"111\"}"}} 这样吗?查询也不成立呀。 莫非。。。你直接让前端给你传过来查询的语句?  | 
            
     63 
                    
                    drymonfidelia   OP @scriptB0y 前端传来的是 JSON ,框架 parse 出来的 password 是一个 dict 
                 | 
            
     65 
                    
                    lrh3321      2024-06-11 06:19:26 +08:00 via Android 
                    
                    你这 password 的类型都不对了,再怎么赶工,你也要先把它强转成字符串吧。 
                 | 
            
     66 
                    
                    LuckyLauncher      2024-06-11 08:56:33 +08:00 
                    
                    “校验起来工作量翻倍” 
                那等人把你们用户的余额都刷完,你就没有任何工作量了  | 
            
     67 
                    
                    lambdaq      2024-06-11 09:28:56 +08:00 
                    
                    @drymonfidelia 大概明白了。直接把 json 里的东西传到 mongo 里去操作。。好家伙。。 
                 | 
            
     68 
                    
                    Nazz      2024-06-11 09:32:22 +08:00 
                    
                    是不是让前端传 JSON 过来自己查询了 
                 | 
            
     69 
                    
                    drymonfidelia   OP @Nazz json 的字段值直接带入查询了 
                 | 
            
     70 
                    
                    bthulu      2024-06-11 10:05:28 +08:00 
                    
                    改什么改, 报警啊 
                 | 
            
     71 
                    
                    mmdsun      2024-06-11 10:10:38 +08:00 
                    
                    这种可能是 json 序列号漏洞,比如 fastjson 这种漏洞提权就很多 
                 | 
            
     72 
                    
                    sampeng      2024-06-11 10:58:02 +08:00 
                    
                    @drymonfidelia 嫌麻烦,就别怨踩雷 
                 | 
            
     73 
                    
                    Cruzz      2024-06-11 11:48:48 +08:00 
                    
                    这直接给参数拼 sql 去处理?都当字符串处理不就行了么。 
                 | 
            
     74 
                    
                    corcre      2024-06-11 14:17:56 +08:00 
                    
                    你这参数化处理是我见过最新奇的... 
                 | 
            
     75 
                    
                    rainingwrong      2024-06-11 15:06:40 +08:00 
                    
                    @drymonfidelia 想啥呢,上 ORM 
                 | 
            
     76 
                    
                    MapleEve      2024-06-11 15:23:59 +08:00 
                    
                    这个为什么不上 ORM 啊 
                 | 
            
     77 
                    
                    GoRoad      2024-06-11 15:26:46 +08:00 
                    
                    大开眼界 
                 | 
            
     78 
                    
                    yumenlong      2024-06-11 16:46:34 +08:00    https://ex.noerr.eu.org/t/1048368#  看了 op 这篇主题,感觉是来编故事赚铜币的吧. 
                 | 
            
     79 
                    
                    Kalan      2024-06-11 17:17:08 +08:00 
                    
                    还有这种神人 
                 | 
            
     80 
                    
                    drymonfidelia   OP @yumenlong 我铜币根本用不完 骗来干什么 
                 | 
            
     81 
                    
                    h175h32      2024-06-11 21:37:36 +08:00 
                    
                    装一个 web 防火墙 
                 | 
            
     82 
                    
                    vishun      2024-06-12 08:12:18 +08:00 
                    
                    绝对压根没有用参数化查询 
                 |