T09 · Insecure Skill Coding Practices
- Location
scripts/instagram_analyzer.py:128- Finding
Unrestricted Browser Navigation Enables Server-Side Request Forgery
- Content
View full analysis
dict: """Analyze a single Instagram post/Reel""" result = { "url": post_url, "post_type": "reel" if "/reel/" in post_url else "post", "username": "", "metrics": {}, "ratios": {}, "timing": {}, "error": None, "timestamp": datetime.utcnow().isoformat() } print(f"📊 Analyzing: {post_url}") with sync_playwright() as p: browser = p.chromium.launch(headless=self.config["scraper"]["headless"]) context = browser.new_context( user_agent=self.config["browser"]["user_agent"], viewport={"width": 390, "height": 844} ) page = context.new_page() try: page.goto(post_url, timeout=self.config["scraper"]["timeout"]) ``` ### Technical Analysis The `post_url` argument is controlled by the caller and is passed directly to Playwright's `page.goto()` method. The implementation does not validate the URL scheme, hostname, port, resolved IP address, or redirect destination. Although the command is documented as accepting Instagram post URLs, no code enforces that restriction. A caller can therefore direct Chromium to HTTP services available from the Skill's execution environment, including localhost, private network addresses, link-local services, or arbitrary external websites. Using a browser rather than a basic HTTP client does not prevent SSRF. Chromium still issues requests with the network access available to the host process and may follow redirects to otherwise prohibited destinations. ### Attack Path 1. An attacker invokes `analyze-post` with a URL that targets an internal service rather than Instagram. 2. ` ...[truncated 878 chars]- Remediation
View remediation
