微信小程序任意手机号登录漏洞原理与修复方案
本文分析了微信小程序中因 SessionKey 泄露导致的任意手机号登录漏洞。详细阐述了微信登录机制中 SessionKey、encryptedData 及 iv 的交互原理,展示了如何通过 Burp Suite 抓包、Python 脚本解密篡改数据并重新加密的完整攻击流程。文章最后提供了服务端验证、签名校验等修复方案,强调密钥不应返回前端,应在服务端完成解密逻辑以防止用户信息被非法劫持。

本文分析了微信小程序中因 SessionKey 泄露导致的任意手机号登录漏洞。详细阐述了微信登录机制中 SessionKey、encryptedData 及 iv 的交互原理,展示了如何通过 Burp Suite 抓包、Python 脚本解密篡改数据并重新加密的完整攻击流程。文章最后提供了服务端验证、签名校验等修复方案,强调密钥不应返回前端,应在服务端完成解密逻辑以防止用户信息被非法劫持。

在微信小程序的安全测试中,开发者经常遇到一种高危漏洞:任意用户登录(Arbitrary User Login)。这种漏洞通常出现在'微信快捷登录'功能中。攻击者可以通过截获请求包,利用返回的敏感信息解密并修改用户数据,从而伪装成任意用户进行登录。
该漏洞的核心在于小程序后端逻辑对客户端传入数据的信任度过高,且未能有效验证会话密钥(sessionKey)的归属权。
当用户使用微信授权登录小程序时,微信服务器会返回一个 sessionKey。这个密钥用于加密和解码用户的敏感信息(如手机号、OpenID 等),以保护用户隐私。
官方机制流程如下:
wx.login 获取临时登录凭证 code。code 发送给后端服务器。code 换取 openid 和 session_key。session_key 配合 iv 和 encryptedData 进行 AES 解密,获取用户信息。问题点: 在某些实现不当的小程序中,sessionKey 并没有严格限制在后端服务器内部流转,而是被直接返回给了前端,或者在请求/响应包中以明文形式暴露。一旦攻击者获取了 sessionKey,就可以解密任何由该密钥加密的数据包。
微信提供的用户信息加密方式通常为 AES-CBC。主要参数包括:
encryptedData: 加密后的密文(Base64 编码)。iv: 初始化向量(Base64 编码)。sessionKey: 解密密钥。如果攻击者能够获取这三个要素,即可通过标准算法解密出原始的用户手机号等信息。
使用 Burp Suite 等工具拦截小程序的登录请求。重点关注包含 encryptedData 字段的接口。
正常情况下,请求包应包含以下关键参数:
code: 登录凭证。encryptedData: 加密的用户信息。iv: 初始化向量。sessionKey: 注意观察此处是否暴露。若发现 sessionKey 直接出现在请求体或响应头中,则存在高危风险。
encryptedData、iv 和 sessionKey。sessionKey 和 iv 对修改后的数据进行加密。encryptedData 替换原请求包中的值并发送。若后端仅校验解密结果而不校验 sessionKey 的来源合法性,攻击即可成功。
以下是一个基于 Python 的解密与重加密示例,用于演示漏洞原理。实际环境中请勿滥用。
import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
# 模拟从请求包中提取的参数
session_key = "your_session_key_here" # 需替换为实际获取的 sessionKey
iv = "your_iv_here" # 需替换为实际获取的 iv
encrypted_data = "your_encrypted_data_here" # 需替换为实际获取的 encryptedData
try:
# 解码 Base64
key = base64.b64decode(session_key)
iv_bytes = base64.b64decode(iv)
data_bytes = base64.b64decode(encrypted_data)
# 创建 AES 解密器
cipher = AES.new(key, AES.MODE_CBC, iv_bytes)
# 解密并去除填充
decrypted = unpad(cipher.decrypt(data_bytes), AES.block_size)
# 输出明文
print("Decrypted Data:", decrypted.decode('utf-8'))
except Exception as e:
print(f"Error: {e}")
若要实施攻击,需在解密后修改 JSON 中的手机号字段,再使用相同 Key 和 IV 进行加密替换。
针对此类漏洞,建议采取以下措施:
不要完全信任客户端传来的 encryptedData。最安全的做法是:
code 给后端。code 调用微信 API 获取 openid 和 session_key。session_key 解密 encryptedData(如果必须传输用户信息)。sessionKey 返回给前端。对于关键操作,建议增加签名校验机制。确保请求数据未被篡改,且来源可信。
仅收集业务必需的用户信息。避免过度依赖微信提供的手机号接口,可引导用户手动输入或通过其他安全渠道验证身份。
微信小程序的任意登录漏洞本质上是会话管理不当导致的信任链断裂。开发者应严格遵守微信官方安全规范,确保敏感密钥不落地到客户端,并在服务端完成所有核心解密与验证逻辑。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online