T09 · Insecure Skill Coding Practices
- Location
scripts/bitaxe_status.py:70- Finding
Unrestricted Network Destination Enables Server-Side Request Forgery
- Content
View full analysis
dict: """Fetch system info from Bitaxe Gamma API.""" url = f"http://{ip}/api/system/info" try: with urllib.request.urlopen(url, timeout=10) as response: return json.loads(response.read().decode('utf-8')) except urllib.error.URLError as e: raise ConnectionError(f"Failed to connect to Bitaxe at {ip}: {e}") except json.JSONDecodeError as e: raise ValueError(f"Invalid JSON response: {e}") ``` The destination is obtained from a command-line argument, configuration file, or environment variable and passed directly to the network function: ```python # Determine which IP to use (priority: arg > config file > env var) ip = args.ip if not ip: ip = get_saved_ip() if not ip: parser.error( "No IP provided. Either:\n" " - Pass IP as argument: bitaxe_status.py \n" " - Save IP to config: bitaxe_status.py --set-ip \n" " - Set BITAXE_IP environment variable" ) source = "config file" if load_config().get('bitaxe_ip') else "environment variable" print(f"📡 Using Bitaxe IP from {source}: {ip}\n") # Fetch and display status try: data = fetch_bitaxe_status(ip) if args.format == "json": print(json.dumps(data, indent=2)) else: print(format_text(data)) ``` ### Technical Analysis Although the variable is described as an IP address, no validation ensures that it is an IP literal, belongs to an approved private subnet, or identifies a Bitaxe device. The value is interpolated directly into an HTTP URL and passed to `urllib.request.urlopen()`. Consequently, anyone able to ...[truncated 2630 chars]- Remediation
View remediation
