Skip to content

Commit 6cec706

Browse files
committed
fix(exceptions): redact device address from connection error messages
Connection-related errors (ScrapeError, AuthError, RestError, DeviceTimeout) include netmiko's raw message, which contains a 'Device settings:' line exposing the device IP address and port. Strip that line before the error reaches the client (falling back to a generic message if nothing else remains) so internal device addressing is not leaked to looking-glass users. Standalone change; touches only hyperglass/exceptions/public.py.
1 parent fd34bda commit 6cec706

1 file changed

Lines changed: 68 additions & 8 deletions

File tree

hyperglass/exceptions/public.py

Lines changed: 68 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,32 +20,92 @@ class ScrapeError(
2020
"""Raised when an SSH driver error occurs."""
2121

2222
def __init__(self, *, error: BaseException, device: "Device"):
23-
"""Initialize parent error."""
24-
super().__init__(error=str(error), device=device.name, proxy=device.proxy)
23+
"""Initialize parent error with sanitized error message."""
24+
# Sanitize error message to remove sensitive information like IP/port
25+
error_str = str(error)
26+
27+
# Remove device settings line that contains IP:port
28+
if "Device settings:" in error_str:
29+
lines = error_str.split("\n")
30+
sanitized_lines = [
31+
line for line in lines if not line.strip().startswith("Device settings:")
32+
]
33+
error_str = "\n".join(sanitized_lines).strip()
34+
35+
# If the error is empty after sanitization, provide a generic message
36+
if not error_str or error_str.isspace():
37+
error_str = "Connection error occurred"
38+
39+
super().__init__(error=error_str, device=device.name, proxy=device.proxy)
2540

2641

2742
class AuthError(PublicHyperglassError, template="authentication_error", level="danger"):
2843
"""Raised when authentication to a device fails."""
2944

3045
def __init__(self, *, error: BaseException, device: "Device"):
31-
"""Initialize parent error."""
32-
super().__init__(error=str(error), device=device.name, proxy=device.proxy)
46+
"""Initialize parent error with sanitized error message."""
47+
# Sanitize error message to remove sensitive information like IP/port
48+
error_str = str(error)
49+
50+
# Remove device settings line that contains IP:port
51+
if "Device settings:" in error_str:
52+
lines = error_str.split("\n")
53+
sanitized_lines = [
54+
line for line in lines if not line.strip().startswith("Device settings:")
55+
]
56+
error_str = "\n".join(sanitized_lines).strip()
57+
58+
# If the error is empty after sanitization, provide a generic message
59+
if not error_str or error_str.isspace():
60+
error_str = "Authentication failed"
61+
62+
super().__init__(error=error_str, device=device.name, proxy=device.proxy)
3363

3464

3565
class RestError(PublicHyperglassError, template="connection_error", level="danger"):
3666
"""Raised upon a rest API client error."""
3767

3868
def __init__(self, *, error: BaseException, device: "Device"):
39-
"""Initialize parent error."""
40-
super().__init__(error=str(error), device=device.name)
69+
"""Initialize parent error with sanitized error message."""
70+
# Sanitize error message to remove sensitive information like IP/port
71+
error_str = str(error)
72+
73+
# Remove device settings line that contains IP:port
74+
if "Device settings:" in error_str:
75+
lines = error_str.split("\n")
76+
sanitized_lines = [
77+
line for line in lines if not line.strip().startswith("Device settings:")
78+
]
79+
error_str = "\n".join(sanitized_lines).strip()
80+
81+
# If the error is empty after sanitization, provide a generic message
82+
if not error_str or error_str.isspace():
83+
error_str = "REST API connection error"
84+
85+
super().__init__(error=error_str, device=device.name)
4186

4287

4388
class DeviceTimeout(PublicHyperglassError, template="request_timeout", level="danger"):
4489
"""Raised when the connection to a device times out."""
4590

4691
def __init__(self, *, error: BaseException, device: "Device"):
47-
"""Initialize parent error."""
48-
super().__init__(error=str(error), device=device.name, proxy=device.proxy)
92+
"""Initialize parent error with sanitized error message."""
93+
# Sanitize error message to remove sensitive information like IP/port
94+
error_str = str(error)
95+
96+
# Remove device settings line that contains IP:port
97+
if "Device settings:" in error_str:
98+
lines = error_str.split("\n")
99+
sanitized_lines = [
100+
line for line in lines if not line.strip().startswith("Device settings:")
101+
]
102+
error_str = "\n".join(sanitized_lines).strip()
103+
104+
# If the error is empty after sanitization, provide a generic message
105+
if not error_str or error_str.isspace():
106+
error_str = "Connection timed out"
107+
108+
super().__init__(error=error_str, device=device.name, proxy=device.proxy)
49109

50110

51111
class InvalidQuery(PublicHyperglassError, template="request_timeout"):

0 commit comments

Comments
 (0)