Mostly safe — a couple of notes worth reading.
Scanned 5/3/2026, 6:43:59 PM·Cached result·Fast Scan·45 rules·How we decide ↗
AIVSS Score
Low
Severity Breakdown
0
critical
0
high
38
medium
43
low
MCP Server Information
Findings
This package earns a B grade with a safety score of 68/100, driven primarily by 38 medium-severity issues concentrated in readiness and verbose error handling rather than exploitable vulnerabilities. The 43 low-severity findings suggest the server lacks some hardening practices and may expose unnecessary diagnostic information, but no critical or high-severity flaws were detected. Installation is reasonably safe if you're comfortable with moderate operational and information disclosure risks.
No known CVEs found for this package or its dependencies.
Scan Details
Want deeper analysis?
Fast scan found 81 findings using rule-based analysis. Upgrade for LLM consensus across 5 judges, AI-generated remediation, and cross-file taint analysis.
Building your own MCP server?
Same rules, same LLM judges, same grade. Private scans stay isolated to your account and never appear in the public registry. Required for code your team hasn’t shipped yet.
Showing 1–30 of 81 findings
81 findings
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 772 | pass |
| 773 | return result |
| 774 | except Exception as e: |
| 775 | return {"addr": addr, "code": None, "error": str(e)} |
| 776 | |
| 777 | |
| 778 | @tool |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 1223 | try: |
| 1224 | session = _require_supervisor().resolve_session(None) |
| 1225 | except Exception as e: |
| 1226 | return _jsonrpc_error(request_obj.get("id"), -32001, str(e)) |
| 1227 | return _require_supervisor().forward_raw(session, request_obj) |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 1985 | start_ea = parse_address(start_s) |
| 1986 | end_ea = parse_address(end_s) if end_s is not None else None |
| 1987 | except Exception as e: |
| 1988 | return [], str(e) |
| 1989 | |
| 1990 | if not exec_segments: |
| 1991 | return [], "No executable segments found" |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 1076 | return {**result, **sup.context_fields(context_id)} |
| 1077 | return {"ready": False, **sup.context_fields(context_id), "session": None, "health": None, "error": "Unexpected health result"} |
| 1078 | except Exception as e: |
| 1079 | return {"ready": False, "error": str(e)} |
| 1080 | |
| 1081 | |
| 1082 | @mcp.tool |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 971 | "message": f"Bound context to session: {session.session_id} ({session.filename})", |
| 972 | } |
| 973 | except Exception as e: |
| 974 | return {"error": str(e)} |
| 975 | |
| 976 | |
| 977 | @mcp.tool |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 228 | ), |
| 229 | } |
| 230 | except (FileNotFoundError, RuntimeError, ValueError) as e: |
| 231 | return {"error": str(e)} |
| 232 | except Exception as e: |
| 233 | return {"error": f"Unexpected error: {e}"} |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 474 | "error": None, |
| 475 | } |
| 476 | except Exception as e: |
| 477 | return {"ready": False, "error": str(e)} |
| 478 | |
| 479 | |
| 480 | def main(): |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 1123 | return {**result, **sup.context_fields(context_id)} |
| 1124 | return {"ready": False, **sup.context_fields(context_id), "session": None, "warmup": None, "error": "Unexpected warmup result"} |
| 1125 | except Exception as e: |
| 1126 | return {"ready": False, "error": str(e)} |
| 1127 | |
| 1128 | |
| 1129 | @mcp.resource("ida://databases") |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 566 | try: |
| 567 | start_ea = _resolve_addr(addr) |
| 568 | except IDAError as exc: |
| 569 | return {"error": str(exc)} |
| 570 | |
| 571 | if max_depth < 1: |
| 572 | max_depth = 1 |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 426 | "error": None, |
| 427 | } |
| 428 | except Exception as e: |
| 429 | return {"ready": False, "error": str(e)} |
| 430 | |
| 431 | |
| 432 | @tool |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 1166 | try: |
| 1167 | return sup.forward_raw(session, forwarded) |
| 1168 | except Exception as e: |
| 1169 | return _jsonrpc_result(request_id, _call_tool_result({"error": str(e)}, is_error=True)) |
| 1170 | |
| 1171 | |
| 1172 | def _handle_resources_list(request_obj: dict[str, Any]) -> dict[str, Any]: |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 1002 | return {"edit": edit, "kind": kind, "error": f"Unknown kind: {kind}"} |
| 1003 | except Exception as e: |
| 1004 | return {"edit": edit, "error": str(e)} |
| 1005 | |
| 1006 | |
| 1007 | @tool |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 1970 | return [], f"Function not found at {func_addr}" |
| 1971 | return [(func.start_ea, func.end_ea)], None |
| 1972 | except Exception as e: |
| 1973 | return [], str(e) |
| 1974 | |
| 1975 | if segment_name is not None: |
| 1976 | for seg in exec_segments: |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 1048 | return {**result, **sup.context_fields(context_id)} |
| 1049 | return {"ok": False, **sup.context_fields(context_id), "error": "Unexpected save result"} |
| 1050 | except Exception as e: |
| 1051 | return {"ok": False, "error": str(e)} |
| 1052 | |
| 1053 | |
| 1054 | @mcp.tool |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 470 | try: |
| 471 | ea = _resolve_addr(addr) |
| 472 | except IDAError as exc: |
| 473 | return {"error": str(exc)} |
| 474 | |
| 475 | func = idaapi.get_func(ea) |
| 476 | if func is None: |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 281 | try: |
| 282 | ea = _resolve_addr(addr) |
| 283 | except IDAError as exc: |
| 284 | return {"addr": addr, "error": str(exc)} |
| 285 | |
| 286 | return _analyze_function_internal(ea, include_asm=include_asm) |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 175 | logger.debug("[MCP] << %s (%.1fms) CANCELLED", method, elapsed_ms) |
| 176 | if is_notification: |
| 177 | return None |
| 178 | return self._error(request_id, -32800, str(e) or "Request cancelled") |
| 179 | except Exception as e: |
| 180 | elapsed_ms = (time.perf_counter() - start_time) * 1000 |
| 181 | if log_method: |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 1159 | try: |
| 1160 | session = sup.resolve_session(database) |
| 1161 | except Exception as e: |
| 1162 | return _jsonrpc_result(request_id, _call_tool_result({"error": str(e)}, is_error=True)) |
| 1163 | |
| 1164 | forwarded = copy.deepcopy(request_obj) |
| 1165 | forwarded.setdefault("params", {})["arguments"] = arguments |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 381 | "error": None if ok else "save_database returned false", |
| 382 | } |
| 383 | except Exception as e: |
| 384 | return {"ok": False, "error": str(e)} |
| 385 | |
| 386 | |
| 387 | @tool |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 529 | }, |
| 530 | ) |
| 531 | except Exception as e: |
| 532 | return {"success": False, "error": str(e)} |
| 533 | |
| 534 | if isinstance(result, dict): |
| 535 | if ( |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 267 | ), |
| 268 | } |
| 269 | except ValueError as e: |
| 270 | return {"error": str(e)} |
| 271 | except RuntimeError as e: |
| 272 | return {"error": f"Failed to switch session: {e}"} |
| 273 | except Exception as e: |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 121 | if not isinstance(request, dict): |
| 122 | return self._error(None, -32600, "Invalid request: must be a JSON object") |
| 123 | except Exception as e: |
| 124 | return self._error(None, -32700, "JSON parse error", str(e)) |
| 125 | |
| 126 | if request.get("jsonrpc") != "2.0": |
| 127 | return self._error(None, -32600, "Invalid request: 'jsonrpc' must be '2.0'") |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 941 | "message": f"Binary opened and bound to context: {session.filename} ({session.session_id})", |
| 942 | } |
| 943 | except Exception as e: |
| 944 | return {"error": str(e)} |
| 945 | |
| 946 | |
| 947 | @mcp.tool |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 1192 | session = sup.resolve_session(None) |
| 1193 | return sup.forward_raw(session, request_obj) |
| 1194 | except Exception as e: |
| 1195 | return _jsonrpc_error(request_obj.get("id"), -32001, str(e)) |
| 1196 | |
| 1197 | |
| 1198 | def dispatch_supervisor(request: dict | str | bytes | bytearray) -> dict | None: |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure — useful recon for attackers.
Evidence
| 847 | result["error"] = "save_database returned false" |
| 848 | return result |
| 849 | except Exception as e: |
| 850 | return {"ok": False, "path": path or None, "error": str(e)} |
| 851 | |
| 852 | |
| 853 | @tool |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 79 | class MakeSigResult(TypedDict): |
| 80 | query: str |
| 81 | addr: str | None |
| 82 | signature: str | None |
| 83 | format: str |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" — the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 421 | class Metadata(TypedDict): |
| 422 | path: str |
| 423 | module: str |
| 424 | base: str |
| 425 | size: str |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" — the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 44 | class GlobalValueResult(TypedDict): |
| 45 | query: str |
| 46 | value: str | None |
| 47 | error: NotRequired[str] |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" — the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 88 | class MakeSigForFunctionResult(TypedDict): |
| 89 | query: str |
| 90 | addr: str | None |
| 91 | name: str | None |
| 92 | signature: str | None |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" — the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 15 | class SurveyMetadata(TypedDict): |
| 16 | path: str |
| 17 | module: str |
| 18 | arch: str |
| 19 | base_address: str |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" — the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 71 | class LookupFuncResult(TypedDict): |
| 72 | query: str |
| 73 | fn: Function | None |
| 74 | error: str | None |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" — the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 92 | class IdalibSaveResult(IdalibContextFields, total=False): |
| 93 | ok: bool |
| 94 | path: str |
| 95 | error: str | None |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" — the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 97 | class XrefSigResult(TypedDict): |
| 98 | query: str |
| 99 | addr: str | None |
| 100 | signatures: list[dict] | None |
| 101 | total_xrefs: NotRequired[int] |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" — the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 155 | class IdalibSaveResult(IdalibContextFields, total=False): |
| 156 | ok: bool |
| 157 | path: str |
| 158 | error: str | None |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" — the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable — a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 43 | with: |
| 44 | ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.sha || github.sha }} |
| 45 | |
| 46 | - uses: astral-sh/setup-uv@v7 |
| 47 | |
| 48 | - name: Run tests |
| 49 | run: | |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version — Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable — a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 39 | username: ${{ github.repository_owner }} |
| 40 | password: ${{ secrets.GITHUB_TOKEN }} |
| 41 | steps: |
| 42 | - uses: actions/checkout@v6 |
| 43 | with: |
| 44 | ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.sha || github.sha }} |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version — Dependabot can do this automatically with `version-update-strategy: inc
MCP server uses `session_id` as the sole key for session-data lookup without binding it to a user identifier. The official MCP security best practices require keys to combine user_id + session_id (e.g. `<user_id>:<session_id>`) so a guessed/obtained session_id alone cannot impersonate another user. Fix: use a compound key in DDB (`Key={"user_id": user_id, "session_id": session_id}`), or build the key as `f"{user_id}:{session_id}"` for dict/cache/redis access. Sourced `user_id` MUST come from th
Evidence
| 816 | "No database bound for this context. Use idalib_open(...), " |
| 817 | "idalib_switch(session_id), or pass database=..." |
| 818 | ) |
| 819 | session = self.sessions.get(session_id) |
| 820 | if session is None: |
| 821 | raise RuntimeError(f"Session is stale or missing: {session_id}") |
| 822 | session.last_accessed = datetime.now() |
Remediation
Bind session IDs to user IDs in every key: # BAD ddb.get_item(Key={"session_id": session_id}) data = sessions[session_id] redis.get(session_id) # GOOD ddb.get_item(Key={"user_id": user_id, "session_id": session_id}) data = sessions[f"{user_id}:{session_id}"] redis.get(f"{user_id}:{session_id}") The user_id should come from the verified authorization token (JWT claim, validated session cookie) — never from a request parameter the user can choose.
MCP server uses `session_id` as the sole key for session-data lookup without binding it to a user identifier. The official MCP security best practices require keys to combine user_id + session_id (e.g. `<user_id>:<session_id>`) so a guessed/obtained session_id alone cannot impersonate another user. Fix: use a compound key in DDB (`Key={"user_id": user_id, "session_id": session_id}`), or build the key as `f"{user_id}:{session_id}"` for dict/cache/redis access. Sourced `user_id` MUST come from th
Evidence
| 658 | session_collision_error = None |
| 659 | if existing_session is None: |
| 660 | existing_by_id = self.sessions.get(session_id) |
| 661 | if existing_by_id is not None: |
| 662 | if existing_by_id.is_alive(): |
| 663 | existing_by_id.last_accessed = datetime.now() |
Remediation
Bind session IDs to user IDs in every key: # BAD ddb.get_item(Key={"session_id": session_id}) data = sessions[session_id] redis.get(session_id) # GOOD ddb.get_item(Key={"user_id": user_id, "session_id": session_id}) data = sessions[f"{user_id}:{session_id}"] redis.get(f"{user_id}:{session_id}") The user_id should come from the verified authorization token (JWT claim, validated session cookie) — never from a request parameter the user can choose.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 175 | try: |
| 176 | parsed = urlparse(f"//{authority}") |
| 177 | if parsed.hostname is not None and parsed.port is None: |
| 178 | return f"{authority}:{port}" |
| 179 | except ValueError: |
| 180 | pass |
| 181 | return authority |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 1325 | length=len(str_content), |
| 1326 | string=str_content.decode("utf-8", errors="replace"), |
| 1327 | ) |
| 1328 | ) |
| 1329 | except Exception: |
| 1330 | pass |
| 1331 | return strings |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 773 | # Fallback: try idc.get_type |
| 774 | try: |
| 775 | return idc.get_type(fn.start_ea) |
| 776 | except Exception: |
| 777 | pass |
| 778 | |
| 779 | return None |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 702 | raise Exception(f"Invalid transport URL: {args.transport}") |
| 703 | # NOTE: npx -y @modelcontextprotocol/inspector for debugging |
| 704 | mcp.serve(url.hostname, url.port, request_handler=ProxyHttpRequestHandler) |
| 705 | input("Server is running, press Enter or Ctrl+C to stop.") |
| 706 | except (KeyboardInterrupt, EOFError): |
| 707 | pass |
| 708 | |
| 709 | |
| 710 | if __name__ == "__main__": |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 126 | info: InstanceInfo = json.load(f) |
| 127 | except (json.JSONDecodeError, OSError): |
| 128 | try: |
| 129 | os.unlink(file_path) |
| 130 | except OSError: |
| 131 | pass |
| 132 | continue |
| 133 | |
| 134 | if not all(k in info for k in ("host", "port", "pid")): |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 310 | ] |
| 311 | if local_result and "result" in local_result: |
| 312 | local_tools = local_result["result"].get("tools", []) |
| 313 | local_result["result"]["tools"] = remote_tools + local_tools |
| 314 | except Exception: |
| 315 | pass # Remote unreachable, show local tools only |
| 316 | return local_result |
| 317 | |
| 318 | # Everything else (resources/list, etc.): proxy |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 184 | # sub_<hex> - IDA auto-named function |
| 185 | if q.startswith("sub_"): |
| 186 | try: |
| 187 | return int(q[4:], 16) |
| 188 | except ValueError: |
| 189 | pass |
| 190 | |
| 191 | return idaapi.BADADDR |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 140 | if not is_pid_alive(info["pid"]): |
| 141 | try: |
| 142 | os.unlink(file_path) |
| 143 | except OSError: |
| 144 | pass |
| 145 | continue |
| 146 | |
| 147 | # Secondary check: verify the instance is actually listening. |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 240 | _state["idb_hook"] = None |
| 241 | if hook is not None: |
| 242 | try: |
| 243 | hook.unhook() |
| 244 | except Exception: |
| 245 | pass |
| 246 | if idb_b is not None: |
| 247 | try: |
| 248 | idb_b.close() |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 515 | pass |
| 516 | try: |
| 517 | if tif.is_typedef(): |
| 518 | return "typedef" |
| 519 | except Exception: |
| 520 | pass |
| 521 | try: |
| 522 | if tif.is_func(): |
| 523 | return "func" |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 245 | pass |
| 246 | if idb_b is not None: |
| 247 | try: |
| 248 | idb_b.close() |
| 249 | except Exception: |
| 250 | pass |
| 251 | |
| 252 | |
| 253 | def iter_idb_records() -> Iterator[dict]: |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 358 | if local_result and "result" in local_result: |
| 359 | local_result["result"]["tools"] = ( |
| 360 | ida_tools + local_result["result"].get("tools", []) |
| 361 | ) |
| 362 | except Exception: |
| 363 | pass # IDA unreachable — local tools still work |
| 364 | return local_result |
| 365 | |
| 366 | try: |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 362 | """decompile raises IDAError for invalid address""" |
| 363 | try: |
| 364 | decompile("0xDEADBEEFDEADBEEF") |
| 365 | assert False, "Expected IDAError" |
| 366 | except IDAError: |
| 367 | pass # Expected |
| 368 | ``` |
| 369 | |
| 370 | ### 4. Referential Integrity |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 617 | ea = idaapi.get_name_ea(idaapi.BADADDR, addr.strip()) |
| 618 | if ea != idaapi.BADADDR: |
| 619 | return ea |
| 620 | except ImportError: |
| 621 | pass |
| 622 | for ch in addr: |
| 623 | if ch not in "0123456789abcdefABCDEF": |
| 624 | raise IDAError(f"Not found: {addr!r}") |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 133 | if not all(k in info for k in ("host", "port", "pid")): |
| 134 | try: |
| 135 | os.unlink(file_path) |
| 136 | except OSError: |
| 137 | pass |
| 138 | continue |
| 139 | |
| 140 | if not is_pid_alive(info["pid"]): |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 1146 | ds = dstr.split(": ") |
| 1147 | if len(ds) == 2: |
| 1148 | try: |
| 1149 | line_ea = int(ds[0], 16) |
| 1150 | except ValueError: |
| 1151 | pass |
| 1152 | text = compact_whitespace(ida_lines.tag_remove(sl.line)) |
| 1153 | if line_ea is not None: |
| 1154 | lines.append(f"{text} /*{line_ea:#x}*/") |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 520 | pass |
| 521 | try: |
| 522 | if tif.is_func(): |
| 523 | return "func" |
| 524 | except Exception: |
| 525 | pass |
| 526 | try: |
| 527 | if tif.is_ptr(): |
| 528 | return "ptr" |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 711 | if isinstance(parsed, dict): |
| 712 | return [parsed] |
| 713 | elif isinstance(parsed, list): |
| 714 | return parsed |
| 715 | except (json.JSONDecodeError, ValueError): |
| 716 | pass |
| 717 | |
| 718 | # Not JSON - split by comma and parse |
| 719 | parts = [s.strip() for s in value.split(",") if s.strip()] |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 525 | pass |
| 526 | try: |
| 527 | if tif.is_ptr(): |
| 528 | return "ptr" |
| 529 | except Exception: |
| 530 | pass |
| 531 | |
| 532 | try: |
| 533 | if tif.is_udt(): |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 534 | udt = ida_typeinf.udt_type_data_t() |
| 535 | if tif.get_udt_details(udt) and udt.is_union: |
| 536 | return "union" |
| 537 | return "struct" |
| 538 | except Exception: |
| 539 | pass |
| 540 | |
| 541 | return "other" |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 484 | if isinstance(parsed, dict): |
| 485 | method = parsed.get("method") |
| 486 | if isinstance(method, str): |
| 487 | request_method = method |
| 488 | except Exception: |
| 489 | pass |
| 490 | |
| 491 | mcp_session_id = self.headers.get("Mcp-Session-Id") |
| 492 | if request_method == "initialize": |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 333 | checker = getattr(ida_name, "has_user_name", None) |
| 334 | if checker is not None: |
| 335 | return checker(flags) |
| 336 | except Exception: |
| 337 | pass |
| 338 | return False |
| 339 | |
| 340 | def _set_name_checked(ea: int, new_name: str) -> tuple[bool, str | None]: |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 869 | try: |
| 870 | tif = ida_typeinf.tinfo_t(text, None, ida_typeinf.PT_SIL) |
| 871 | if tif.is_func(): |
| 872 | return tif |
| 873 | except Exception: |
| 874 | pass |
| 875 | |
| 876 | raise ValueError(f"Not a function type: {text}") |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 794 | frame_info["symbol"] = str(e) |
| 795 | |
| 796 | callstack.append(frame_info) |
| 797 | |
| 798 | except Exception: |
| 799 | pass |
| 800 | return callstack |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 177 | # 0x<hex> - direct address |
| 178 | if q.startswith("0x") or q.startswith("0X"): |
| 179 | try: |
| 180 | return int(q, 16) |
| 181 | except ValueError: |
| 182 | pass |
| 183 | |
| 184 | # sub_<hex> - IDA auto-named function |
| 185 | if q.startswith("sub_"): |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 680 | if tif.get_pointed_object(pointed): |
| 681 | rel_name = pointed.get_type_name() or str(pointed) |
| 682 | if rel_name: |
| 683 | related.add(rel_name) |
| 684 | except Exception: |
| 685 | pass |
| 686 | |
| 687 | related_list = sorted(related) |
| 688 | out["related_count"] = len(related_list) |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 767 | if cfunc: |
| 768 | refs = _collect_decompile_refs(cfunc) |
| 769 | if refs: |
| 770 | result["refs"] = refs |
| 771 | except Exception: |
| 772 | pass |
| 773 | return result |
| 774 | except Exception as e: |
| 775 | return {"addr": addr, "code": None, "error": str(e)} |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 839 | if not empty(): |
| 840 | return tif |
| 841 | else: |
| 842 | return tif |
| 843 | except Exception: |
| 844 | pass |
| 845 | |
| 846 | raise ValueError(f"Unable to parse type: {text}") |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 1852 | if more: |
| 1853 | break |
| 1854 | if more: |
| 1855 | break |
| 1856 | except Exception: |
| 1857 | pass |
| 1858 | |
| 1859 | results.append( |
| 1860 | { |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 1780 | ) |
| 1781 | more = next_ea != idaapi.BADADDR |
| 1782 | break |
| 1783 | ea += 1 |
| 1784 | except Exception: |
| 1785 | pass |
| 1786 | |
| 1787 | results.append( |
| 1788 | { |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 400 | sock = self.connection |
| 401 | if sock and hasattr(sock, "settimeout"): |
| 402 | try: |
| 403 | sock.settimeout(1.0) |
| 404 | except OSError: |
| 405 | pass |
| 406 | |
| 407 | last_ping = time.time() |
| 408 | while conn.alive and self.mcp_server._running: |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 510 | def _type_kind(tif: ida_typeinf.tinfo_t) -> str: |
| 511 | try: |
| 512 | if tif.is_enum(): |
| 513 | return "enum" |
| 514 | except Exception: |
| 515 | pass |
| 516 | try: |
| 517 | if tif.is_typedef(): |
| 518 | return "typedef" |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 894 | if ida_frame.get_func_frame(frame_tif, fn): |
| 895 | _, udm = tinfo_get_udm(frame_tif, str(edit["name"])) |
| 896 | if udm: |
| 897 | return "stack" |
| 898 | except Exception: |
| 899 | pass |
| 900 | |
| 901 | return "global" |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 283 | idb_b = _state["idb_backend"] |
| 284 | if idb_b is not None: |
| 285 | try: |
| 286 | idb_b.append(record) |
| 287 | except Exception: |
| 288 | pass |
| 289 | |
| 290 | |
| 291 | def install_tracer() -> None: |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 150 | # cases where the process is alive but the server crashed. |
| 151 | if not probe_instance(info["host"], info["port"], timeout=1.0): |
| 152 | try: |
| 153 | os.unlink(file_path) |
| 154 | except OSError: |
| 155 | pass |
| 156 | continue |
| 157 | |
| 158 | result.append(info) |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 270 | if rc: |
| 271 | return True |
| 272 | elif int(rc) > 0: |
| 273 | return True |
| 274 | except Exception: |
| 275 | pass |
| 276 | |
| 277 | # Fallback to ida_hexrays for very old IDA |
| 278 | if not IDA_GE_84 and ida_hexrays is not None: |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 201 | b = backend_ref.get("idb_backend") |
| 202 | if b is not None: |
| 203 | try: |
| 204 | b.flush() |
| 205 | except Exception: |
| 206 | pass |
| 207 | return 0 |
| 208 | |
| 209 | hook = _TraceFlushHook() |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 192 | b = backend_ref.get("idb_backend") |
| 193 | if b is not None: |
| 194 | try: |
| 195 | b.flush() |
| 196 | except Exception: |
| 197 | pass |
| 198 | return 0 |
| 199 | |
| 200 | def closebase(self, *args): |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 548 | if raw: |
| 549 | codec = _STR_CODECS.get(strtype & 3, "utf-8") |
| 550 | try: |
| 551 | info["string"] = raw.decode(codec, errors="replace") |
| 552 | except Exception: |
| 553 | pass |
| 554 | return info |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 278 | if not IDA_GE_84 and ida_hexrays is not None: |
| 279 | try: |
| 280 | if ida_hexrays.init_hexrays_plugin() and ida_hexrays.guess_tinfo(tif, ea): |
| 281 | return True |
| 282 | except Exception: |
| 283 | pass |
| 284 | |
| 285 | return False |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 298 | # a str, we try to parse it as JSON first. |
| 299 | if type(str) not in args and isinstance(value, str): |
| 300 | try: |
| 301 | value = json.loads(value) |
| 302 | except json.JSONDecodeError: |
| 303 | pass |
| 304 | |
| 305 | for arg_type in args: |
| 306 | if arg_type is type(None): |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 812 | # Fast path for common type aliases and named types. |
| 813 | try: |
| 814 | return get_type_by_name(text) |
| 815 | except Exception: |
| 816 | pass |
| 817 | |
| 818 | flags = ida_typeinf.PT_SIL | ida_typeinf.PT_TYP |
| 819 | parse_decl = getattr(ida_typeinf, "parse_decl", None) |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 61 | os.replace(tmp_path, file_path) |
| 62 | except Exception: |
| 63 | try: |
| 64 | os.unlink(tmp_path) |
| 65 | except OSError: |
| 66 | pass |
| 67 | raise |
| 68 | return file_path |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.