Back to skill

Security audit

baidu qianfan agent chat

Security checks for vulnerabilities and agentic risk

Overview

This skill is a straightforward Baidu Qianfan chat API wrapper, with ordinary privacy cautions around sending prompts to Baidu and saving a local conversation ID.

Install only if you intend to send chat prompts and selected request metadata to Baidu Qianfan. Keep QIANFAN_API_KEY private, avoid sending sensitive data unless authorized, and delete or protect artifact/state/session.json if conversation linkage matters on your machine.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Note
Location
scripts/chat.py:24
Finding

Insecure Plaintext Session-State Storage

Content
View full analysis
Dict[str, Any]: """Load session state""" if SESSION_STATE_FILE.exists(): try: with open(SESSION_STATE_FILE, "r", encoding="utf-8") as f: return json.load(f) except Exception: pass return {} def save_session_state(state: Dict[str, Any]) -> None: """Save session state""" SESSION_STATE_FILE.parent.mkdir(parents=True, exist_ok=True) with open(SESSION_STATE_FILE, "w", encoding="utf-8") as f: json.dump(state, f, ensure_ascii=False, indent=2) ``` The state is subsequently loaded and saved as follows: ```python # Process conversation ID conversation_id = args.conversation_id if not conversation_id and not args.new_session: # Read conversation ID from state file state = load_session_state() conversation_id = state.get("conversation_id") if conversation_id: print(f"[Using saved conversation: {conversation_id}]", file=sys.stderr) # Call API result = chat( query=args.query or "", app_id=args.app_id, stream=args.stream, conversation_id=conversation_id, file_ids=file_ids, tools=tools, tool_choice=tool_choice, tool_outputs=tool_outputs, action=action, end_user_id=args.end_user_id, metadata_filter=metadata_filter, custom_metadata=custom_metadata, ) # Save conversation ID if "conversation_id" in result: save_session_state({"conversation_id": result["conversation_id"]}) ``` ### Technical Analysis The returned conversation identifier is stored in plaintext at the predictable path `state/session.json`. The code creates the directory and file wi ...[truncated 2883 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (9)

Tainted flow: 'headers' from os.environ.get (line 91, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/chat.py (reported line 123)May include surrounding context.

python
body["custom_metadata"] = custom_metadata
    
    try:
        response = requests.post(
            API_URL,
            headers=headers,
            json=body,

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill declares access to sensitive capabilities via metadata requirements and documented behavior—environment variables, local state persistence for conversation IDs, and outbound API calls—but does not define an explicit permission or allowed-tools boundary. This can lead to overbroad execution in agent environments, making it harder to constrain or audit what the skill may read, write, or send over the network.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger conditions are broad and ambiguous, including any mention of '千帆', 'qianfan', or generic need for Baidu AI chat, which can cause the skill to activate outside the user's actual intent. In an agent system with network and file capabilities, accidental activation may expose prompts, session context, or files to an external API and create unintended side effects such as persisted conversation state.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This markdown file documents request fields such as file_ids and end_user_id that can send user documents and user identifiers to a remote API, but the surrounding description does not warn readers about privacy, data handling, or external transmission implications. Under the markdown-specific SQP-2 criterion, documentation should disclose behaviors that may affect user data or privacy.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/api.md (reported line 149)May include surrounding context.

基础请求示例

bash
curl --location 'https://qianfan.baidubce.com/v2/app/conversation/runs' \
--header 'Authorization: Bearer <API Key>' \
--header 'Content-Type: application/json' \
--data '{

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The module docstring and all user-facing CLI descriptions are written exclusively in Chinese, presenting the skill as a Chinese-language tool without any opt-in or alternative language support. Under the policy, forcing a specific language without user choice is a natural-language policy concern unless the locale restriction is explicitly justified.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/chat.py (reported line 123)May include surrounding context.

python
body["custom_metadata"] = custom_metadata
    
    try:
        response = requests.post(
            API_URL,
            headers=headers,
            json=body,

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The function description states that only Chinese cities are supported and other countries are not supported, which is a locale restriction expressed in natural language. The document does not present this as an explicit user opt-in choice or provide a policy or compliance justification for excluding other locales.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script persists the conversation_id to disk automatically without notifying the user or offering an opt-in. While a conversation_id is not typically a secret like an API key, it is still session-related metadata that can leak chat linkage, create privacy surprises on shared systems, or enable unintended session reuse by other local users/processes.

Content

No source excerpt is available for this finding.