首页/开发/正则与编码速查/URL 重复编码问题排查

URL 重复编码问题排查

重复编码的特征是百分号本身被转义:%E4%B8%AD 变成 %25E4%25B8%25AD,解码一次后仍是编码形式;原因是链路中编码环节被叠加两次,修复要在数据与链路上同时进行。

正则与编码速查开发更新于 2026-10-17
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​​‌‌‌​‌‌​​‌​‌​‌‌‌‌​​​​​‌​‌‌‌‌​‌‌‌​‌​‌​‌‌‌​​‌​​‌‌​‌‌​​​​‌​‌‌​‌​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌‌​‌​‌​‌‌​​​‌​​‌‌​‌‌​​​‌‌​​‌​‌​​‌​‌‌​‌​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​​‌​​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌‌‌​​‌​‌‌​‌​‌‌​​‌​​​‌‌​​‌​‌​‌‌​​​‌​​‌‌‌​‌​‌​‌‌​​‌‌‌​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​

识别与成因

重复编码最直观的标志是 %25:因为百分号自身编码为 %25,被编码两次就会出现 %25E4%25B8%25AD 这类内容,解开一层后还是编码字符串。成因通常不是恶意构造,而是链路叠加:框架自动编码一次,业务代码又编码一次;或者数据经过网关、队列、脚本转换时被重复处理。长期存在的后果不止是「不好看」——长度膨胀、日志难以检索、索引与去重失效,甚至在签名与校验环节引入不一致。

基本信息

单层编码外观%E4%B8%AD 形式,解开即得中文
双层编码外观%25E4%25B8%25AD,解开一层仍是编码串
层数判据数 %25 的嵌套次数,或逐次解码直到可读
常见成因框架自动编码叠加业务代码编码、链路重复处理
影响长度膨胀、检索与去重失效、签名不一致
修复原则数据与链路同时修,避免复发

典型使用场景

  • 接口联调:参数值里出现 %25,值是「中文的编码」而不是中文
  • 数据清洗:历史数据被重复编码,需要确定层数后逐层还原
  • 日志分析:检索关键字时常因编码层数不同而漏查
  • 签名排查:多层编码导致签名基串与预期不符
  • 安全审查:重复编码常被用来绕过过滤器,需按最终形态校验

层数判断与还原

层数判断与还原
# 逐层解码并观察内容变化
python - <<'PY'
import urllib.parse as u
s = '%25E4%25B8%25AD'
for i in range(3):
    s2 = u.unquote(s)
    print(i, s2)
    if s2 == s:
        break
    s = s2
PY
# 快速数层:统计 %25 出现的次数
python -c "s='%25E4%25B8%25AD'; print(s.count('%25'))"        # 1 表示还有一层
# 修复:按实际层数逐层还原,而不是不管层数统一解一次
python -c "import urllib.parse as u; print(u.unquote(u.unquote('%25E4%25B8%25AD')))"   # 中文

层数与处置

外观层数处置
中文0无需处理
%E4%B8%AD1解码一次即可
%25E4%25B8%25AD2解码两次;同时检查编码环节
%2525E4%2525B8%2525AD3 以上按层数循环解码,并排查链路
部分可读部分仍编码不一致说明不同环节规则不同,需分段核对
修复要看「数据里存的是编码后的字符串」还是「展示层多解了一层」:前者要修数据,后者只需修显示逻辑。混淆这两种情况会把正确数据改成错误数据,动手前先用样本确认。
重复编码与安全过滤的顺序很关键:过滤器只解码一次、校验后仍残留编码内容,攻击者可能借此绕过规则。校验应对解码后的最终内容进行,并限制解码层数,防止无限解码造成资源消耗或绕过。
根治要落在链路上:确认框架是否自动编码、网关是否改写参数、脚本是否重复处理。只修数据不改链路,下一批数据很快又会被叠加编码,运维成本持续累积。

易错点

  • 不论层数统一解码一次:双层内容解出仍是编码串,被误判为数据损坏 → 先判断层数再逐层还原
  • 在已编码内容上再次编码:长度成倍膨胀,日志与索引失效 → 明确编码责任方,避免重复处理
  • 只修数据不改链路:问题周期性复现 → 定位并消除重复编码的环节
  • 用字符串比较判断参数正确性:编码层数差异导致比较失败 → 解码后再比较
  • 无限制循环解码:恶意输入造成资源消耗 → 限定解码层数并对结果做校验

数据来源与参考

  • RFC 3986:百分号编码与转义字符处理
  • OWASP:双重编码绕过与输入规范化建议
  • WHATWG URL 标准:查询串解析行为

整理校对:其其网ICT文档中心 · 本页地址:docs.qiqicto.com/regex/url-double-encoding-debug.html

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​​‌‌‌​‌‌​​‌​‌​‌‌‌‌​​​​​‌​‌‌‌‌​‌‌‌​‌​‌​‌‌‌​​‌​​‌‌​‌‌​​​​‌​‌‌​‌​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌‌​‌​‌​‌‌​​​‌​​‌‌​‌‌​​​‌‌​​‌​‌​​‌​‌‌​‌​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​​‌​​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌‌‌​​‌​‌‌​‌​‌‌​​‌​​​‌‌​​‌​‌​‌‌​​​‌​​‌‌‌​‌​‌​‌‌​​‌‌‌​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​