检测应用程序内部的漏洞
去年有个朋友把一款开源笔记应用装到了自己服务器上,检测用了不到两周,应用数据库就被拖走了。程序攻击入口不是内部什么高深的零日漏洞,而是漏洞应用自带的一个导出接口——它把用户传入的文件名直接拼进了系统命令里。开发者在写这段代码时大概只想着"导出功能真方便",检测完全没意识到自己顺手给攻击者留了后门。应用
这类事情每天都在发生。程序应用程序内部的内部漏洞,往往不是漏洞被"攻破"的,而是检测被"发现"的。区别在于,应用前者需要高超技术,程序后者只需要耐心和一点好奇心。内部
代码写出来那一刻,漏洞漏洞就已经在了
很多人以为漏洞是后来被引入的,其实大部分漏洞在代码提交的那一刻就存在了。一个参数没做边界检查,一个字符串没转义,一个权限判断写在了错误的层级——这些细节在功能测试阶段根本暴露不出来,因为测试用例只覆盖了"正常使用"的路径。
我见过一个电商系统,商品详情页的接口接受一个item_id参数。正常请求返回商品信息,但如果把item_id换成1 OR 1=1,它会返回整个商品表的第一条记录。更糟的是,这个接口没有任何鉴权,未登录用户也能调用。开发者后来解释说"没想到有人会改参数"。这种"没想到"三个字,几乎可以概括八成以上的应用漏洞成因。
检测不是跑一遍扫描器就完事
市面上的自动化扫描工具能覆盖一些常见问题,比如SQL注入、XSS、目录遍历。但工具的报告经常让人哭笑不得——一堆误报里夹着几个真问题,你得自己判断哪些值得深挖。而且工具对业务逻辑漏洞基本无能为力。比如一个优惠券系统,允许用户重复领取同一张券,扫描器不会觉得这有什么异常,但业务上这就是个资金漏洞。
我自己的习惯是先把应用跑起来,用Burp Suite挂上代理,手动点一遍所有功能。注册、登录、改密码、下单、退款、上传文件——每个操作都看一遍请求和响应。重点不是找那些明显的注入点,而是观察哪些参数是客户端可控的、哪些接口缺少权限校验、哪些返回值包含了不该返回的数据。
有一次我在一个后台管理系统里发现,普通用户登录后,把URL里的/user/profile改成/admin/users,居然能直接看到所有用户的手机号和邮箱。前端做了菜单隐藏,但后端接口压根没检查角色。这种问题扫描器扫不出来,因为URL本身没有任何特殊字符,它只是一个"没权限的人访问了不该访问的页面"。
看日志比看代码更快找到线索
如果你能拿到应用的运行日志,那是最好的切入点。异常堆栈里经常藏着数据库结构、文件路径、甚至部分SQL语句。一个报错信息里出现了SELECT * FROM orders WHERE user_id = '...',你就知道这里大概率存在注入。日志里频繁出现的404和500,往往对应着被扫描器或者攻击者探测过的路径。
还有个小技巧:把应用的所有接口列出来,逐个去掉认证头再请求一遍。很多系统在开发阶段为了方便调试,把某些接口的鉴权关掉了,上线时忘了加回来。我遇到过不止一次,删除用户、修改配置这类高危操作,居然不需要任何token就能调用。
别忽略客户端
移动端应用和桌面客户端同样值得翻一翻。APK反编译之后,经常能看到硬编码的API密钥、测试环境的地址、甚至数据库密码。有个同事在某个App的strings.xml里找到了一串AWS密钥,权限还开得挺大。开发者大概觉得"打包进APK里没人会看",但反编译工具用起来比解压压缩包难不了多少。
检测应用程序内部的漏洞,说到底是个体力活加细心活。工具能帮你省时间,但替代不了对业务逻辑的理解和对异常细节的敏感。那些真正造成损失的漏洞,往往就藏在开发者觉得"这地方没人会动"的角落里。









