小程序后端开发的安全问题,最容易被忽视的往往不是HTTPS或者登录鉴权,而是业务接口本身。多数团队把精力放在前端代码加固、防逆向、防篡改上,但后端一旦暴露一个未校验身份的查询接口,攻击者可以直接遍历用户数据。真正有效的专项防护,必须从接口鉴权、数据校验、传输加密、敏感信息脱敏、运行环境隔离、日志审计六个维度同时下手,而不是只做某一项。
接口鉴权必须做到“双令牌”机制小程序前端的登录态不能只依赖wx.login返回的code换取openid就完事。正确的做法是,前端调用wx.login拿到临时code,后端用code向微信接口换取openid和session_key,然后生成两样东西:一个短期有效的access_token用于业务请求,一个长期有效的refresh_token用于续期。access_token有效期建议控制在2小时以内,refresh_token有效期不超过30天。每次请求业务接口时,access_token放在请求头Authorization字段中,后端校验签名和过期时间。不要用URL参数传递token,因为网关和日志会记录URL,导致token泄露。
另一个容易被忽略的点是,access_token必须与设备指纹绑定。后端在签发token时,记录前端上报的设备标识(如机型、系统版本、小程序版本、网络类型等组合生成的指纹),每次请求校验指纹一致性。如果指纹变化,直接判定token失效并要求重新登录。这样可以有效防止token被窃取后在其它设备上重放。
敏感数据接口必须做“资源归属校验”很多数据泄露事件不是因为没有鉴权,而是因为接口只校验了“用户已登录”,却没有校验“这个数据属于当前用户”。例如查询订单详情接口,前端传一个orderId,后端直接返回数据。攻击者只要登录自己的账号,然后遍历orderId就能拿到其他用户的订单。正确的做法是,所有涉及具体资源的查询、修改、删除操作,后端必须校验该资源是否属于当前登录用户。例如订单查询,SQL条件中必须带上user_id = 当前用户ID,而不是只按orderId查询。
对于管理员接口,更要单独做权限分级。小程序管理后台的接口不能和小程序端接口混用同一套鉴权体系。管理端接口需要独立的角色权限校验,并且限制只能从特定IP段或通过VPN专线访问。如果管理端接口暴露在公网且仅靠一个简单密码,等于把整个数据库开放给攻击者。
输入校验不能只靠前端,后端必须二次过滤前端做表单校验只是提升用户体验,不能作为安全防线。攻击者可以绕过小程序直接调用后端接口,所以后端必须对所有入参做严格校验。包括但不限于:参数类型、长度、范围、格式、枚举值。对于字符串类型参数,要防止SQL注入和XSS。对于数字类型参数,要防止溢出和负数。对于文件上传接口,要限制文件类型、大小、数量,并对文件内容做病毒扫描。
SQL注入的防护不能依赖手动拼接字符串时加转义,必须使用参数化查询或ORM框架提供的预编译语句。例如在Node.js中使用mysql2的execute方法,在Java中使用PreparedStatement,在Python中使用SQLAlchemy的参数绑定。对于动态排序字段、动态表名这类无法参数化的场景,必须使用白名单校验,只允许传入预定义的字段名。
传输层加密要覆盖全链路小程序前端到后端API的通信必须全站启用HTTPS,并且强制使用TLS 1.2及以上版本。证书要选择受信任的CA机构签发,不要使用自签名证书。同时要注意,小程序后台配置的request合法域名必须是HTTPS协议,否则在正式环境无法通信。但仅仅前端到API的链路加密还不够,如果后端服务之间、后端与数据库之间、后端与缓存之间是明文传输,攻击者一旦进入内网就能窃听数据。
对于后端服务间的调用,建议使用mTLS双向认证,或者至少在内网使用HTTPS。数据库连接要启用SSL,Redis等缓存服务如果暴露在公网,必须设置强密码并限制访问IP。云环境中的安全组规则要最小化开放,只允许必要的端口和来源IP访问。
敏感信息必须脱敏存储和展示手机号、身份证号、银行卡号、地址等个人信息,在数据库存储时不能明文保存。手机号可以使用AES加密存储,或者至少做部分掩码存储。身份证号和银行卡号必须加密存储,解密密钥要放在独立的密钥管理服务中,不能硬编码在代码里。日志中禁止记录完整手机号、身份证号、token、密码等敏感信息,需要记录时做掩码处理。
接口返回给前端的数据也要做脱敏。例如用户列表接口返回手机号时,只返回中间四位掩码后的格式:1385678。前端展示需要完整手机号的场景,必须单独调用一个鉴权更严格的接口,并且记录调用日志。不要为了前端方便就把完整手机号放在列表接口里返回。
运行环境隔离和依赖安全后端服务部署时要区分开发环境、测试环境、生产环境,三者之间的数据不能互通。生产环境的数据库账号、密钥、第三方服务凭证必须与开发测试环境完全隔离。很多安全事件是因为开发人员把生产环境的配置提交到了代码仓库,或者测试环境使用了生产环境的备份数据。代码仓库中严禁出现任何真实密钥,使用环境变量或配置中心注入。
依赖安全同样重要。Node.js、Java、Python等后端项目的第三方依赖包可能存在已知漏洞。需要定期使用npm audit、OWASP Dependency-Check、Snyk等工具扫描依赖漏洞,并及时升级。不要使用来源不明的第三方SDK,尤其是小程序端引入的SDK,因为小程序端SDK可以获取用户信息并上传到第三方服务器。
日志审计和异常监控要形成闭环后端必须记录所有关键操作的审计日志,包括登录、注册、修改密码、修改手机号、支付、退款、管理员操作等。日志内容要包含用户ID、操作类型、操作时间、IP地址、设备指纹、请求参数摘要、操作结果。日志存储要集中化,并且保留至少180天。日志系统本身要设置访问权限,防止攻击者删除日志掩盖踪迹。
同时要配置实时告警机制。例如同一用户短时间内大量请求、同一IP频繁尝试登录失败、异常时间段的操作、敏感接口的异常调用频率等,都要触发告警。告警可以通过邮件、短信、企业微信等方式通知运维人员。没有告警的日志等于没有日志,因为安全事件发生时往往已经过去了很久。
小程序后端安全防护是一个持续的过程,不是上线前做一次渗透测试就结束了。业务迭代过程中新增的接口、修改的逻辑、引入的依赖都可能带来新的风险。建议每个版本上线前都做一次安全评审,重点检查新增接口的鉴权和数据校验逻辑。同时定期对线上环境做漏洞扫描和渗透测试,发现问题及时修复。安全方案的价值不在于文档写得有多完整,而在于每个接口、每个数据字段是否真正落实了校验和防护。
