Back to skill

Security audit

Bijian AI Writing Expert

Security checks for vulnerabilities and agentic risk

Overview

The skill is a writing helper for Bijian AI, but it loads workspace configuration as shell code and can send tokens and article content to an unpinned API destination.

Review before installing. Use only a trusted, private `.bijian_config`, do not place shell commands in it, and avoid workspace-supplied configs. Keep the API URL pinned to the legitimate Bijian HTTPS endpoint, use a limited-scope token if available, and do not provide confidential notes, credentials, unpublished business material, or private documents as reference content unless you intend to send them to Bijian.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:32
Finding
Executable Workspace Configuration Enables Arbitrary Shell Command Execution<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 32-35 **Vulnerability Type**: Executable configuration file / arbitrary command execution **Risk Level**: High ### Vulnerable Code ```bash CONFIG_FILE="${OPENCLAW_WORKSPACE}/.bijian_config" [ -f "$CONFIG_FILE" ] || CONFIG_FILE="$HOME/.openclaw/workspace/.bijian_config" [ -f "$CONFIG_FILE" ] && source "$CONFIG_FILE" && echo "✅ 配置已加载" || echo "❌ 请创建 .bijian_config" ``` The same configuration file is sourced before the documented API operations: ```bash source "$CONFIG_FILE" && python3 scripts/bijian_api.py spaces ``` ```bash source "$CONFIG_FILE" && python3 scripts/bijian_api.py generate \ --space-id ${SPACE_ID} \ --topic-theme "${TOPIC_THEME}" \ --viewpoints "${VIEWPOINTS}" \ --reference-content "${REFERENCE_CONTENT}" \ --user-require "${USER_REQUIRE}" \ --is-need-picture false ``` ### Technical Analysis The workflow uses the shell `source` command to load `.bijian_config`. Unlike a data-only configuration parser, `source` interprets the entire file as shell code. The documented sample contains only environment-variable declarations, but no validation restricts the file to those declarations. The preferred file is taken directly from the workspace identified by `OPENCLAW_WORKSPACE`. A malicious or compromised project, archive, shared workspace, or prior process could therefore place commands in `.bijian_config`. When the Agent follows the documented workflow, those commands execute before the Python API client. For example, a malicious configuration could combine apparently valid settings with arbitrary commands: ```bash export BIJIAN_API_TOKEN='token' export BIJIAN_BASE_URL='https://bj.aizmjx.com/api' arbitrary_attacker_command ``` This is an unsafe configuration-loading pattern even though the audited project does not itself contain a malicious `.bijian_config`. ### Attack Path 1. An attacker gains the ability to supply or modify `<workspace>/.bijian_config`, such a ...[truncated 1263 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not execute configuration files with `source`, `.`, `eval`, or an equivalent shell mechanism. 2. Store configuration in a data-only format such as JSON, TOML, or a strictly parsed dotenv file. 3. Parse only an explicit allowlist of fields: - `BIJIAN_API_TOKEN` - `BIJIAN_TOKEN_HEADER` - `BIJIAN_TOKEN_PREFIX` - `BIJIAN_BASE_URL` - `BIJIAN_USER_ID` 4. Reject command substitutions, shell metacharacters, multiline values, unexpected keys, and malformed quoting. 5. Prefer reading configuration directly in `bijian_api.py` instead of passing it through a shell. 6. Require the configuration file to have restrictive permissions, such as mode `0600`, and verify that it is owned by the expected user. 7. Prefer a trusted user configuration directory over a project-controlled workspace. If workspace configuration must be supported, require explicit user approval before loading it. 8. Document that configuration files must be treated as sensitive data and must never be committed to source control. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/bijian_api.py:26
Finding
Unrestricted API Base URL Can Redirect Credentials and Article Content<![CDATA[ ## Vulnerability Details **File Location**: `scripts/bijian_api.py`, lines 26-58 **Vulnerability Type**: Credential exfiltration through an unrestricted network destination **Risk Level**: High ### Vulnerable Code ```python class BijianClient: def __init__(self): self.base_url = env("BIJIAN_BASE_URL", "https://bj.aizmjx.com/api").rstrip("/") self.token = env("BIJIAN_API_TOKEN") self.token_header = env("BIJIAN_TOKEN_HEADER", "Authorization") self.token_prefix = env("BIJIAN_TOKEN_PREFIX", "Bearer") self.user_id = env("BIJIAN_USER_ID") def _headers(self): h = { "Content-Type": "application/json", "Accept": "application/json", } if self.token: if self.token_prefix: h[self.token_header] = f"{self.token_prefix} {self.token}".strip() else: h[self.token_header] = self.token return h def _request(self, method: str, path: str, query=None, body=None): query = dict(query or {}) # fallback user context (for endpoints expecting injected userId) if self.user_id and "userId" not in query: query["userId"] = self.user_id url = f"{self.base_url}{path}" if query: url = f"{url}?{urlencode(query)}" data = None if body is not None: data = json.dumps(body, ensure_ascii=False).encode("utf-8") req = urllib.request.Request(url=url, data=data, headers=self._headers(), method=method) try: with urllib.request.urlopen(req, timeout=30) as resp: raw = resp.read().decode("utf-8", errors="ignore") return resp.getcode(), self._maybe_json(raw) ``` ### Technical Analysis `BIJIAN_BASE_URL` controls the complete scheme and network origin used for API requests. The client does not enforce HTTPS and does not verify that the destination belongs to the expected Bijian service. ...[truncated 2496 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin the production API origin to the documented endpoint instead of accepting an arbitrary base URL. 2. If configurability is required, parse the URL and enforce: - Scheme exactly equal to `https`. - Hostname on an explicit allowlist, such as `bj.aizmjx.com`. - An expected port, normally `443`. - An approved API path prefix. - No embedded username or password. 3. Validate the destination again immediately before creating the request. 4. Apply authorization headers only when the validated request origin exactly matches the trusted API origin. 5. Disable cross-origin redirects for credential-bearing requests, or strip sensitive headers and reject any redirect whose origin differs from the original trusted origin. 6. Do not allow workspace-controlled configuration to override security-sensitive destination restrictions. 7. Separate sensitive credentials from ordinary project configuration and load them from a trusted secret store where available. 8. Add automated tests confirming that HTTP URLs, lookalike domains, user-info URLs, unexpected ports, and cross-origin redirects are rejected before any credential is transmitted. ]]>
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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (5)

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill invokes environment access and outbound network activity by sourcing a local config file and calling an external API, but it does not declare any explicit tool scope or permission boundary. This weakens reviewability and least-privilege controls, making it easier for a skill with code-like behavior to access secrets or transmit data without clear governance.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The manifest description specifies Chinese trigger phrases and the skill content consistently instructs the agent to interact in Chinese, but it does not offer any language choice or indicate that Chinese is an optional mode. This is a natural-language policy concern because it imposes a specific language/locale without explicit user opt-in or a documented region-specific justification.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The workflow instructs collecting user-supplied topic, viewpoints, and reference materials and sending them to an external AI service, but it does not clearly warn users that their content will leave the local system. This creates a real data-sharing risk, especially if users include private notes, unpublished material, credentials, or proprietary documents in the reference content.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The skill exposes API operations to list spaces, enumerate styles, poll tasks, fetch arbitrary article details, and list existing articles, which goes beyond the stated purpose of generating new content. In an agent setting, these read capabilities can be abused to inventory account resources and retrieve prior content without a clear user need, increasing the risk of unauthorized data access and prompt-driven exfiltration.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The articles command supports searching and listing content by space ID and keyword, enabling bulk discovery of existing account content unrelated to the writing-assistant workflow. In a conversational agent context, this is especially dangerous because a malicious or confused prompt could induce the agent to enumerate sensitive drafts or published materials and disclose them back to the user.

Static analysis

No suspicious patterns detected.