agentleFS
SirGuanZzSirGuanZz/claude-skills/url-decode/SKILL.md

url-decode

Skill2 starsChanged 2 months agoMITView on GitHub

解码任意 URL,列出协议 / 域名 / 路径 / 哈希路由 / 查询参数,并对每个参数逐项解码、识别嵌套 URL、JSON、Base64、时间戳等语义。 Use when the user says "解码 URL", "解 url", "解析这个链接", "分析这个 URL", "看看链接里参数", "URL 参数", "url 参数解码", "拆一下这个链接", or /url-decode. 默认只解析不改代码;结论以工具真实运行结果为准,不凭肉眼估算。

The file

Files
SKILL.md

url-decode: URL 解码与参数拆解

职责:把用户丢过来的一段 URL(可能被 encodeURIComponent 编码过、可能是 hash 路由、可能嵌套另一段 URL)拆开成结构化信息,清楚回答:

  • 这个 URL 的协议 / 主机 / 端口 / 路径 / hash / query 分别是什么?
  • 每个参数的原始值、解码后值、可能的语义(嵌套 URL / JSON / Base64 / JWT / 时间戳 / 逗号列表)?
  • 有没有异常(重复参数、非法编码、被截断、明显敏感字段)?

核心纪律:用工具真实解析,不肉眼估算。 用 Python urllib.parse(优先)或 Node URL API 走一遍再报结果。


启动:先拿到 URL

1. 用户已直接贴 URL

直接进入解析。如果贴的是长 URL,不要复述整串,直接给结果。

2. 用户只说「解析下这个链接」但没贴内容

只问一次:让用户把 URL 贴过来。不要问额外偏好(是否递归、是否解 Base64 等),这些默认全开。

3. 输入可能的形态

进入分析前,先识别:

形态特征处理
普通 URLhttps://a.com/p?x=1&y=2直接 urlparse + parse_qsl
Hash 路由https://a.com/#/detail?id=1(Vue Router / React Router hash 模式)先取 fragment,再对 fragment 内部当作 path?query 二次解析
被 encodeURIComponent 包过https%3A%2F%2Fa.com%2F%3Fx%3D1 或整段全是 %先 unquote 一次再当 URL 解
双重 / 多重编码%2525 之类递归 unquote,直到内容不再变化,最多 5 层,超过则报警
嵌套 URL参数值是 https%3A%2F%2F...递归调用本流程解析该值
只有 query 片段a=1&b=2 开头没有 ? 或 scheme允许,直接当 querystring 解析

解析步骤(用工具跑,不要口算)

1. 优先用 Python(内置库,零依赖)

用 Bash 起一个 python3 -c 或写临时脚本,基础模板:

from urllib.parse import urlparse, parse_qsl, unquote, unquote_plus
import base64, json, re, sys, time

url = sys.argv[1]

# 1. 递归 unquote 直到不变(最多 5 层)
def deep_unquote(s, limit=5):
    for _ in range(limit):
        d = unquote(s)
        if d == s:
            return s
        s = d
    return s

# 2. 拆结构
p = urlparse(url)
# 3. 拆 query(保留重复 key)
params = parse_qsl(p.query, keep_blank_values=True)
# 4. hash 路由:如果 fragment 里带 ?,再拆一次
frag = p.fragment
frag_path, frag_params = frag, []
if '?' in frag:
    frag_path, frag_q = frag.split('?', 1)
    frag_params = parse_qsl(frag_q, keep_blank_values=True)

2. 每个参数值的语义识别

对拿到的每个 value,按顺序探测,命中一个就停:

  1. 嵌套 URL:decoded 值以 http:// / https:// / // 开头 → 标记 nested-url,递归解析
  2. JSON:decoded 值以 { 或 [ 开头且能 json.loads → 标记 json,展开或 pretty print
  3. JWT:decoded 值符合 ^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]*$ → 拆三段,base64url 解 header/payload,不校验签名
  4. Base64:decoded 值长度 % 4 == 0 且只含 base64 字符集,且解出来是可打印文本或有效 JSON → 标记 base64,展开解出内容
  5. 时间戳:decoded 值是 10 位或 13 位纯数字,且落在 2000~2100 年区间 → 标记 timestamp,输出对应 UTC / 本地时间
  6. 逗号分隔列表:decoded 值含 , 且不含空格换行 → 标记 csv,拆成数组
  7. 纯数字 / 布尔 / 空:标记类型即可
  8. 其它:标记 string

不要过度识别 —— 一个短字符串强行解 Base64 常常"成功"但内容是乱码,加一个可打印字符占比阈值(>= 95% 可打印才认)。

3. 敏感字段扫描

如果参数名匹配以下(不区分大小写),额外加提示 ⚠️ 疑似敏感,注意脱敏后再分享:

token, access_token, refresh_token, id_token, session, sessionid, sid, auth, authorization, secret, password, pwd, passwd, apikey, api_key, signature, sign, code(OAuth 授权码)

不要在最终输出里裁剪或替换值 —— 用户是自己在调试,替换掉反而没法排查。只加标签提醒。


输出格式(固定)

先给结构总览,再给参数表,最后给发现的问题清单。

1. 结构总览

URL: <原始 URL,如果太长可以在中间用 … 省略,但保留 scheme+host 和 path 头尾>

Scheme:    https
Host:      lanhuapp.com
Port:      (默认)
Path:      /web/
Fragment:  #/item/project/product?tid=xxx&pid=xxx&docId=xxx

Fragment 里如果含 ?,再列一个 Fragment path 和 Fragment query。

2. 参数表

用 Markdown 表格,列固定为:参数名 / 原始值 / 解码值 / 类型 / 说明。

  • 「原始值」保留 URL 里出现的样子(还没 unquote)
  • 「解码值」是 deep unquote 后的结果
  • 「类型」:string / int / bool / timestamp / json / nested-url / base64 / jwt / csv
  • 「说明」:识别后的补充信息(时间戳解出的日期、JSON 展开、嵌套 URL 的主机、⚠️ 敏感字段提醒等)

原始值 / 解码值超过 80 字符时,用行内 code 折叠展示,并在「说明」里给出完整解码。

嵌套 URL 单独在参数表下方展开子表,标题写「└─ 参数 foo 的嵌套 URL:...」,格式和主表一致,可再嵌套。

3. 观察 / 问题清单

只在有内容时才输出这段。举例:

  • ⚠️ 有 2 个 id 参数,值分别是 1 和 2 —— 浏览器 / 后端行为不确定
  • ⚠️ token 疑似敏感,分享前脱敏
  • ⚠️ expires 是 2024-05-01 的时间戳,已过期
  • ⚠️ 检测到 3 层嵌套编码,可能是转发链路 / 重定向
  • ⚠️ 参数 q 值末尾像被截断(非法百分号编码 %2)

边界情况

  • 空参数值:a=&b=1 → a 的解码值是空字符串,类型 string,不要跳过。
  • 重复 key:同名参数出现多次,表格里列多行,说明 里标 重复 #1 / #2。
  • 参数名被编码:%E4%B8%AD%E6%96%87=1 → 参数名列也要 unquote。
  • 非 UTF-8 编码:先按 UTF-8 试,失败 fallback GBK,再失败保留 raw bytes 并在说明里标注。
  • URL 里有空格:先尝试当作 +(application/x-www-form-urlencoded 场景),再尝试 %20。
  • fragment 有多个 ?:只按第一个 ? 切,后面全部当 query 字符串。
  • hash 里嵌套 hash:极少见,不特殊处理,输出提示即可。
  • 只有 querystring 没 scheme:允许当 ? 后半段解析,Scheme/Host/Path 一列写「无」。
  • 明显非 URL(纯文本 / 纯数字 / JSON)**:不硬解,直接告诉用户「这个看起来不是 URL,你是想要 XX 吗?」。

拒绝什么

  • 不要修改用户的代码 / 文件:本 skill 只输出分析结果。
  • 不要请求 URL:纯静态解析,不发网络请求确认可达性。
  • 不要校验 JWT 签名 / 不要解 API 服务端加密:超出静态解码范畴,只解可解的编码层。
  • 不要"美化"敏感值:保留原样 + 加标签提醒,让用户自己决定要不要分享。

示例(参考,不是模板)

输入:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx123&redirect_uri=https%3A%2F%2Fmy.com%2Fcb%3Fstate%3Dabc%26t%3D1719999999&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect

期望输出结构(简化):

URL: https://open.weixin.qq.com/connect/oauth2/authorize?...#wechat_redirect

Scheme:    https
Host:      open.weixin.qq.com
Path:      /connect/oauth2/authorize
Fragment:  wechat_redirect

Query 参数:

| 参数名 | 原始值 | 解码值 | 类型 | 说明 |
|--------|--------|--------|------|------|
| appid | wx123 | wx123 | string | 微信 AppID |
| redirect_uri | https%3A%2F%2Fmy.com%2Fcb%3F... | https://my.com/cb?state=abc&t=1719999999 | nested-url | 见下方展开 |
| response_type | code | code | string | OAuth authorization code 流程,⚠️ code 属敏感 |
| scope | snsapi_userinfo | snsapi_userinfo | string | 微信 OAuth scope |
| state | STATE | STATE | string | 占位值,未替换 |

└─ 参数 `redirect_uri` 的嵌套 URL:https://my.com/cb?state=abc&t=1719999999

| 参数名 | 原始值 | 解码值 | 类型 | 说明 |
|--------|--------|--------|------|------|
| state | abc | abc | string | |
| t | 1719999999 | 1719999999 | timestamp | 2024-07-03 12:26:39 UTC |

观察:
- redirect_uri 嵌套的 `t` 参数是过去时间戳(2024-07),如果是有效期字段可能已过期

输出风格

  • 中文回复;不要复述用户贴过来的原 URL 一遍再解释,直接给结果。
  • 表格宽度控制:值超过 80 字符折叠 + 说明里给完整值。
  • 不需要总结「刚做了什么」,输出就是结果。

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.