paramspider_mining
Extract URL parameters from web archives using ParamSpider to identify potential attack surfaces for bug bounty reconnaissance and security testing.
Instructions
Execute ParamSpider for parameter mining from web archives with enhanced logging.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| additional_args | No | ||
| domain | Yes | ||
| exclude | No | png,jpg,gif,jpeg,swf,woff,svg,pdf,css,ico | |
| level | No | ||
| output | No |
Implementation Reference
- src/mcp_server/app.py:879-904 (handler)MCP handler function for the 'paramspider_mining' tool. Proxies parameters to the REST API endpoint '/api/paramspider-mining' for execution.@mcp.tool() def paramspider_mining( domain: str, level: int = 2, exclude: str = "png,jpg,gif,jpeg,swf,woff,svg,pdf,css,ico", output: str = "", additional_args: str = "", ) -> dict[str, Any]: """Run ParamSpider to mine parameters from archives with logging.""" data = { "domain": domain, "level": level, "exclude": exclude, "output": output, "additional_args": additional_args, } logger.info(f"🕸️ Starting ParamSpider parameter mining for {domain}") result = api_client.safe_post("api/paramspider-mining", data) if result.get("success"): logger.info(f"✅ ParamSpider mining completed for {domain}") else: logger.error("❌ ParamSpider mining failed") return result
- Backend handler that executes the actual ParamSpider command, parses output, and structures findings.@tool(required_fields=["domain"]) def execute_paramspider(): """Execute ParamSpider for parameter mining from web archives.""" data = request.get_json() params = extract_paramspider_params(data) started_at = datetime.now() command = build_paramspider_command(params) execution_result = execute_command( " ".join(command), timeout=params.get("timeout", 600) ) ended_at = datetime.now() return parse_paramspider_output( execution_result, params, command, started_at, ended_at )
- Helper to extract and normalize parameters for ParamSpider execution.def extract_paramspider_params(data: dict) -> dict: """Extract and organize paramspider parameters from request data.""" # Extract domain from URL if provided domain = data.get("domain", data.get("url", "")) if domain.startswith("http"): parsed = urlparse(domain) domain = parsed.netloc return { "domain": domain, "stream": data.get("stream", True), "placeholder": data.get("placeholder", "FUZZ"), "proxy": data.get("proxy", ""), "exclude": data.get("exclude", []), "output": data.get("output", ""), "level": data.get("level", 1), "subs": data.get("subs", False), "silent": data.get("silent", False), "clean": data.get("clean", False), "aggressive": data.get("aggressive", False), "additional_args": data.get("additional_args", ""), "timeout": data.get("timeout", 600), }
- Helper to construct the ParamSpider CLI command from processed parameters.def build_paramspider_command(params: dict) -> list[str]: """Build the paramspider command from parameters.""" args = ["paramspider", "-d", params["domain"]] # Add stream mode (-s flag) for real-time output if params["stream"]: args.append("-s") # Add placeholder for parameter values if params["placeholder"] and params["placeholder"] != "FUZZ": args.extend(["-p", params["placeholder"]]) # Add proxy if specified if params["proxy"]: args.extend(["--proxy", params["proxy"]]) # Add level (recursion depth) if params["level"] > 1: args.extend(["-l", str(params["level"])]) # Add subdomain inclusion if params["subs"]: args.append("--subs") # Add exclude patterns exclude = params.get("exclude", []) if exclude: if isinstance(exclude, list): exclude_str = " ".join(exclude) else: exclude_str = str(exclude).strip() if exclude_str: args.extend(["--exclude", exclude_str]) # Add output file if params["output"]: args.extend(["-o", params["output"]]) # Add silent mode if params["silent"]: args.append("--silent") # Add any additional arguments if params["additional_args"]: args.extend(params["additional_args"].split()) return args
- Helper to parse ParamSpider output into structured findings with timings and stats.def parse_paramspider_output( execution_result: dict[str, Any], params: dict, command: list[str], started_at: datetime, ended_at: datetime, ) -> dict[str, Any]: """Parse paramspider execution results into structured findings.""" duration_ms = int((ended_at - started_at).total_seconds() * 1000) if not execution_result["success"]: return { "success": False, "tool": "paramspider", "params": params, "command": command, "started_at": started_at.isoformat(), "ended_at": ended_at.isoformat(), "duration_ms": duration_ms, "error": execution_result.get("error", "Command execution failed"), "findings": [], "stats": {"findings": 0, "dupes": 0, "payload_bytes": 0}, } # Parse successful output stdout = execution_result.get("stdout", "") findings = [] # Extract parameters from paramspider output for line in stdout.strip().split("\n"): line = line.strip() if not line: continue # Parse parameter findings param_info = _extract_parameter_from_line(line) if param_info: finding = { "type": "parameter", "target": param_info.get("target", params["domain"]), "evidence": { "raw_output": line, "parameter_name": param_info.get("parameter_name"), "url": param_info.get("url"), }, "severity": "info", "confidence": "medium", "tags": ["paramspider", "parameter-discovery"], "raw_ref": line, } findings.append(finding) payload_bytes = len(stdout.encode("utf-8")) return { "success": True, "tool": "paramspider", "params": params, "command": command, "started_at": started_at.isoformat(), "ended_at": ended_at.isoformat(), "duration_ms": duration_ms, "findings": findings, "stats": { "findings": len(findings), "dupes": 0, "payload_bytes": payload_bytes, }, }