Back to skill

Security audit

九马免费图片编辑

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent cloud image-editing tool, but it needs review because it uploads images to a third party and persists a reusable API key without strong local protections.

Install only if you are comfortable sending images and prompts to Jiuma's cloud service. Avoid sensitive photos, confidential work, or regulated data. If you log in, treat the saved Jiuma API key as a local secret and consider deleting or permission-hardening the .jiuma key file after use.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Warning
Location
utils.py:75
Finding

API Key Stored Without Enforced File Permissions

Content
View full analysis

Vulnerability Details

File Location: utils.py, lines 5-7 and 75-77
Vulnerability Type: Plaintext credential storage with inherited permissions
Risk Level: Medium

Vulnerable Code

python
JIUMA_API_KEY_SAVE_DIR = f"{os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))}/.jiuma"
os.makedirs(JIUMA_API_KEY_SAVE_DIR, exist_ok=True)
JIUMA_API_KEY_SAVE_PATH = f"{JIUMA_API_KEY_SAVE_DIR}/jiuma_api_key"
python
def save_jiuma_api_key(api_key):
    with open(JIUMA_API_KEY_SAVE_PATH, "w") as f:
        f.write(api_key)

Technical Analysis

The API key is written as plaintext using the process's default umask. The code does not explicitly restrict the directory to mode 0700 or the credential file to mode 0600. Therefore, the effective permissions depend on the host configuration and may allow other local users or processes to read the credential.

This also conflicts with the documentation's assertion that only the current user can read the key. Plaintext storage is not inherently avoidable for every command-line application, but enforcing owner-only access is the minimum necessary protection for a reusable API credential.

Attack Path

  1. The user completes the QR login workflow.
  2. login.py obtains a secret_key from the remote service.
  3. save_jiuma_api_key() creates or overwrites .jiuma/jiuma_api_key using inherited permissions.
  4. On a system with a permissive umask, another local account or compromised process reads the file.
  5. The attacker submits requests to the Jiuma API using the stolen key.

Exploitation requires local filesystem access and sufficiently permissive effective permissions.

Impact Assessment

A successful attacker can obtain the stored Jiuma API credential and exercise the API privileges associated with the victim's account. This may consume the victim's quota, submit unauthorized image-processing jobs, or expose a ...[truncated 181 chars]

Remediation
View remediation

Remediation Suggestions

  • Create the credential directory with owner-only permissions:
    python
    os.makedirs(JIUMA_API_KEY_SAVE_DIR, mode=0o700, exist_ok=True)
    os.chmod(JIUMA_API_KEY_SAVE_DIR, 0o700)
    
  • Create the key file atomically with mode 0600, preferably using os.open() with O_CREAT | O_WRONLY | O_TRUNC and an explicit mode.
  • Write to a protected temporary file and atomically replace the destination to avoid partial writes.
  • Check and correct permissions on existing key files before reading them.
  • Where available, use an operating-system credential store instead of a plaintext file.
  • Never print the API key or include it in exceptions and diagnostic logs.

T09 · Insecure Skill Coding Practices

Warning
Location
login.py:24
Finding

Login Access Token Exposed in URL Query String

Content
View full analysis

Vulnerability Details

File Location: login.py, lines 24-25
Vulnerability Type: Sensitive token transmitted in a URL query parameter
Risk Level: Medium

Vulnerable Code

python
def check_login_status(access_token):
    data, message = jiuma_request(f"{CHECK_API}?rand_string={access_token}")

Technical Analysis

The login access token is interpolated directly into the request URL. Although the endpoint uses HTTPS, query strings are routinely retained by web servers, reverse proxies, monitoring systems, error trackers, and network diagnostics. HTTPS protects the token in transit from passive network observers but does not prevent endpoint infrastructure from logging the complete URL.

The request helper uses POST, so the token could instead be sent in the request body or an authorization header. Placing it in the URL exceeds the minimum exposure necessary for checking login status.

Attack Path

  1. The user obtains a temporary login token through the QR login endpoint.
  2. The user invokes login.py --check --access_token ....
  3. The token is appended to the URL as rand_string.
  4. A server, proxy, monitoring agent, or diagnostic system records the complete URL.
  5. An attacker with access to those logs extracts the token while it remains valid.
  6. The attacker replays the token against the login-status endpoint and may obtain the resulting API credential, depending on token validity and server-side controls.

Successful exploitation depends on access to URL logs, an unexpired token, and the remote API permitting token replay.

Impact Assessment

Exposure may allow unauthorized login-status checks and potentially retrieval of the API key associated with the completed login flow. If credential retrieval is possible through replay, the attacker may acquire the same Jiuma API privileges as the victim. This issue does not independently provide local system privileges.

Remediation
View remediation

Remediation Suggestions

  • Send rand_string in the HTTPS POST body:
    python
    data, message = jiuma_request(
        CHECK_API,
        data={"rand_string": access_token}
    )
    
  • If supported by the service, use an authorization header rather than either a query parameter or body field.
  • Configure client, proxy, and server logging to redact login tokens.
  • Make login tokens short-lived, single-use, and bound to the initiating login session.
  • Reject replay after successful credential retrieval.
  • Avoid including token values in exception messages or command output.

T08 · Insecure Dependencies

Note
Location
SKILL.md:378
Finding

Unpinned Third-Party Dependency Installation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, line 378; LOGIN.md, line 14
Vulnerability Type: Unpinned dependency and non-reproducible installation
Risk Level: Low

Vulnerable Code

SKILL.md:

bash
pip install requests

LOGIN.md:

bash
pip install requests

Technical Analysis

The installation instructions retrieve the latest package version available under the requests package name without a version constraint, lock file, or integrity hash. The package name itself is legitimate, and the reviewed project contains no evidence of dependency confusion or typosquatting. However, installation is not reproducible and implicitly trusts any future version delivered by the configured package index.

A compromised package index, compromised upstream release, maliciously configured package source, or incompatible future release could introduce unexpected code during installation or runtime.

Attack Path

  1. A user follows the documented installation command.
  2. pip resolves requests and its transitive dependencies from the user's configured package index.
  3. The index supplies a future, compromised, or otherwise unintended release.
  4. Package installation or subsequent import executes affected dependency code in the user's Python environment.
  5. That code runs with the privileges of the user performing the installation or invoking the Skill.

This path requires compromise or manipulation of the dependency source or release chain; the audited code does not itself provide that capability.

Impact Assessment

A malicious dependency could access files, environment variables, network resources, and credentials available to the invoking user. If installation is performed with administrative privileges, impact could extend to the wider system. Under normal non-privileged installation, scope is limited to the installing user's permissions and environment.

Remediation
View remediation

Remediation Suggestions

  • Declare an audited, compatible version range or exact version in a requirements file.
  • Use a lock file or hash-checked requirements, for example:
    text
    requests==<audited-version> --hash=sha256:<verified-hash>
    
  • Pin and review transitive dependencies as well as the direct dependency.
  • Install into a dedicated virtual environment without administrative privileges.
  • Use a trusted package index explicitly and review dependency updates before adoption.
  • Add automated dependency vulnerability scanning and scheduled lock-file updates.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is presented as an image-editing tool, but the documented workflow also includes QR-based login, polling authentication state, retrieving an access token/API key, and storing credentials locally. That is a significant behavior expansion involving authentication and secret handling, which users may not expect when invoking a media-editing skill and which increases the risk of credential misuse or exfiltration.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill documents capabilities that involve reading local files, writing locally saved credentials, and making network requests, but it declares no explicit tool scope or permission boundaries. This weakens least-privilege controls and makes it easier for an agent or user to invoke broader capabilities than expected, especially when handling local images and login artifacts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill explains editing features but does not clearly warn that user-provided local images and remote image URLs are sent to a third-party cloud service for processing. This can expose sensitive personal, confidential, or copyrighted content to an external provider without informed user consent, which is especially risky for image-editing workflows that often involve private photos.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The instruction to 'record to memory' asks the agent to retain information beyond the immediate task, which can conflict with expected data-minimization and privacy boundaries. In a skill that may process user images, prompts, login state, or credential-related workflow details, encouraging persistent retention increases the chance of unnecessary storage of sensitive operational context.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

This endpoint definition confirms that the skill is designed to transmit data to an external service. In the context of an image-editing skill that can open local files and upload them, external transmission is security-relevant because sensitive images and associated prompts may leave the local environment and be processed by a third party.

Content

Scanner excerpt · agent.py (reported line 12)May include surrounding context.

python
from utils import get_jiuma_api_key, output_result, jiuma_request

SUBMIT_API = "https://api.jiuma.com/api/imageEdit/add"
CHECK_STATUS_API = "https://api.jiuma.com/api/imageEdit/status"

MIME_MAP = {

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

The status-check endpoint is another external API dependency and part of the same third-party data flow. While checking status is less sensitive than uploading the image itself, it still sends task identifiers externally and reinforces that user activity and generated asset metadata are exposed to an outside service.

Content

Scanner excerpt · agent.py (reported line 13)May include surrounding context.

python
from utils import get_jiuma_api_key, output_result, jiuma_request

SUBMIT_API = "https://api.jiuma.com/api/imageEdit/add"
CHECK_STATUS_API = "https://api.jiuma.com/api/imageEdit/status"

MIME_MAP = {
    # 图片

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill submits user-provided images and prompts to a third-party service, but the code does not provide any explicit consent flow, warning, or privacy notice at the point of upload. This can cause unintended disclosure of sensitive local image contents to an external API, especially because the tool accepts local file paths and silently uploads those files when --submit is used.

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 · login.py (reported line 5)May include surrounding context.

python
from utils import jiuma_request, output_result, save_jiuma_api_key

LOGIN_API = "https://api.jiuma.com/user/getLoginQrcode"
CHECK_API = "https://api.jiuma.com/user/checkLoginStatus"

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 · login.py (reported line 6)May include surrounding context.

python
from utils import jiuma_request, output_result, save_jiuma_api_key

LOGIN_API = "https://api.jiuma.com/user/getLoginQrcode"
CHECK_API = "https://api.jiuma.com/user/checkLoginStatus"

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest describes a skill for editing images via the Jiuma AI API, including fusion editing of up to three images. This file instead implements a login flow that retrieves a login QR code, checks login status, and saves a secret API key, which is account/authentication management rather than image editing behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The code stores the returned secret_key via save_jiuma_api_key() immediately after login without any visible consent prompt, disclosure of persistence, or indication of storage location/protection. Persisting API credentials silently increases the risk of unintended credential retention, local leakage, or later misuse by other components on the system.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This function sends arbitrary data, headers, and uploaded files to a remote API via requests.post, which can transmit user or system data off-host. Although error logging exists, there is no user-facing disclosure or inline documentation warning that data and files may be sent to an external service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill persists the Jiuma API key to a predictable file path on disk without any disclosure, encryption, or permission hardening. On multi-user systems or environments where the workspace is shared, this can expose a reusable secret to other local users, processes, backups, or logs, enabling unauthorized use of the external API.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill notes that edited images are returned via cloud URLs, but it does not clearly warn users that the outputs may remain hosted remotely and accessible through those links for some period. Even if the URLs are time-limited, storing edited images on third-party infrastructure can create privacy and sharing risks if users assume the outputs are only local.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The natural-language descriptions, help text, and user-facing messages are presented only in Chinese, which forces a specific language experience without user opt-in. No justification or documented locale constraint is provided to show that the skill is intentionally region-specific.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.