T09 · Insecure Skill Coding Practices
- Location
- scripts/fb-group-monitor.py:363
- Finding
- Unrestricted Browser Navigation with Chromium Sandbox Disabled<![CDATA[ ## Vulnerability Details **File Location**: `scripts/fb-group-monitor.py:55-59, 224-233, 363-380` **Vulnerability Type**: Browser-based server-side request forgery and unsafe browser configuration **Risk Level**: High ### Vulnerable Code ```python BROWSER_ARGS = [ "--disable-blink-features=AutomationControlled", "--no-sandbox", "--disable-dev-shm-usage", ] ``` ```python context = await p.chromium.launch_persistent_context( user_data_dir=str(BROWSER_DATA), headless=headless, viewport={"width": 1280, "height": 900}, user_agent=USER_AGENT, args=BROWSER_ARGS, ignore_default_args=["--enable-automation"], locale="vi-VN", timezone_id="Asia/Ho_Chi_Minh", ) ``` ```python group_url = args.group_url limit = args.limit take_screenshots = not args.no_shots shots_dir = Path(args.shots_dir).expanduser() shots_dir.mkdir(parents=True, exist_ok=True) if not group_url.startswith("http"): group_url = f"https://www.facebook.com/groups/{group_url}" if take_screenshots: cleanup_screenshots(shots_dir) async with async_playwright() as p: context, stealth_fn = await create_browser_context(p, headless=True) page = context.pages[0] if context.pages else await context.new_page() if stealth_fn: await stealth_fn(page) try: await page.goto(group_url, wait_until="domcontentloaded") ``` ### Technical Analysis The `group_url` validation only tests whether the supplied string begins with `http`. It does not enforce HTTPS, an approved Facebook hostname, or a Facebook group path. Consequently, any attacker who can influence the command argument can direct the browser to arbitrary public, loopback, link-local, or private-network destinations. The screenshot routine falls back to capturing the full viewport when no Facebook feed element exists. Therefore, content returned by a non-Facebook endpoint may be written to a screenshot even when post extraction fails. Navigation may also trigger state-c ...[truncated 1914 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Parse URLs with `urllib.parse.urlsplit` rather than testing string prefixes. 2. Require the `https` scheme. 3. Allow only exact approved hostnames, such as `www.facebook.com`, rather than suffix or substring matching. 4. Require the path to begin with `/groups/` and reject embedded credentials and unexpected ports. 5. Resolve the destination and reject loopback, private, link-local, multicast, reserved, and unspecified IP addresses. 6. Validate every redirect target before following it. 7. Remove `--no-sandbox` and run Chromium as a non-root user with its normal sandbox enabled. 8. If disabling the browser sandbox is operationally unavoidable, place the entire process in a separately hardened container with restricted filesystem mounts, network egress controls, dropped Linux capabilities, and no access to host services. 9. Consider using a fresh context for scraping and storing only the minimum authentication state required for Facebook. ]]>
