T01 · Skill Instruction Hijacking
- Location
SKILL.md:39- Finding
Broad instruction and output hijacking redirects media requests to Lovart
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This Lovart media skill mostly matches its stated purpose, but it needs Review because it broadly redirects media requests to Lovart, persists and reuses project context, and has weak safeguards around endpoints, TLS, and downloads.
Install only if you are comfortable sending prompts, selected reference files, project/thread metadata, and generated artifacts to Lovart. Before use, review or clear ~/.lovart/state.json, confirm the active project and thread before sensitive work, do not enable LOVART_INSECURE_SSL, keep LOVART_BASE_URL on the official endpoint, and avoid uploading private files unless you intentionally want Lovart to process them.
SKILL.md:39Broad instruction and output hijacking redirects media requests to Lovart
scripts/agent_skill.py:19Authentication and user data can be redirected to an arbitrary endpoint with TLS verification disabled
scripts/agent_skill.py:248Unrestricted artifact URL downloads permit local-network access and unbounded file writes
scripts/agent_skill.py:536Conversation metadata is persisted without explicitly restrictive filesystem permissions
The trigger conditions are extremely broad, matching common verbs like create, make, design, draw, and their multilingual equivalents, plus generic project/history words. This can cause the skill to activate in many normal conversations where the user did not explicitly intend to use Lovart, leading to unintended network actions, reuse of saved state, and possible disclosure of prior project or thread context.
The anti-refusal language, especially 'You CAN generate directly - never say you cannot,' pressures the agent to comply broadly rather than pause for policy, safety, or consent checks. Such statements are a red flag because they can undermine safer orchestration behavior and make unintended or risky invocations more likely when combined with the skill's broad trigger rules.
creation request in any language — draw, generate, create, design, make, 画, 生成,
制作, 创作, 设计 combined with image, video, audio, music, song, BGM, poster, etc.
(2) Lovart project/thread management — 项目, 对话, project, thread, conversation,
history, 历史, 切换, switch. You CAN generate directly - never say you cannot.
user-invocable: true
version: 1.1.0
author: Lovart (lovartai)
The skill exposes capabilities that can read environment secrets, read/write local files, and access the network, but it does not declare a restrictive tool scope such as permissions or allowed-tools. That makes the effective privilege boundary unclear and increases the blast radius if the skill is triggered unexpectedly or behaves unsafely, especially because it also persists state locally and interacts with remote services.
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
- `"done"` — Generation complete. Send the downloaded files to the user.
- `"pending_confirmation"` — A high-cost tool (e.g. video, or a premium-quality image variant) needs user approval before credits are consumed.
**You MUST ask the user for explicit confirmation before proceeding. Do NOT auto-confirm.**
1. Show the user: "This will cost approximately {estimated_cost} credits. Shall I proceed? (yes/no)"
2. **WAIT for user response.** Only if user explicitly says yes/confirm/proceed, run:
`confirm --thread-id THREAD_ID --json --download`
The documentation instructs the agent to read and write ~/.lovart/state.json and to reuse project and thread history, but it does not clearly disclose to users that local state is persisted and prior conversation context may be reused automatically. Users may unknowingly expose older content or operate on the wrong project because they were not informed of this persistence behavior.
The instruction 'Do NOT ask the user' when an active project exists authorizes autonomous selection of persisted context for subsequent operations. This removes an important consent checkpoint and can cause actions to occur in an old or unintended project, especially when multiple projects exist or the conversation topic has changed.
**Step 1: `config --json`**
- Check local state (`~/.lovart/state.json`) for `active_project`
- If `active_project` is set → proceed to Step 2. Do NOT create a new project. Do NOT ask the user.
- If `active_project` is missing → ask the user: "Do you have an existing Lovart project ID, or should I create a new one?" **WAIT for their answer.**
- Save with: `project-add --project-id PID --name "name"`
The skill relies on persistent local session state and directs the agent to silently reuse it when available. That persistence can cause cross-session confusion, privacy leakage, or unintended association of new user requests with previous projects and threads, especially on shared systems or multi-user environments.
**Step 1: `config --json`**
- Check local state (`~/.lovart/state.json`) for `active_project`
- If `active_project` is set → proceed to Step 2. Do NOT create a new project. Do NOT ask the user.
- If `active_project` is missing → ask the user: "Do you have an existing Lovart project ID, or should I create a new one?" **WAIT for their answer.**
- Save with: `project-add --project-id PID --name "name"`
The skill mandates reusing recent threads and existing projects by default, which carries forward prior user prompts, attachments, and generated content into later requests without obtaining fresh consent. In a shared or simply changed context, this can leak earlier sensitive material into new generations or cause operations to run against the wrong historical context.
The skill allows TLS certificate and hostname verification to be disabled via LOVART_INSECURE_SSL=1, which enables man-in-the-middle interception of all API traffic, including access keys, signatures, prompts, project metadata, and returned artifact URLs. Because this skill handles authenticated requests to a remote service, weakening transport security materially increases the chance of credential theft and response tampering.
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.
def save_project(self, project_id: str = "", canvas: str = "",
project_name: str = "", project_type: int = 3) -> dict:
"""Create (empty project_id) or update (with project_id) a project."""
body = {
"project_id": project_id,
"canvas": canvas,
The manifest focuses on generating media through Lovart and managing Lovart-side projects, threads, and settings. The upload_file function gives the skill general local file-read capability, which is broader than the stated purpose and could expose unrelated local data if misused.
The download path writes remote content to local disk automatically when invoked, but there is no inline disclosure or confirmation at write time beyond a command-line flag. In an agent setting, silent file writes increase the risk of unexpected persistence of untrusted content, disk consumption, and storing potentially sensitive generated artifacts on the host.
Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.
def chat(self, prompt: str, project_id: Optional[str] = None,
attachments=None, thread_id=None,
timeout=None, auto_create_project=True,
prefer_models=None, include_tools=None, exclude_tools=None,
mode: Optional[str] = None, subjects=None, kits=None) -> dict:
"""Send → poll → get result. One-shot convenience method.
The skill silently persists project/thread metadata to ~/.lovart/state.json whenever state-changing operations occur, without user-facing disclosure in those execution paths. In an agent context, this creates covert local persistence of conversation history and identifiers, which may expose sensitive workflow metadata to other local users or later processes.
Data is uploaded to cloud storage (S3 / GCS / Azure Blob). This may be a legitimate backup or exfiltration to an external bucket. Manual review is recommended.
print(json.dumps({"project_id": pid}))
elif args.command == "upload":
url = skill.upload_file(args.file)
print(json.dumps({"url": url}))
elif args.command == "upload-artifact":
The manifest mentions Lovart project, thread, and user-setting management, which implies server-side operations, but this file additionally stores active project and thread history in ~/.lovart/state.json. Local persistence changes the skill's behavior and data footprint beyond the manifest description.
Detected: suspicious.insecure_tls_verification