没人注意的攻击,从你网站的联系表单进来
联系表单看着人畜无害。它其实是你敞得最开的一扇门,几乎没人上锁。
人人都护着登录页。没人看联系表单。可它偏偏接受任何人的输入,不用认证,没有摩擦,很多时候连提交次数都不限。
攻击者要的就是这种不对称。一个文本框,直连你的邮件服务器、你的数据库,或某个内部 webhook。你看到的是一个「留言」字段。他看到的是一行命令。
为什么这个目标这么诱人
一个联系表单把三个罕见的特性凑在了一处。它接受不可信的输入。它在服务器上跑逻辑。而且几乎从不被审计。开发者测过留言能进邮箱,就到此为止。
问题是,「留言能进邮箱」背后藏着一整条路径。用户的文字被拼进 SMTP 头,被串进一条查询,或被发往第三方服务。每一道边界都是一次注入的机会。
邮件头注入
经典手法叫 email header injection。如果你把「主题」或「发件人」字段直接贴进邮件头,攻击者写个换行,就能加上自己的头。比如给一千个地址加一条密送。
转眼间你的服务器就在发垃圾邮件。不是碰巧冒你的名,而是实打实地借你的基础设施、你的 IP、你的域名发出去。结果很好预测:各大邮件商把你的域名标成垃圾邮件源,你的业务邮件从此哪儿都到不了。
文本变成代码
再往下是更糟的情形。如果你不做参数化就把留言存进数据库,你就为 SQL 注入开了门。如果你在后台面板里不转义 HTML 就展示留言,攻击者种下一段脚本,你团队打开这条线索时它就在浏览器里跑起来。这是存储型 XSS,也是最被低估的攻击途径之一。
注意这个规律。以上没有一例是攻击者「攻破」了什么。他就照着表单被设计出来的样子去用它。这漏洞不是什么奇门异术。它只是缺了一条简单的规矩:绝不相信进来的东西。
该怎么做,按优先级排
你不需要 WAF,也不需要安全顾问,就能堵住其中九成。你需要的是四点上的自律。
- 在服务器端校验,绝不只在浏览器端。前端校验是给用户的舒适感,不是安全。攻击者不用你的表单,他直接向接口发 POST。
- 输出时永远转义。存进数据库用参数化查询。在面板上展示时转义 HTML。在证明无害之前,把每条留言都当成敌意的。
- 在头字段里拒绝换行。主题、姓名、邮箱没理由包含 \r 或 \n。碰到 SMTP 之前就把它们过滤掉。
- 限制提交频率,加一道隐形挑战。按 IP 做速率限制,配一个蜜罐或 hCaptcha,就能挡住自动化机器人,又不打扰真人。
还有几乎所有人都忘掉的那一面
一个联系表单收集的是个人数据。姓名、邮箱,很多时候还有电话和留言内容。这就把你放进了 GDPR 的范围,不管你乐不乐意。你需要一个处理这些数据的法律依据,而同意必须是知情的。
落到实处就是三件具体的事。表单旁边挂一份清晰的隐私说明。一个明确的法律依据,通常是第 6 条的正当利益,或明示同意。再加一条留存策略,因为把线索永久留着不是策略,是不断堆积的责任。要是你的线索库被偷,问题就不再是技术问题,而成了监管问题。
表单安全不是一道昂贵的防火墙。它是你拒绝去相信一个陌生人写下的文字。— Krivar Diário
这个道理很无聊,所以才管用。没人看见的攻击,从没人看的那扇门进来。像对待登录一样尊重你的联系表单,这些问题大多数根本不会发生。