Skip to content

Commit 26cfaa5

Browse files
Potential fix for code scanning alert no. 13: Clear-text logging of sensitive information
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
1 parent 473d5b3 commit 26cfaa5

File tree

3 files changed

+82
-3
lines changed

3 files changed

+82
-3
lines changed

wifite/util/interface_manager.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1707,10 +1707,19 @@ def get_available_interfaces() -> List[InterfaceInfo]:
17071707
# Task 11.1: Log interface capabilities
17081708
log_info('InterfaceManager',
17091709
f' {interface_name}: {interface_info.get_capability_summary()}')
1710+
# Mask MAC address to avoid logging full hardware identifier
1711+
masked_mac = interface_info.mac_address
1712+
try:
1713+
if isinstance(interface_info.mac_address, str) and interface_info.mac_address:
1714+
parts = interface_info.mac_address.split(':')
1715+
if len(parts) == 6:
1716+
masked_mac = ':'.join(parts[:3] + ['**', '**', '**'])
1717+
except Exception:
1718+
pass
17101719
log_debug('InterfaceManager',
17111720
f' {interface_name} details: driver={interface_info.driver}, '
17121721
f'chipset={interface_info.chipset}, phy={interface_info.phy}, '
1713-
f'mac={interface_info.mac_address}')
1722+
f'mac={masked_mac}')
17141723
log_debug('InterfaceManager',
17151724
f' {interface_name} state: mode={interface_info.current_mode}, '
17161725
f'up={interface_info.is_up}, connected={interface_info.is_connected}')

wifite/util/logger.py

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,71 @@ def _should_log(cls, level: int) -> bool:
9292
"""Check if message should be logged based on level."""
9393
return cls._enabled and level >= cls._log_level
9494

95+
@classmethod
96+
def _sanitize_message(cls, message: str) -> str:
97+
"""
98+
Best-effort sanitization to avoid logging sensitive data in clear text.
99+
100+
Currently masks:
101+
- Known wpa-sec API key from Configuration.wpasec_api_key
102+
- Command-line API key arguments like "-k <value>" and "--key <value>"
103+
- MAC addresses in standard hex notation (aa:bb:cc:dd:ee:ff)
104+
"""
105+
try:
106+
# Import lazily to avoid circular imports during module initialization
107+
from ..config import Configuration # type: ignore
108+
except Exception:
109+
Configuration = None # type: ignore
110+
111+
sanitized = message
112+
113+
# Mask configured wpa-sec API key if present in message
114+
try:
115+
if Configuration is not None and getattr(Configuration, "wpasec_api_key", None):
116+
api_key = Configuration.wpasec_api_key
117+
if isinstance(api_key, str) and api_key:
118+
masked_key = api_key[:4] + "*" * (len(api_key) - 4) if len(api_key) > 4 else "****"
119+
sanitized = sanitized.replace(api_key, masked_key)
120+
except Exception:
121+
# Never let sanitization break logging
122+
pass
123+
124+
# Mask common CLI key patterns: "-k <value>" and "--key <value>"
125+
try:
126+
import re
127+
128+
def _mask_cli_key(match):
129+
flag = match.group(1)
130+
return f"{flag} ****"
131+
132+
sanitized = re.sub(r"(-k)\s+\S+", _mask_cli_key, sanitized)
133+
sanitized = re.sub(r"(--key)\s+\S+", _mask_cli_key, sanitized)
134+
except Exception:
135+
pass
136+
137+
# Mask MAC addresses: aa:bb:cc:dd:ee:ff -> aa:bb:cc:**:**:**
138+
try:
139+
import re
140+
141+
def _mask_mac(match):
142+
full = match.group(0)
143+
parts = full.split(":")
144+
if len(parts) == 6:
145+
return ":".join(parts[:3] + ["**", "**", "**"])
146+
return full
147+
148+
sanitized = re.sub(r"\b([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}\b", _mask_mac, sanitized)
149+
except Exception:
150+
pass
151+
152+
return sanitized
153+
95154
@classmethod
96155
def _format_message(cls, level: str, module: str, message: str) -> str:
97156
"""Format log message with timestamp and level."""
98157
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
99-
return f"[{timestamp}] [{level:8s}] [{module:20s}] {message}"
158+
safe_message = cls._sanitize_message(message)
159+
return f"[{timestamp}] [{level:8s}] [{module:20s}] {safe_message}"
100160

101161
@classmethod
102162
def _write_to_file(cls, formatted_message: str):

wifite/util/process.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,17 @@ def __init__(self, command, devnull=False, stdout=PIPE, stderr=PIPE, cwd=None, b
151151
self._devnull_handles = []
152152

153153
cmd_str = " ".join(command) if isinstance(command, list) else str(command)
154-
log_debug('Process', f'Creating process: {cmd_str}')
154+
# Avoid logging sensitive arguments (e.g. API keys) in clear text
155+
try:
156+
import re
157+
def _mask_cli_key(match):
158+
flag = match.group(1)
159+
return f"{flag} ****"
160+
safe_cmd_str = re.sub(r"(-k)\s+\S+", _mask_cli_key, cmd_str)
161+
safe_cmd_str = re.sub(r"(--key)\s+\S+", _mask_cli_key, safe_cmd_str)
162+
except Exception:
163+
safe_cmd_str = cmd_str
164+
log_debug('Process', f'Creating process: {safe_cmd_str}')
155165

156166
if Configuration.verbose > 1:
157167
Color.pe(f'\n {{C}}[?] {{W}} Executing: {{B}}{" ".join(command)}{{W}}')

0 commit comments

Comments
 (0)