How VulnClaw's TUI Workbench Validates Testing Scope Boundaries
VulnClaw's TUI workbench validates testing scope boundaries through a three-layer validation system that parses user input via the /scope command, normalizes action lists and port ranges, applies mode-specific defaults, and re-validates through the CLI parser before execution.
The Unclecheng-li/VulnClaw repository implements a defensive validation pipeline that prevents out-of-bounds targets or dangerous action combinations from reaching the penetration testing engine. This scope validation is centralized in the TuiState object and enforced through interactive parsing, mode-aware defaults, and CLI-level re-validation.
Three-Layer Validation Architecture
VulnClaw's validation operates at three distinct layers to ensure testing scope boundaries are never violated during task execution.
Interactive Input Parsing and Normalization
When an operator issues the /scope slash command, the TUI initiates a prompt-state machine that collects and validates fields before they enter the system state.
The _cmd_scope handler (lines 79-94 in vulnclaw/cli/tui.py) builds a list of scope fields including target, only_host, only_port, blocked_host, blocked_path, allow_actions, and block_actions. Each user response routes through _handle_prompt_response, which dispatches to specialized parsers:
- Port validation: The
_parse_optional_portfunction (lines 629-638) converts input to an integer and enforces the range 1-65535, raisingValueError(_("tui.error_invalid_port"))for out-of-bounds values. - Action list normalization: The
_parse_action_csvfunction (lines 221-226) splits comma-separated strings, trims whitespace, and filters empty items to guarantee a cleanlist[str].
Mode-Aware Default Application
If the operator leaves action lists empty, the TUI automatically applies safety defaults based on the selected TuiMode (quick, standard, deep, or continuous).
The _effective_allow_actions and _effective_block_actions methods (lines 613-618 in vulnclaw/cli/tui.py) query the mode configuration from vulnclaw/config/settings.py. For example, quick mode defaults to allow_actions=("recon",) and block_actions=("exploit", "persistent", "post_exploitation"), ensuring high-risk actions are blocked even when the user specifies nothing.
CLI-Level Re-Validation
Before launching any task, the TUI constructs a TuiTaskDraft via _draft_from_state (lines 442-456), which consolidates validated scope data into CLI arguments. When the user executes /run or presses Start, the _cmd_start handler triggers _do_launch (lines 331-349), passing the draft to the CLI runner in vulnclaw/cli/main.py.
The CLI entry point re-applies the same validation constraints independently, ensuring that bypassing the TUI (or manually editing generated commands) cannot violate scope boundaries.
Core Validation Logic in vulnclaw/cli/tui.py
The primary validation implementation resides in vulnclaw/cli/tui.py, where state management and boundary checking are tightly coupled.
State Storage: The TuiState dataclass maintains the canonical scope definition, tracking target, only_* filters, blocked_* exclusions, and action allow-lists/block-lists.
Draft Generation: The _draft_from_state function transforms the validated state into a TuiTaskDraft object, which build_command_preview_args converts into executable command-line strings. This draft serves as the immutable boundary specification passed to the execution engine.
Error Handling: All user-facing validation errors reference translation keys in vulnclaw/i18n/en.json (and zh.json), such as tui.error_invalid_port, ensuring consistent localized feedback when boundaries are violated.
Practical Usage Examples
Setting a Valid Custom Scope
/scope host=example.com port=443 allow=recon,scan block=exploit
- The
_cmd_scopehandler parses key-value pairs through_parse_scope_args. port=443passes_parse_optional_portvalidation (within 1-65535).allow=recon,scanandblock=exploitare normalized by_parse_action_csvinto clean lists.
The dashboard displays the effective actions:
Allowed actions: recon, scan
Blocked actions: exploit
Using Quick Mode Defaults
/mode quick
/run
- The
quickmode definesallow_actions=("recon",)andblock_actions=("exploit", "persistent", "post_exploitation")inTuiMode. _effective_allow_actionsand_effective_block_actionsinject these defaults when the user omits explicit values.
The generated command preview becomes:
vulnclaw recon <target> --only-host example.com --only-port 443 --allow-actions recon --block-actions exploit,persistent,post_exploitation
Handling Invalid Port Input
/scope port=99999
_parse_optional_portraisesValueErrorwith the translated messagetui.error_invalid_port.- The TUI displays "Invalid port number" and prompts the user to retry, preventing the out-of-bounds value from entering
TuiState.
Inspecting the Command Draft Programmatically
from vulnclaw.cli.tui import build_task_draft, build_state_from_options
state = build_state_from_options(
target="10.0.0.5",
mode="deep",
only_host="10.0.0.5",
only_port="443",
allow_actions="recon,scan",
)
draft = build_task_draft(state)
print(draft.command_line)
# Output: vulnclaw scan 10.0.0.5 --only-host 10.0.0.5 --only-port 443 --allow-actions recon,scan
Summary
- Interactive validation occurs immediately during
/scopeinput parsing, enforcing valid port ranges (1-65535) and normalized action lists via_parse_optional_portand_parse_action_csv. - Mode-aware defaults automatically populate empty allow/block action lists from
TuiModeconfigurations (quick, standard, deep, continuous) through_effective_allow_actionsand_effective_block_actions. - CLI re-validation ensures the
TuiTaskDraftcreated by_draft_from_stateis checked again byvulnclaw/cli/main.pybefore execution, preventing scope bypasses. - Localized error reporting uses translation keys like
tui.error_invalid_portstored invulnclaw/i18n/en.jsonto provide immediate feedback on boundary violations.
Frequently Asked Questions
How does VulnClaw validate port numbers entered in the TUI?
VulnClaw validates ports through the _parse_optional_port function in vulnclaw/cli/tui.py (lines 629-638). This function attempts to convert the input string to an integer and verifies it falls within the valid TCP/UDP port range of 1 to 65535. If the value is outside this range or not a valid integer, the function raises a ValueError with the translation key tui.error_invalid_port, which the TUI renders as a localized error message prompting the user to correct the input.
What happens if I don't specify allow_actions or block_actions when setting scope?
When action lists are omitted, the TUI applies default values based on the currently selected TuiMode (quick, standard, deep, or continuous). The _effective_allow_actions and _effective_block_actions methods (lines 613-618) retrieve the appropriate defaults from the mode configuration in vulnclaw/config/settings.py. For instance, quick mode automatically blocks high-risk actions like exploit and persistent while allowing only recon, ensuring safe defaults even without explicit user input.
Can the TUI validation be bypassed by running VulnClaw commands directly?
No, the validation cannot be bypassed because the CLI entry point in vulnclaw/cli/main.py re-applies the same scope validation constraints independently of the TUI. When the TUI launches a task via _do_launch, it passes a TuiTaskDraft to the CLI runner, which re-parses and validates all arguments—including targets, ports, and actions—before executing the penetration testing job. This dual-layer validation ensures consistency whether the operator uses the interactive workbench or command-line interface.
Where are the error messages for validation failures defined?
All user-facing validation error messages are defined in the internationalization files located at vulnclaw/i18n/en.json and zh.json. The TUI references these messages via translation keys such as tui.error_invalid_port and tui.invalid_choice. When validation fails in functions like _parse_optional_port, the code raises exceptions with these keys, which the Textual UI front-end (vulnclaw/cli/tui_textual.py) renders into the user's selected language.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →