T09 · Insecure Skill Coding Practices
- Location
scripts/tailscale_ctrl.py:146- Finding
Public IP Disclosure Through Unmasked Output Fallbacks
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This is a read-only Tailscale helper, but its broad activation trigger and incomplete IP redaction deserve review before installation.
Install only if you are comfortable letting the agent read and display Tailscale device, hostname, owner/whois, status, and diagnostic information from your current tailnet. Treat the IP masking as best-effort rather than guaranteed until the stderr and fallback output paths are fixed, and prefer explicit Tailscale command requests over broad conversational triggers.
scripts/tailscale_ctrl.py:146Public IP Disclosure Through Unmasked Output Fallbacks
The declared behavior does not fully match the exposed commands: whois and ip are available without being clearly disclosed, and serve/funnel inspection is described more broadly than implemented. Behavior mismatches weaken operator trust and review accuracy, and can expose network-identifying information or enable uses that were not evaluated under the stated security assumptions.
The skill advertises shell-backed capabilities but does not declare any explicit tool scope or allowed-tools boundary. In an agent environment, missing permission declarations can allow broader-than-intended command execution paths or make policy enforcement ambiguous, which is risky even if the documented commands are read-only.
Using tailnet as a trigger is overly broad and may cause the skill to activate during ordinary conversation rather than clear user intent to run network queries. Unintended invocation could disclose device status, internal hostnames, Tailscale IPs, or diagnostic data from a sensitive network context.
The script exposes a whois lookup capability that is outside the skill metadata's declared feature set, which creates a scope mismatch between what operators expect and what the code can actually do. In an agent setting, hidden or undocumented capabilities are dangerous because they may disclose identity, device-owner, or node-mapping information from the tailnet without users or reviewers realizing that this action is available.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
"""Execute a tailscale command and return raw stdout/stderr (NO masking)."""
cmd = ["tailscale"] + args
try:
result = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
return {
"returncode": result.returncode,
"stdout": result.stdout.strip(),
The trigger list includes "chi è connesso", which introduces a language-specific behavior, but the document does not state that multilingual triggering is optional or explain the locale policy. This can conflict with language/locale requirements when a skill silently forces or embeds support for a specific language without user opt-in or justification.
The module documentation states public IPs are masked only in final output after JSON parsing. However, in main() JSON mode serializes the entire data structure and then applies regex masking over the full JSON text, which is broader than the documented behavior and not limited to parsed/display fields in the way described.