当前位置:首页 > 时尚

websql注入

去年帮朋友看一个后台系统,注入登录框里随手敲了个单引号,注入页面直接甩出一段SQLite报错。注入不用猜,注入WebSQL注入。注入很多人以为SQLite这种嵌入式数据库只在手机App里跑,注入跟Web安全不沾边,注入恰恰是注入这种盲区让漏洞活得挺滋润。

WebSQL是注入浏览器端的一套API,允许JavaScript直接操作本地SQLite数据库。注入Chrome、注入Safari曾经都支持,注入虽然W3C在2010年就停止维护这个规范,注入但大量老项目、注入混合开发框架、注入甚至某些Electron应用里还在用。IndexedDB是官方推荐的替代品,可迁移成本摆在那,于是WebSQL就这么半死不活地撑着。

它的注入逻辑跟传统SQL注入一模一样——用户输入被拼进SQL语句,没有参数化,没有转义。区别在于攻击面:传统注入打的是服务端数据库,WebSQL注入打的是浏览器本地库。听起来危害小?想想看,一个用WebSQL存用户凭证、订单草稿、离线消息的Web App,攻击者通过注入能读整张表,甚至用ATTACH DATABASE把数据写到可控文件里。

我见过一个真实案例。某离线笔记应用把用户输入直接拼进INSERT INTO notes (title, content) VALUES ('"+title+"','"+content+"')。标题栏填'); DROP TABLE notes;--,整张笔记表当场蒸发。更隐蔽的玩法是UNION SELECT把其他表的数据带出来,比如用户表里的token。

有人会问:浏览器本地库,攻击者怎么拿到数据?XSS。一个存储型XSS配合WebSQL注入,恶意脚本在受害者浏览器里执行查询,把结果POST到远程服务器。整个链路不需要碰服务端一行代码。或者更直接——如果应用把WebSQL数据同步到云端,注入产生的脏数据会跟着同步上去,污染服务端。

防御手段其实不复杂。WebSQL的executeSql方法支持参数化查询,第四个参数传数组就行:

db.transaction(function(tx) {  tx.executeSql('SELECT * FROM users WHERE name = ?', [userName], ...); });

但现实是,很多老代码用字符串拼接图方便。我翻过一些开源项目,2018年之后的代码里还能看到"WHERE id = " + id这种写法。开发者觉得本地库无所谓,安全审计也常忽略前端存储层。

另一个坑是executeSql的批量执行。有人把多条语句拼成一个字符串丢进去,SQLite默认不支持多语句执行,但某些浏览器实现允许。一旦允许,注入点就从单条查询扩展到任意DDL/DML。

还有个细节:WebSQL的报错信息默认会通过回调函数暴露给前端。不处理error回调,错误直接进console,攻击者用XSS hook住console.log就能拿到表结构。这比盲注舒服多了。

说回那个朋友的后台。我让他把所有拼接查询改成参数化,半小时改完。他问要不要加WAF规则,我说不用,前端注入WAF拦不住——请求里根本没有恶意payload,全在浏览器里生成。他愣了一下,然后说了句“那这玩意儿还挺阴”。

确实阴。服务端注入有ORM、有预编译、有安全框架兜底,WebSQL这边基本裸奔。规范废弃了,文档稀烂,社区讨论少,出问题连Stack Overflow都搜不到几条。如果你手头还有用WebSQL的老项目,别犹豫,要么迁IndexedDB,要么至少把参数化查询补上。别等报错页面甩出来才后悔。

分享到: