T09 · Insecure Skill Coding Practices
- Location
web/app.py:42- Finding
Arbitrary File Overwrite and Deletion Through Unsanitized Upload Filename
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This appears to be a real LRC lyric editor, but its unauthenticated network service exposes unsafe upload handling and a shutdown endpoint.
Review carefully before installing. Run it only in a trusted local environment, preferably bound to localhost rather than all interfaces, and avoid using it on shared or privileged accounts until the upload path handling, shutdown route, dependency pinning, and resource limits are fixed.
web/app.py:42Arbitrary File Overwrite and Deletion Through Unsanitized Upload Filename
web/app.py:63Unauthenticated Network-Accessible Service Shutdown
web/app.py:22Unauthenticated Audio Processing Enables Resource Exhaustion
start_server.py:6Mutable Dependencies Are Installed Automatically at Runtime
web/templates/index.html:7Third-Party Browser Scripts Are Loaded Without Integrity Verification
The skill description materially overstates implemented functionality while omitting an extra shutdown capability, which is a trust and security problem in agent-distributed skills. Users may expose files, run the service, or rely on data-handling guarantees that do not exist, and the undocumented shutdown endpoint widens the attack surface beyond the declared purpose.
The /shutdown route allows any requester to terminate the entire Flask process with no authentication, authorization, or local-only restriction. For an LRC editing service, remote process termination is unnecessary to core functionality and creates an easy denial-of-service condition for anyone who can reach the port.
Exposing a visible 'close service' control in an LRC editor introduces an operational capability unrelated to the tool's editing purpose. This increases the attack surface by advertising a backend termination path that can be abused for denial of service if the shutdown endpoint is reachable without strong authorization.
The client issues a POST request to /shutdown, enabling backend termination from browser-accessible code. In context, this is dangerous because an LRC editor should not let ordinary page interactions stop the service; if server-side controls are weak, this can become a trivial denial-of-service vector.
The skill documentation instructs users to run a Python server that can install dependencies and use shell-level execution, but it does not declare any explicit tool scope or permissions boundary. In an agent ecosystem, undocumented shell capability increases the chance of unintended command execution and makes risk review, policy enforcement, and user consent weaker.
Natural-language policy violations include forcing a specific language without user opt-in. The entire skill description and invocation guidance are presented only in Chinese, and the file does not indicate that the user may choose another language or that the skill is intentionally limited to a Chinese-language audience.
Automatically installing Python packages on startup exceeds what a user would reasonably expect from an LRC editing tool and causes code from external repositories to be fetched and executed implicitly. This creates a supply-chain attack surface and can alter the host environment without informed consent.
The script installs packages via pip without meaningful upfront consent, only emitting status messages as it proceeds. Users may not realize the tool will download and execute third-party package installation logic, which increases risk to the local environment and reduces transparency.
The script invokes pip in a subprocess to install packages at runtime. While the package names are hard-coded and there is no shell injection here, dynamically modifying the Python environment during startup introduces supply-chain and integrity risk, especially if package indexes, dependency resolution, or network paths are compromised.
def install_package(package):
"""安装Python包"""
subprocess.check_call([sys.executable, "-m", "pip", "install", package])
def check_dependencies():
"""检查并安装依赖"""
The skill is presented as a lyric authoring web tool, but this file uses subprocess execution to run pip and launch another Python process. Spawning subprocesses is a powerful capability that is not mentioned in the manifest and is not inherently part of LRC editing functionality.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
print("访问地址: http://localhost:698")
print("按 Ctrl+C 停止服务")
subprocess.run([sys.executable, "app.py"])
This endpoint performs a destructive action solely via an unauthenticated POST request, so any local or remote party with network access can stop the service instantly. Even if intended as a convenience feature, exposing process termination through the application interface materially weakens availability and may also be triggerable by cross-site requests if the service is used from a browser.
The page declares zh-CN as the document language and presents the title and interface text in Chinese, with no indication that language selection is optional or region-specific. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation.
The page loads executable JavaScript directly from third-party CDNs, which expands trust beyond the stated local lyric-editing scope. If the CDN, dependency, or delivery path is compromised, arbitrary script can execute in the app context and access local lyric data, browser storage, and UI actions.
This code automatically stores the user's lyric data and uploaded file name in browser localStorage, which persists across sessions and may expose creative content or metadata to other users of the same browser profile. There is no visible notice in the UI, comment, or other user-facing disclosure that imported or edited data will be retained locally.
For markdown files, missing-warning findings apply when the description omits warnings about behaviors affecting user data or privacy. The document advertises automatic saving to browser local storage, but only later mentions recovery behavior; it does not upfront warn that edited lyric content remains stored locally on the device/browser.
The script's natural-language strings and comments are consistently in Chinese, including operational output shown to the user. Under the policy, forcing a specific language without opt-in can be a locale/language policy violation unless the restriction is clearly justified or optional.
The file includes Chinese-only natural-language strings in comments, docstrings, and API error/status messages such as '没有选择文件' and '服务已关闭'. This enforces a specific language for user-visible behavior without any opt-in, language selection, or justification that the skill is intentionally region-specific.
The dependency is specified with a lower bound only, which allows future installs to resolve to different Flask versions over time. This weakens reproducibility and makes it impossible to verify whether deployed versions include known security fixes or newly introduced vulnerable releases.
flask>=2.3.0
pydub>=0.25.1
numpy>=1.24.0
Flask has known advisories, and because the manifest does not pin an exact version, there is no reliable way to determine whether the installed package is affected. For a Flask-backed web skill exposed on a network port, this uncertainty increases operational risk because deployment may resolve to an insecure version.
Using pydub with only a minimum version makes builds non-deterministic and can pull in different versions across environments. While this is primarily a supply-chain hygiene issue, it can expose deployments to unreviewed or vulnerable upstream releases.
flask>=2.3.0
pydub>=0.25.1
numpy>=1.24.0
The unpinned numpy requirement permits installation of any version at or above 1.24.0, preventing reliable verification of security posture and behavior. In practice, this can lead to inconsistent environments and accidental exposure to vulnerable or incompatible releases.
flask>=2.3.0
pydub>=0.25.1
numpy>=1.24.0
NumPy has multiple published advisories, and the unpinned requirement means the actual installed release cannot be verified from this file alone. Although numpy is not typically the primary attack surface in this application, unverifiable versions still create avoidable supply-chain and maintenance risk.
No suspicious patterns detected.