T09 · Insecure Skill Coding Practices
- Location
scripts/extract_with_scrapling.py:65- Finding
Unrestricted URL Fetching Enables Server-Side Request Forgery
- Content
View full analysis
Vulnerability Details
File Location:
scripts/extract_with_scrapling.py, lines 65-81
Vulnerability Type: Server-Side Request Forgery through insufficient URL validation
Risk Level: HighVulnerable Code
python def _fetch_url(url: str, fetcher_type: str, timeout: int) -> Any: try: if fetcher_type == "dynamic": from scrapling.fetchers import DynamicFetcher # type: ignore log.info("Fetching with DynamicFetcher: %s", url) page = DynamicFetcher().fetch(url, timeout=timeout * 1000) elif fetcher_type == "stealthy": from scrapling.fetchers import StealthyFetcher # type: ignore log.info("Fetching with StealthyFetcher: %s", url) page = StealthyFetcher().fetch(url, timeout=timeout * 1000) else: from scrapling.fetchers import Fetcher # type: ignore log.info("Fetching with Fetcher (auto_match): %s", url) page = Fetcher.auto_match(url, auto_save=True, disable_adaptive=False)The URL originates from the command-line interface without validation:
python source.add_argument("--url", help="HTTP(S) URL to fetch with Scrapling Fetcher.")python if args.url: page = _fetch_url(args.url, args.fetcher, args.timeout)Technical Analysis
The helper passes a caller-controlled URL directly to static, dynamic, or stealth browser fetchers. It does not parse the URL, enforce the advertised HTTP or HTTPS schemes, resolve and validate the destination address, restrict destination hosts, or reject loopback, private, link-local, reserved, and cloud metadata address ranges.
The implementation also does not demonstrate validation of redirect destinations. Consequently, validating only the initial hostname outside this helper would not be sufficient: an attacker-controlled public URL could redirect the fetcher to a prohibited internal destinatio ...[truncated 1544 chars]
- Remediation
View remediation
Remediation Suggestions
- Parse every URL with a strict URL parser and allow only
httpandhttps. - Require an explicit allowlist of permitted hostnames when the intended targets are known.
- Resolve all destination hostnames before connecting and reject every resolved loopback, private, link-local, multicast, unspecified, reserved, and documentation address.
- Revalidate DNS results at connection time to reduce DNS-rebinding exposure.
- Disable redirects by default or validate the scheme, hostname, and resolved addresses at every redirect hop.
- Apply the same policy to requests initiated by dynamic or stealth browser pages, including subresources and JavaScript-generated requests.
- Block sensitive destinations at the network layer through egress firewall rules in addition to application validation.
- Run the scraper in an isolated container or network namespace without access to cloud metadata endpoints, control planes, or private administrative networks.
- Set request-size, response-size, timeout, and redirect-count limits to reduce resource-exhaustion risks.
- Add tests covering IPv4 and IPv6 loopback addresses, private ranges, encoded IP forms, DNS rebinding, mixed-scheme URLs, user-info parsing, and public-to-private redirects.
- Parse every URL with a strict URL parser and allow only
