Back to skill

Security audit

Sonos Announce

Security checks for vulnerabilities and agentic risk

Overview

This Sonos audio skill appears purpose-aligned, but it starts a local web server and uses unsafe shell/process controls that can expose files or run/kill commands if misused.

Review this skill before installing. Use it only in a trusted local network, keep media_dir limited to a dedicated non-sensitive audio folder, avoid passing user-controlled paths, and be aware it may leave an unauthenticated local HTTP server running and may kill other processes using the configured port. Prefer a hardened version that uses subprocess without shell=True, serves only the requested file, binds explicitly, cleans up in a finally block, and pins dependencies.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
sonos_core.py:73
Finding

Shell Command Injection Through the media_dir Parameter

Content
View full analysis

Vulnerability Details

File Location: sonos_core.py:73-81
Vulnerability Type: OS command injection
Risk Level: High

Vulnerable Code

python
if platform.system() == "Windows":
    # Start server and save PID to file
    os.system(f'start /b python -m http.server {HTTP_PORT} --directory "{media_dir}"')
    # On Windows, we can't easily get the PID of start /b, so just track by port
    # The stop_http_server will use port-based killing as fallback
else:
    # Use nohup to ensure it persists and save PID
    os.system(f'nohup python3 -m http.server {HTTP_PORT} --directory "{media_dir}" > /tmp/sonos_http.log 2>&1 &')

Technical Analysis

The media_dir argument is interpolated directly into commands executed through os.system(). Although it is surrounded by double quotes, the value is not escaped for the relevant command shell. A crafted value containing a closing quote and shell control operators can terminate the intended argument and append arbitrary commands.

This issue affects both the Windows and Unix-like execution paths. The function is reachable through the public announce(..., media_dir=...) API. Consequently, any party capable of influencing that argument may be able to execute commands with the privileges of the process running the Skill.

Attack Path

  1. An attacker gains control over, or influences, the media_dir value supplied to announce().
  2. announce() passes the value to start_http_server(media_dir).
  3. start_http_server() embeds the untrusted value into a shell command.
  4. A crafted quote closes the --directory argument, while shell metacharacters append another command.
  5. os.system() invokes the platform shell and executes the injected command.
  6. The injected command runs under the account and permissions of the Agent or Skill host.

Impact Assessment

Successful exploitation permits arbitrary local command execution. The att ...[truncated 260 chars]

Remediation
View remediation

Remediation Suggestions

  • Replace os.system() with subprocess.Popen() using an argument array and without shell=True.
  • Resolve media_dir with pathlib.Path.resolve() and require it to be an existing directory.
  • Restrict serving to an explicitly approved media root and reject paths that escape that root.
  • Track the returned Popen object or PID directly instead of discovering the process through shell commands.
  • Open log files through Python and pass their handles to stdout and stderr.

Example hardened approach:

python
from pathlib import Path
import subprocess

directory = Path(media_dir).expanduser().resolve()
if not directory.is_dir():
    raise ValueError("Invalid media directory")

process = subprocess.Popen(
    [
        "python3",
        "-m",
        "http.server",
        str(HTTP_PORT),
        "--bind",
        HTTP_HOST,
        "--directory",
        str(directory),
    ],
    stdout=log_file,
    stderr=subprocess.STDOUT,
    start_new_session=True,
)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
sonos_core.py:65
Finding

Unauthenticated Directory Exposure and Lingering HTTP Server

Content
View full analysis

Vulnerability Details

File Location: sonos_core.py:65-82, with lifecycle behavior at sonos_core.py:399-447
Vulnerability Type: Excessive file exposure and persistent network service
Risk Level: High

Vulnerable Code

python
def start_http_server(media_dir=None):
    """Start the HTTP server for streaming audio to Sonos."""
    if media_dir is None:
        media_dir = os.path.expanduser("~/.local/share/openclaw/media/outbound")
    
    # Always kill any stale server first, then start fresh
    print("Stopping any existing HTTP server...")
    stop_http_server()
    time.sleep(1)
    
    print(f"Starting HTTP server from {media_dir}...")
    if platform.system() == "Windows":
        # Start server and save PID to file
        os.system(f'start /b python -m http.server {HTTP_PORT} --directory "{media_dir}"')
    else:
        # Use nohup to ensure it persists and save PID
        os.system(f'nohup python3 -m http.server {HTTP_PORT} --directory "{media_dir}" > /tmp/sonos_http.log 2>&1 &')

The server is started by announce() but is not stopped before the function returns:

python
# Ensure HTTP server is running
start_http_server(media_dir)

# ...

print("=== Done ===")
return {
    'coordinators': len(coordinators),
    'states': states,
}

Technical Analysis

Python's standard http.server serves the complete directory supplied through --directory, including directory listings, and does not provide authentication or authorization. No mechanism limits access to the single announcement file.

The server is also launched as a detached background process. On Unix-like systems, nohup explicitly allows it to survive after the invocation completes. announce() does not call stop_http_server() after playback and does not use a finally block to guarantee cleanup after errors.

SONOS_HTTP_HOST is used to construct the URL sent to Sono ...[truncated 1341 chars]

Remediation
View remediation

Remediation Suggestions

  • Copy or link only the requested audio file into a newly created, permission-restricted temporary directory.
  • Use a custom HTTP request handler that disables directory listings and permits access only to the expected file.
  • Generate a cryptographically random, single-use URL path rather than exposing the original file name.
  • Bind explicitly to the required LAN interface with --bind or an equivalent server API.
  • Start the server immediately before playback and terminate it in a finally block after playback or restoration.
  • Avoid nohup and other detached execution unless persistent serving is an explicitly documented requirement.
  • Validate that media_dir remains beneath an approved media root.
  • Document the temporary LAN exposure in SKILL.md.

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
sonos_core.py:91
Finding

Forceful Termination of Unrelated Processes Using the Configured Port

Content
View full analysis

Vulnerability Details

File Location: sonos_core.py:91-122
Vulnerability Type: Unsafe process management and denial of service
Risk Level: Medium

Vulnerable Code

python
def stop_http_server():
    """Stop the HTTP server gracefully using PID file, then fallback to port."""
    # Try PID file first (cleanest)
    if os.path.exists(PID_FILE):
        try:
            with open(PID_FILE, 'r') as f:
                pid = f.read().strip()
            if pid:
                os.kill(int(pid), 9)
                print(f"Stopped HTTP server (PID {pid})")
        except:
            pass
        try:
            os.remove(PID_FILE)
        except:
            pass
    
    # Fallback: kill by port
    if platform.system() == "Windows":
        try:
            result = subprocess.run(
                f'for /f "tokens=5" %a in (\'netstat -aon ^| findstr :{HTTP_PORT} ^| findstr LISTENING\') do taskkill /f /pid %a',
                shell=True, capture_output=True, text=True
            )
        except:
            pass
    else:
        os.system(f"lsof -ti:{HTTP_PORT} | xargs kill -9 2>/dev/null")
        os.system(f"pkill -9 -f 'python3 -m http.server {HTTP_PORT}' 2>/dev/null")

Technical Analysis

The fallback logic identifies processes by listening port or a broad command-line pattern rather than verifying that a process was created by the current Skill invocation.

On Unix-like systems, every process returned by lsof -ti:{HTTP_PORT} is sent SIGKILL. The pkill -f fallback may also terminate unrelated Python HTTP servers whose command lines match the pattern. On Windows, any listening process found through netstat for the configured port is forcefully terminated with taskkill /f.

Even the PID-file path uses SIGKILL without validating process identity or first attempting graceful termination. Stale PID reuse could cause an unrelated process to be ki ...[truncated 1021 chars]

Remediation
View remediation

Remediation Suggestions

  • Retain the exact subprocess.Popen object or securely recorded PID for the server created by the Skill.
  • Before terminating a stored PID, verify process ownership, creation time, and executable or command identity.
  • Attempt graceful shutdown with terminate() or SIGTERM, wait with a timeout, and use force only as a final fallback.
  • Never kill an arbitrary process merely because it occupies the desired port.
  • If the port is already in use by an unrelated service, return a clear error or select an available configured port.
  • Store runtime PID data in a user-private runtime directory with restrictive permissions and protect against stale PID reuse.
  • Remove the broad pkill -f and port-wide lsof | xargs kill fallbacks.

T08 · Insecure Dependencies

Note
Location
SKILL.md:9
Finding

Unpinned Third-Party SoCo Dependency

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:9-12, with installation instructions at SKILL.md:31-38
Vulnerability Type: Uncontrolled dependency resolution
Risk Level: Low

Vulnerable Code

yaml
"requires":
  {
    "bins": ["python3", "ffprobe"],
    "pip": ["soco"],
  },

The installation documentation likewise installs the package without a version or integrity constraint:

bash
pip install soco

Technical Analysis

The Skill requests soco without pinning a reviewed release or providing an integrity hash. Installation therefore resolves whichever release is current at installation time. This makes deployments non-reproducible and allows future upstream changes to alter the effective code executed by the Skill without changes to the audited project.

The package name itself is consistent with the declared Sonos functionality, and no dependency-confusion or typosquatting indicator was identified. The risk arises from uncontrolled future dependency resolution rather than evidence that the current package is malicious.

Attack Path

  1. A user or deployment system follows the metadata or documentation and runs an unpinned installation.
  2. The package index resolves the latest available soco release rather than a specifically reviewed version.
  3. A compromised, malicious, or unexpectedly incompatible future release is downloaded.
  4. Dependency installation or import executes code in the Skill environment.
  5. That code receives the permissions and network access available to the Agent process.

Impact Assessment

A compromised dependency could execute arbitrary Python code under the Agent account, access files available to that account, communicate over the network, or manipulate Sonos operations. Without evidence of an actually compromised release, this is a preventive supply-chain finding with low current severity.

Remediation
View remediation

Remediation Suggestions

  • Pin soco to a reviewed exact version in both metadata and installation documentation.
  • Maintain a lock file containing transitive dependency versions.
  • Use hash verification, such as pip install --require-hashes -r requirements.txt.
  • Install dependencies in an isolated virtual environment with only the permissions required for Sonos control.
  • Periodically review and deliberately update the pinned dependency after security testing.
  • Use trusted package indexes over authenticated TLS and avoid adding unreviewed alternate indexes.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (28)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The stated purpose focuses on Sonos playback and restoration, but the documentation also reveals hidden operational behaviors: starting/killing background HTTP servers, process management, IP autodetection, and serving local files over the network. This mismatch is dangerous because users may authorize a media skill without realizing it exposes local content and manipulates OS processes.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 219)May include surrounding context.

md
- `SKILL.md` - This documentation

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
98% confidence
Finding

This builds a shell command with a user-controllable path component (media_dir) and executes it via os.system on Windows. Even though HTTP_PORT is cast to int, media_dir is only quoted, not safely escaped for cmd.exe semantics, so a crafted directory value could break out of quoting and trigger arbitrary command execution.

Content

Scanner excerpt · sonos_core.py (reported line 80)May include surrounding context.

python
print(f"Starting HTTP server from {media_dir}...")
    if platform.system() == "Windows":
        # Start server and save PID to file
        os.system(f'start /b python -m http.server {HTTP_PORT} --directory "{media_dir}"')
        # On Windows, we can't easily get the PID of start /b, so just track by port
        # The stop_http_server will use port-based killing as fallback
    else:

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
99% confidence
Finding

This invokes a shell with a formatted command containing media_dir and HTTP_PORT. On Unix-like systems, shell metacharacters in media_dir can lead to arbitrary command execution, and the command is also used to launch a persistent background service, increasing abuse potential.

Content

Scanner excerpt · sonos_core.py (reported line 85)May include surrounding context.

python
# The stop_http_server will use port-based killing as fallback
    else:
        # Use nohup to ensure it persists and save PID
        os.system(f'nohup python3 -m http.server {HTTP_PORT} --directory "{media_dir}" > /tmp/sonos_http.log 2>&1 &')
        # Save PID for clean shutdown
        time.sleep(1)
        # Find the PID by port and save it

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · sonos_core.py (reported line 90)May include surrounding context.

python
time.sleep(1)
        # Find the PID by port and save it
        try:
            pid = subprocess.check_output(f"lsof -ti:{HTTP_PORT}", shell=True).decode().strip()
            with open(PID_FILE, 'w') as f:
                f.write(pid)
        except:

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
85% confidence
Finding

os.system() and os exec-family calls run shell commands with the process's full privileges, enabling arbitrary command execution.

Content

Scanner excerpt · sonos_core.py (reported line 126)May include surrounding context.

python
except:
            pass
    else:
        os.system(f"lsof -ti:{HTTP_PORT} | xargs kill -9 2>/dev/null")
        os.system(f"pkill -9 -f 'python3 -m http.server {HTTP_PORT}' 2>/dev/null")

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
85% confidence
Finding

os.system() and os exec-family calls run shell commands with the process's full privileges, enabling arbitrary command execution.

Content

Scanner excerpt · sonos_core.py (reported line 127)May include surrounding context.

python
pass
    else:
        os.system(f"lsof -ti:{HTTP_PORT} | xargs kill -9 2>/dev/null")
        os.system(f"pkill -9 -f 'python3 -m http.server {HTTP_PORT}' 2>/dev/null")


def is_external_input(uri):

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill documents capabilities including environment-variable use, filesystem access, network exposure, and shell/process control, but it does not declare any explicit tool scope or permissions. In an agent setting, this increases the risk of overbroad execution because users and orchestrators cannot clearly constrain what the skill may do before running it.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest description says the skill 'skips Line-In/TV/Bluetooth,' implying those source types are excluded from playback-state handling. However, later documentation states Line-In, TV/HDMI, and Bluetooth are detected as non-pausable inputs and then restored by reconnecting to them, which is materially different behavior.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
55% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SKILL.md (reported line 27)May include surrounding context.

md
- User wants to play an announcement on Sonos
- Soundboard effects (airhorn, rimshot, etc.)
- Any audio playback that should resume previous state

**This skill handles playback only** - audio generation (TTS, ElevenLabs, etc.) is separate.

Session Persistence

Medium
Category
Rogue Agent
Confidence
55% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SKILL.md (reported line 39)May include surrounding context.

sys.path.insert(0, '/path/to/sonos-announce') from sonos_core import announce

Play audio and restore previous state

Assumes audio is in default media_dir (~/.local/share/openclaw/media/outbound)

result = announce('my_audio.mp3')

text

Session Persistence

Medium
Category
Rogue Agent
Confidence
55% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · sonos_core.py (reported line 393)May include surrounding context.

python
sys.path.insert(0, '/path/to/sonos-announce')
from sonos_core import announce

# Play audio and restore previous state
# Assumes audio is in default media_dir (~/.local/share/openclaw/media/outbound)
result = announce('my_audio.mp3')
```

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documentation describes running an HTTP server in the background and controlling processes, but it does not clearly warn users that local media may be exposed over the LAN or that background processes may persist or be terminated. In context, this is more dangerous because the skill is intended for home-network use and may serve sensitive local audio files to other devices on the network.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The file's top-level description says the skill 'skips Line-In/TV/Bluetooth,' but the state restoration table explicitly documents that Line-In, TV/HDMI, and Bluetooth are re-connected after playback. This is an active contradiction in the skill's own documentation about what happens to those input types.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The skill's functionality extends beyond simple Sonos playback by starting a local web server and force-killing processes, including with broad port- and pattern-based termination. In an agent setting, that extra host-level control increases blast radius and can be abused to interfere with unrelated local services or expose local media over HTTP.

Content

No source excerpt is available for this finding.

Tainted flow: 'HTTP_PORT' from os.environ.get (line 39, credential/environment) → os.system (code execution)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · sonos_core.py (reported line 80)May include surrounding context.

python
print(f"Starting HTTP server from {media_dir}...")
    if platform.system() == "Windows":
        # Start server and save PID to file
        os.system(f'start /b python -m http.server {HTTP_PORT} --directory "{media_dir}"')
        # On Windows, we can't easily get the PID of start /b, so just track by port
        # The stop_http_server will use port-based killing as fallback
    else:

Session Persistence

Medium
Category
Rogue Agent
Confidence
65% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · sonos_core.py (reported line 84)May include surrounding context.

python
# On Windows, we can't easily get the PID of start /b, so just track by port
        # The stop_http_server will use port-based killing as fallback
    else:
        # Use nohup to ensure it persists and save PID
        os.system(f'nohup python3 -m http.server {HTTP_PORT} --directory "{media_dir}" > /tmp/sonos_http.log 2>&1 &')
        # Save PID for clean shutdown
        time.sleep(1)

Session Persistence

Medium
Category
Rogue Agent
Confidence
65% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · sonos_core.py (reported line 85)May include surrounding context.

python
# On Windows, we can't easily get the PID of start /b, so just track by port
        # The stop_http_server will use port-based killing as fallback
    else:
        # Use nohup to ensure it persists and save PID
        os.system(f'nohup python3 -m http.server {HTTP_PORT} --directory "{media_dir}" > /tmp/sonos_http.log 2>&1 &')
        # Save PID for clean shutdown
        time.sleep(1)

Tainted flow: 'HTTP_PORT' from os.environ.get (line 39, credential/environment) → os.system (code execution)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · sonos_core.py (reported line 85)May include surrounding context.

python
# The stop_http_server will use port-based killing as fallback
    else:
        # Use nohup to ensure it persists and save PID
        os.system(f'nohup python3 -m http.server {HTTP_PORT} --directory "{media_dir}" > /tmp/sonos_http.log 2>&1 &')
        # Save PID for clean shutdown
        time.sleep(1)
        # Find the PID by port and save it

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · sonos_core.py (reported line 90)May include surrounding context.

python
time.sleep(1)
        # Find the PID by port and save it
        try:
            pid = subprocess.check_output(f"lsof -ti:{HTTP_PORT}", shell=True).decode().strip()
            with open(PID_FILE, 'w') as f:
                f.write(pid)
        except:

Tainted flow: 'HTTP_PORT' from os.environ.get (line 39, credential/environment) → subprocess.check_output (code execution)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · sonos_core.py (reported line 90)May include surrounding context.

python
time.sleep(1)
        # Find the PID by port and save it
        try:
            pid = subprocess.check_output(f"lsof -ti:{HTTP_PORT}", shell=True).decode().strip()
            with open(PID_FILE, 'w') as f:
                f.write(pid)
        except:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · sonos_core.py (reported line 119)May include surrounding context.

python
if platform.system() == "Windows":
        # Use netstat to find and kill the process on the port
        try:
            result = subprocess.run(
                f'for /f "tokens=5" %a in (\'netstat -aon ^| findstr :{HTTP_PORT} ^| findstr LISTENING\') do taskkill /f /pid %a',
                shell=True, capture_output=True, text=True
            )

Tainted flow: 'HTTP_PORT' from os.environ.get (line 39, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · sonos_core.py (reported line 119)May include surrounding context.

python
if platform.system() == "Windows":
        # Use netstat to find and kill the process on the port
        try:
            result = subprocess.run(
                f'for /f "tokens=5" %a in (\'netstat -aon ^| findstr :{HTTP_PORT} ^| findstr LISTENING\') do taskkill /f /pid %a',
                shell=True, capture_output=True, text=True
            )

Tainted flow: 'HTTP_PORT' from os.environ.get (line 39, credential/environment) → os.system (code execution)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · sonos_core.py (reported line 126)May include surrounding context.

python
except:
            pass
    else:
        os.system(f"lsof -ti:{HTTP_PORT} | xargs kill -9 2>/dev/null")
        os.system(f"pkill -9 -f 'python3 -m http.server {HTTP_PORT}' 2>/dev/null")

Tainted flow: 'HTTP_PORT' from os.environ.get (line 39, credential/environment) → os.system (code execution)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · sonos_core.py (reported line 127)May include surrounding context.

python
pass
    else:
        os.system(f"lsof -ti:{HTTP_PORT} | xargs kill -9 2>/dev/null")
        os.system(f"pkill -9 -f 'python3 -m http.server {HTTP_PORT}' 2>/dev/null")


def is_external_input(uri):

Static analysis

No suspicious patterns detected.