T09 · Insecure Skill Coding Practices
- Location
scripts/hifly_client.py:10- Finding
Hardcoded Shared Bearer Token Used as an Automatic Fallback
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill does what it claims, but it handles face and voice media, uploads local files to a third-party service, and uses a shared embedded API token with too little user-facing safety and privacy control.
Review this skill before installing. Only upload images and voice samples you own or have explicit permission to use, assume those files and prompts are sent to Flyworks/HiFly infrastructure, set your own API token only if you understand account and quota impact, and prefer a pinned, project-local installation in an isolated environment.
scripts/hifly_client.py:10Hardcoded Shared Bearer Token Used as an Automatic Fallback
requirements.txt:1Unpinned Python Dependency Produces Non-Reproducible and Unsafe Builds
README.md:16Installation Instructions Execute an Unpinned npx Package and Install an Unpinned Repository Revision
The documented behavior goes beyond the declared purpose by relying on an embedded default API token and persisting aliases in memory.json without clearly surfacing those behaviors as security- and privacy-relevant features. Hidden credentials can be abused for unauthorized third-party API use, and undeclared persistence can retain sensitive identifiers or user-specific data longer than expected.
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.
## Features
- 🎬 **Public Avatar Video**: Create videos using pre-made realistic avatars with TTS
- 🖼️ **Talking Photo**: Turn any image into a talking video
- 🎙️ **Voice Cloning**: Clone voices from audio samples
The README promotes talking-photo generation and voice cloning from user-supplied images/audio but does not warn about consent, biometric/privacy sensitivity, or the risks of uploading personal media to a third-party service. In this context, the omission is meaningful because the skill is specifically designed to process highly sensitive likeness and voice data, which could lead users to misuse the feature or expose personal data without informed consent.
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.
The skill advertises and documents capabilities that read environment variables, access local files, write to local state, and make network requests, but it does not declare any tool scope or allowed-tools boundary. That increases the chance an agent will invoke broader-than-expected capabilities without explicit operator review, especially when handling user-supplied paths, media, and remote URLs.
Voice cloning is a sensitive biometric and impersonation capability, and the skill describes it as a normal feature without requiring consent or warning about privacy, fraud, or misuse risks. In this context, omission of consent and safety guidance makes accidental or abusive impersonation substantially easier.
The examples instruct users to upload custom photos and audio, including potentially sensitive personal media, to a remote service without clearly warning that data will leave the local environment. In a skill centered on avatars and voice cloning, that omission is materially risky because facial images and voice samples are highly sensitive and can enable identity misuse if mishandled.
The skill documents creating talking-photo avatars from arbitrary portrait images, including remote image URLs, without any warning about consent, privacy, rights of use, or biometric-data sensitivity. This can enable non-consensual avatar generation or misuse of third-party images, which is especially risky in a digital-human/video generation context where impersonation and deceptive media are plausible outcomes.
The documentation instructs users to upload or reference audio samples for voice cloning without any warning about obtaining consent, protecting biometric voice data, or the fact that samples may be transmitted to an external service. Because cloned voices can enable impersonation, privacy violations, and misuse of sensitive audio, omission of these safeguards creates a real security and abuse-enablement risk in the skill.
The script embeds a working default API token and automatically uses it when no user token is configured. This enables anyone running the skill to consume a third-party account or service allocation without explicit authorization, and normalizes secret-in-code practices that can lead to abuse, quota exhaustion, and account misuse.
The skill accepts local file paths and uploads those files to a remote third-party service with no explicit consent prompt or strong disclosure at the point of transmission. In an agent-skill context, this increases the risk of accidental exfiltration of sensitive local files if a user or upstream tool passes an unintended path.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
headers = get_headers()
try:
resp = requests.post(url, headers=headers, json=payload)
resp.raise_for_status()
data = resp.json()
if data.get("code", 0) != 0:
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
headers = get_headers()
try:
resp = requests.post(url, headers=headers, json=payload)
resp.raise_for_status()
data = resp.json()
if data.get("code", 0) != 0:
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
headers = get_headers()
try:
resp = requests.post(url, headers=headers, json=payload)
resp.raise_for_status()
data = resp.json()
if data.get("code", 0) != 0:
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
headers = get_headers()
try:
resp = requests.post(url, headers=headers, json=payload)
resp.raise_for_status()
data = resp.json()
if data.get("code", 0) != 0:
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
headers = get_headers()
try:
resp = requests.post(url, headers=headers, json=payload)
resp.raise_for_status()
data = resp.json()
if data.get("code", 0) != 0:
The code trusts an upload URL returned by a remote API and then performs a PUT of a local file directly to that URL without validating the destination host, scheme, or expected storage provider. If the API is compromised or returns an unexpected presigned URL, the client will exfiltrate arbitrary local file contents to an attacker-controlled endpoint.
print(f"Uploading {file_path.name}...")
with open(file_path, 'rb') as f:
headers_put = {"Content-Type": content_type}
resp_put = requests.put(upload_url, data=f, headers=headers_put)
resp_put.raise_for_status()
print(f"Upload successful. File ID: {file_id}")
The README instructs users to provide their own API token for non-demo usage without warning that doing so may incur charges, consume account quotas, or expose the user's external account to unintended actions. While not a code-execution flaw, it is a real safety issue because agents or users may proceed without understanding the financial/account impact of enabling live credentials.
The dependency manifest specifies requests without a version pin, which makes builds non-reproducible and can pull in unexpectedly old or newly broken releases depending on the installation environment. In a skill that likely performs outbound API calls for avatar/video generation, this increases supply-chain and maintenance risk because security posture depends on whichever version gets resolved at install time.
requests
Because requests is unpinned, it is impossible to verify from this manifest whether installation will select a version affected by known advisories, including issues involving credential leakage or TLS/request verification behavior. For a network-integrating skill, that uncertainty is meaningful: if deployed in an environment that resolves an affected release, API tokens, session behavior, or request handling could be exposed to known weaknesses.
save_memory persistently writes alias mappings to memory.json, but there is no prior warning that user-provided aliases and IDs will be stored on disk. The later success message confirms saving occurred, but it does not serve as advance disclosure of the file write behavior.
The comment at L227 states 'Should call create_video_tts but here we are,' indicating the documented intent for text input is to invoke TTS handling. The actual code instead rejects text input with an error and returns, so the inline documentation explicitly conflicts with runtime behavior.
No suspicious patterns detected.