Skip to content

Fix 5 bugs: TypeError in Attack class, native module crash, unsafe in…#456

Merged
kimocoder merged 1 commit into
masterfrom
claude/scan-project-issues-rodxf
Mar 6, 2026
Merged

Fix 5 bugs: TypeError in Attack class, native module crash, unsafe in…#456
kimocoder merged 1 commit into
masterfrom
claude/scan-project-issues-rodxf

Conversation

@kimocoder

Copy link
Copy Markdown
Owner

…dex access, placeholder dep check, command splitting

  • model/attack.py: Replace class-level min(60, None) with safe static method that handles uninitialized Configuration.wpa_attack_timeout
  • native/init.py + all 6 native submodules: Catch BaseException (not just ImportError) on scapy imports to handle pyo3 PanicException gracefully
  • native/init.py: Wrap top-level imports in try/except for graceful degradation when scapy/cryptography/cffi unavailable
  • attack/pmkid.py, util/scanner.py: Broaden exception handling for native module imports to catch BaseException
  • model/target.py: Guard against empty string in encryption.split() fallback
  • attack/eviltwin.py: Replace placeholder dependency check with actual hostapd/dnsmasq availability verification
  • util/process.py: Use shlex.split() instead of str.split() for proper handling of quoted arguments in commands
  • wifite.py: Log session cleanup errors instead of silently swallowing them

Test results: 43 failures → 0 failures (575 passed, 5 skipped)

…dex access, placeholder dep check, command splitting

- model/attack.py: Replace class-level `min(60, None)` with safe static method
  that handles uninitialized Configuration.wpa_attack_timeout
- native/__init__.py + all 6 native submodules: Catch BaseException (not just
  ImportError) on scapy imports to handle pyo3 PanicException gracefully
- native/__init__.py: Wrap top-level imports in try/except for graceful
  degradation when scapy/cryptography/cffi unavailable
- attack/pmkid.py, util/scanner.py: Broaden exception handling for native
  module imports to catch BaseException
- model/target.py: Guard against empty string in encryption.split() fallback
- attack/eviltwin.py: Replace placeholder dependency check with actual
  hostapd/dnsmasq availability verification
- util/process.py: Use shlex.split() instead of str.split() for proper
  handling of quoted arguments in commands
- wifite.py: Log session cleanup errors instead of silently swallowing them

Test results: 43 failures → 0 failures (575 passed, 5 skipped)

https://claude.ai/code/session_012qvM97c3D9M98CrMjmzuQd
Copilot AI review requested due to automatic review settings March 6, 2026 05:49
@kimocoder kimocoder merged commit 16d4778 into master Mar 6, 2026
8 of 9 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR focuses on improving runtime robustness across the attack pipeline by preventing startup/import crashes, hardening command execution argument parsing, and fixing a handful of edge-case bugs in target parsing and dependency checks.

Changes:

  • Fixes a class-load TypeError in Attack by deferring timeout computation until runtime.
  • Makes native/scapy-backed modules degrade gracefully when imports fail/crash, and broadens native-import exception handling in callers.
  • Improves operational correctness by using shlex.split() for command parsing, adding real EvilTwin dependency checks, and surfacing session cleanup errors in verbose mode.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
wifite/wifite.py Logs session cleanup errors (in verbose) instead of silently ignoring them.
wifite/util/scanner.py Treats native scanner import failures as “native unavailable” to allow fallback behavior.
wifite/util/process.py Switches from naive string splitting to shlex.split() for subprocess argument parsing.
wifite/native/init.py Wraps native module imports to allow partial availability and adds broader availability checks.
wifite/native/wps.py Broadens scapy import exception handling and toggles SCAPY_AVAILABLE.
wifite/native/scanner.py Broadens scapy import exception handling and toggles SCAPY_AVAILABLE.
wifite/native/pmkid.py Broadens scapy import exception handling and toggles SCAPY_AVAILABLE.
wifite/native/handshake.py Broadens scapy import exception handling and toggles SCAPY_AVAILABLE.
wifite/native/deauth.py Broadens scapy import exception handling and toggles SCAPY_AVAILABLE.
wifite/native/beacon.py Broadens scapy import exception handling and toggles SCAPY_AVAILABLE.
wifite/model/target.py Hardens encryption parsing to avoid unsafe index access in fallback logic.
wifite/model/attack.py Fixes Attack.target_wait initialization by introducing a safe runtime getter.
wifite/attack/pmkid.py Broadens native PMKID import exception handling for graceful fallback.
wifite/attack/eviltwin.py Replaces placeholder dependency check with actual hostapd/dnsmasq availability verification.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread wifite/util/process.py
if Configuration.verbose > 1:
Color.pe(f'\n {{C}}[?]{{W}} Executing: {{B}}{command}{{W}}')
command = command.split()
command = shlex.split(command)

Copilot AI Mar 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shlex.split() can raise ValueError for malformed/unbalanced quoting. Right now that would bubble up and potentially crash the caller in cases that previously worked (even if parsed imperfectly). Consider catching ValueError here and either (a) raising a clearer error that includes the original command string, or (b) falling back to a simpler split strategy.

Suggested change
command = shlex.split(command)
orig_command = command
try:
command = shlex.split(command)
except ValueError as e:
# Fall back to a naive split if shlex.split fails (e.g., malformed quoting)
log_warning(
f"Failed to parse command with shlex.split(): {e}. "
f"Falling back to naive split for command: {orig_command!r}"
)
command = orig_command.split()

Copilot uses AI. Check for mistakes.
Comment thread wifite/native/__init__.py
Comment on lines 120 to 166
try:
from .mac import NativeMac
status['mac'] = True
except ImportError:
except BaseException:
status['mac'] = False

try:
from .deauth import SCAPY_AVAILABLE
status['deauth'] = SCAPY_AVAILABLE
except ImportError:
except BaseException:
status['deauth'] = False

try:
from .handshake import SCAPY_AVAILABLE
status['handshake'] = SCAPY_AVAILABLE
except ImportError:
except BaseException:
status['handshake'] = False

try:
from .wps import SCAPY_AVAILABLE
status['wps'] = SCAPY_AVAILABLE
except ImportError:
except BaseException:
status['wps'] = False

try:
from .interface import NativeInterface
status['interface'] = True
except ImportError:
except BaseException:
status['interface'] = False

try:
from .pmkid import SCAPY_AVAILABLE
status['pmkid'] = SCAPY_AVAILABLE
except ImportError:
except BaseException:
status['pmkid'] = False

try:
from .scanner import SCAPY_AVAILABLE
status['scanner'] = SCAPY_AVAILABLE
except ImportError:
except BaseException:
status['scanner'] = False

try:
from .beacon import SCAPY_AVAILABLE
status['beacon'] = SCAPY_AVAILABLE
except ImportError:
except BaseException:
status['beacon'] = False

Copilot AI Mar 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check_native_availability() catches BaseException, which includes KeyboardInterrupt/SystemExit and also masks unexpected coding/runtime errors in the native modules. Consider re-raising KeyboardInterrupt/SystemExit and recording/logging the caught exception (at least under verbose/debug) so users can distinguish "not installed" from "native module crashed during import".

Copilot uses AI. Check for mistakes.
Comment thread wifite/util/scanner.py
Comment on lines +16 to 17
except BaseException:
NATIVE_SCANNER_AVAILABLE = False

Copilot AI Mar 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Catching BaseException here will also intercept KeyboardInterrupt/SystemExit, which can prevent expected termination during startup. If the goal is to handle rare import-time crashes, consider re-raising interrupt/exit exceptions and (optionally) logging the underlying import error in verbose mode to aid debugging when native scanning is disabled.

Suggested change
except BaseException:
NATIVE_SCANNER_AVAILABLE = False
except BaseException as e:
# Do not swallow interrupts/exits during startup
if isinstance(e, (KeyboardInterrupt, SystemExit)):
raise
# Any other error means the native scanner is not available
NATIVE_SCANNER_AVAILABLE = False
# Optionally log the underlying import error when in verbose mode
if Configuration.verbose > 0:
Color.pexception(e)

Copilot uses AI. Check for mistakes.
Comment thread wifite/native/beacon.py
Comment on lines +34 to 35
except BaseException:
SCAPY_AVAILABLE = False

Copilot AI Mar 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same concern as other native modules: except BaseException also catches KeyboardInterrupt/SystemExit and hides unexpected runtime/coding errors as "Scapy unavailable". Consider re-raising interrupt/exit exceptions and optionally storing/logging the underlying import exception for debugging.

Suggested change
except BaseException:
SCAPY_AVAILABLE = False
SCAPY_IMPORT_ERROR = None
except BaseException as e:
# Do not swallow critical exceptions like KeyboardInterrupt/SystemExit.
if isinstance(e, (KeyboardInterrupt, SystemExit)):
raise
# Scapy failed to import for some other reason; mark as unavailable
# and keep the original exception for potential debugging.
SCAPY_AVAILABLE = False
SCAPY_IMPORT_ERROR = e

Copilot uses AI. Check for mistakes.
Comment thread wifite/native/pmkid.py
Comment on lines 43 to 48
sniff, sendp, conf as scapy_conf
)
SCAPY_AVAILABLE = True
except ImportError:
except BaseException:
SCAPY_AVAILABLE = False

Copilot AI Mar 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same pattern: except BaseException catches KeyboardInterrupt/SystemExit and can hide unexpected exceptions as a simple "Scapy unavailable" flag. Consider re-raising interrupt/exit exceptions and logging/preserving the underlying exception for debugging.

Copilot uses AI. Check for mistakes.
Comment thread wifite/native/__init__.py
Comment on lines +26 to +73
try:
from .mac import NativeMac
except BaseException:
NativeMac = None

try:
from .deauth import ScapyDeauth, ContinuousDeauth as NativeDeauth
except BaseException:
ScapyDeauth = None
NativeDeauth = None

try:
from .handshake import ScapyHandshake
except BaseException:
ScapyHandshake = None

try:
from .wps import ScapyWPS, WPSInfo
except BaseException:
ScapyWPS = None
WPSInfo = None

try:
from .interface import NativeInterface, InterfaceInfo
except BaseException:
NativeInterface = None
InterfaceInfo = None

try:
from .pmkid import ScapyPMKID, PMKIDResult, PMKIDCapture
except BaseException:
ScapyPMKID = None
PMKIDResult = None
PMKIDCapture = None

try:
from .scanner import ChannelHopper, NativeScanner, AccessPoint, Client
except BaseException:
ChannelHopper = None
NativeScanner = None
AccessPoint = None
Client = None

try:
from .beacon import BeaconGenerator, create_fake_ap as create_beacon
except BaseException:
BeaconGenerator = None
create_beacon = None

Copilot AI Mar 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Catching BaseException will also swallow KeyboardInterrupt and SystemExit, which can make Ctrl+C or normal interpreter shutdown behave unexpectedly during imports. If BaseException is required for specific import-time crashes, consider re-raising KeyboardInterrupt/SystemExit (and possibly GeneratorExit) while handling the rest, and/or capturing/logging the original exception for debugging when native features are unexpectedly unavailable.

Copilot uses AI. Check for mistakes.
Comment thread wifite/attack/pmkid.py
from ..native.pmkid import ScapyPMKID, PMKIDResult as NativePMKIDResult
NATIVE_PMKID_AVAILABLE = ScapyPMKID.is_available()
except ImportError:
except BaseException:

Copilot AI Mar 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Catching BaseException here will also swallow KeyboardInterrupt/SystemExit, which can lead to surprising behavior at import time. If BaseException is needed to handle specific native import crashes, consider re-raising interrupt/exit exceptions and/or logging the underlying error when verbose so native PMKID availability doesn't silently flip to False on unexpected failures.

Suggested change
except BaseException:
except BaseException as e:
# Do not swallow interrupt/exit exceptions; re-raise them.
if isinstance(e, (KeyboardInterrupt, SystemExit)):
raise
# For any other failure, disable native PMKID support and log the reason.
log_debug("Native PMKID unavailable due to import error: %s" % (e,))

Copilot uses AI. Check for mistakes.
Comment thread wifite/native/wps.py
Comment on lines 33 to 40
try:
from scapy.all import (
rdpcap, Dot11, Dot11Beacon, Dot11ProbeResp, Dot11Elt,
conf as scapy_conf
)
SCAPY_AVAILABLE = True
except ImportError:
except BaseException:
SCAPY_AVAILABLE = False

Copilot AI Mar 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Catching BaseException here will also catch KeyboardInterrupt/SystemExit and can mask unexpected errors (e.g., a programming error inside Scapy) as simply "Scapy unavailable". Consider re-raising interrupt/exit exceptions and, if possible, preserving/logging the original exception for debugging while still allowing graceful fallback when the import truly fails.

Copilot uses AI. Check for mistakes.
Comment thread wifite/native/deauth.py
Comment on lines 42 to 50
try:
from scapy.all import (
RadioTap, Dot11, Dot11Deauth, Dot11Disas,
sendp, conf as scapy_conf
)
SCAPY_AVAILABLE = True
except ImportError:
except BaseException:
SCAPY_AVAILABLE = False

Copilot AI Mar 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

except BaseException here will catch KeyboardInterrupt/SystemExit and can make import-time interrupts behave oddly, while also hiding unexpected errors in Scapy as "unavailable". Consider re-raising interrupt/exit exceptions and logging the underlying exception when falling back.

Copilot uses AI. Check for mistakes.
Comment on lines 38 to 43
Dot11Elt, Raw, conf as scapy_conf
)
SCAPY_AVAILABLE = True
except ImportError:
except BaseException:
SCAPY_AVAILABLE = False

Copilot AI Mar 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Catching BaseException here will also swallow KeyboardInterrupt/SystemExit and can mask genuine bugs in the Scapy import path as a simple availability toggle. Consider re-raising interrupt/exit exceptions and capturing/logging the underlying exception so unexpected failures are diagnosable.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants