T09 · Insecure Skill Coding Practices
- Location
scripts/monitor_feishu_price_table.py:31- Finding
Unrestricted User-Supplied URL Fetching Enables SSRF
- Content
View full analysis
Vulnerability Details
File Location:
scripts/monitor_feishu_price_table.py, lines 31–36, 184–187, 192–201, and 497–508
Vulnerability Type: Server-Side Request Forgery through insufficient URL and redirect validation
Risk Level: MediumVulnerable Code
python resp = http.get( url, timeout=30, headers={"User-Agent": USER_AGENT}, allow_redirects=True, )python def client_vars_api_url(page_url: str) -> str: parsed = urlparse(page_url) if not parsed.scheme or not parsed.netloc: raise RuntimeError("飞书链接格式不正确,无法构造分页接口") return f"{parsed.scheme}://{parsed.netloc}/space/api/docx/pages/client_vars"python resp = session.get( client_vars_api_url(page_url), params=query, timeout=30, headers={ "User-Agent": USER_AGENT, "Accept": "application/json, text/plain, */*", "Referer": page_url, }, )python parser.add_argument("url") parser.add_argument("--section-title", default=DEFAULT_SECTION_TITLE) parser.add_argument( "--state-dir", default=str( Path.home() / ".openclaw" / "workspace" / "data" / "feishu-monitors" ), ) parser.add_argument("--print-snapshot", action="store_true") args = parser.parse_args() state_dir = Path(args.state_dir) state_dir.mkdir(parents=True, exist_ok=True) key = hashlib.sha256( (args.url + "\0" + args.section_title).encode("utf-8") ).hexdigest()[:16] state_path = state_dir / f"{key}.json" snapshot = snapshot_from_url(args.url, args.section_title)Technical Analysis
The positional
urlargument is passed directly into the HTTP request. Validation only checks that the parsed URL contains a scheme and network location. It does not:- Require HTTPS.
- Restrict destinations to legitimate Feishu or Lark domains.
- Reject loopback, private, link-local, reserved, or cloud metadata IP addresses.
- Reject embedded credentials or unexpected ports.
- Validate the IP addr ...[truncated 2546 chars]
- Remediation
View remediation
Remediation Suggestions
-
Enforce an HTTPS-only policy
- Reject every URL whose normalized scheme is not exactly
https.
- Reject every URL whose normalized scheme is not exactly
-
Allowlist supported domains
- Permit only explicitly supported Feishu and Lark hostnames or carefully validated domain suffixes.
- Compare normalized hostnames, not raw URL strings.
- Ensure suffix checks require a label boundary so domains such as
feishu.cn.attacker.examplecannot pass.
-
Block internal and special-purpose addresses
- Resolve all destination hostnames before connecting.
- Reject every resolved address that is loopback, private, link-local, multicast, unspecified, reserved, or otherwise non-global.
- Apply the check to both IPv4 and IPv6 addresses.
-
Harden redirect handling
- Disable automatic redirects and process redirects manually.
- Reapply scheme, hostname, port, and resolved-IP validation to every redirect destination before following it.
- Set a small redirect limit.
-
Reduce DNS-rebinding exposure
- Ensure the address validated is the address used for the connection where practical.
- Revalidate DNS results immediately before every network request.
-
Restrict URL authority components
- Reject embedded usernames and passwords.
- Permit only expected ports, normally TCP 443.
- Reject malformed or ambiguous host encodings.
-
Minimize Referer disclosure
- Do not send the complete input URL as the
Refererif it may contain query parameters or fragments. - Construct a sanitized Referer containing only the validated scheme, host, and safe path when the endpoint requires it.
- Do not send the complete input URL as the
-
Apply the same policy consistently
- Use one centralized URL validation routine for the initial document request, redirects, and pagination requests.
- Verify that the derived pagination endpoint remains on the validated Feishu/Lark origin.
-
