Back to skill

Security audit

alibabacloud-oss-direct-access-link-diagnosis

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a read-only Alibaba OSS diagnostic, but it needs Review because it contradicts that promise by emitting ACL-changing remediation commands and exposing account bucket names without explicit opt-in.

Install only with a narrowly scoped read-only RAM policy and do not grant OSS mutation permissions to the diagnostic credential. Treat any `ossutil set-acl` or recursive `-r` remediation as a separate manual change that needs independent review, object-level scoping, and confirmation because it can make private objects inherit a public bucket ACL. Provide the exact bucket name instead of relying on auto-enumeration, and expect public Alibaba Cloud doc lookups plus a local cache under your home directory.

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

Error
Location
scripts/oss_direct_access_diagnosis.py:1597
Finding

Unscoped Recursive ACL Remediation Can Publicly Expose Private Objects

Content
View full analysis

Vulnerability Details

File Location: scripts/oss_direct_access_diagnosis.py:1597-1604
Additional Locations: SKILL.md:155,220; references/ec-0003-00000005-bisection.md:76-87
Vulnerability Type: Unsafe permission-changing remediation guidance
Risk Level: High

Technical Analysis

When an anonymous probe receives HTTP 403 on a non-private bucket and GetObjectAcl identifies a private object ACL, the Skill recommends changing the ACL to default. It also suggests adding the recursive -r option for a batch of objects:

python
elif verdict == "object_acl_private_403":
    next_action = (
        "EC 0003-00000005 cause-1 CONFIRMED: the object carries "
        "its own private ACL on a public-read bucket -- reset it "
        "to inherit the bucket ACL manually (ossutil set-acl "
        "oss://<BUCKET>/<OBJECT_KEY> default; add -r for a batch "
        "of affected objects), then re-test the link.")

The referenced procedure supplies the corresponding bucket-wide recursive command:

bash
ossutil set-acl oss://<BUCKET>/<OBJECT_KEY> default -e oss-cn-<REGION>.aliyuncs.com
bash
ossutil set-acl oss://<BUCKET>/ default -r -e oss-cn-<REGION>.aliyuncs.com

Resetting an object ACL to default causes it to inherit the bucket ACL. If the bucket is public-read, an object that was intentionally private becomes anonymously readable. The recursive command targets the bucket root and may therefore alter every matching object rather than only the object whose ACL was diagnosed.

This behavior also conflicts with the stated read-only boundary in SKILL.md:28, which prohibits generating commands for ACL or configuration changes. Although the Skill does not execute the command itself, it presents the mutation as the recommended next action without a mandatory object inventory, dry run, effective-permission preview, scope constraint, or explicit disclosure confirmation.

No evidence indicates that this inconsistency is inten ...[truncated 1756 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove executable ossutil set-acl commands from the Skill output and referenced documentation to preserve the declared read-only boundary.
  2. Do not recommend -r or any bucket-root recursive ACL operation as a default remediation.
  3. Limit guidance to the exact object for which GetObjectAcl confirmed an explicit private ACL.
  4. Before suggesting any ACL change, clearly display:
    • the current object ACL;
    • the bucket ACL that would be inherited;
    • whether the resulting object would become anonymously readable;
    • the exact object key and affected scope.
  5. Require separate, explicit user confirmation for each permission-changing operation. Batch remediation should require an independently reviewed object manifest and a second confirmation.
  6. Prefer console-oriented explanatory guidance rather than copy-paste mutation commands.
  7. If an external remediation tool is introduced, provide a dry-run mode that lists every affected object and its before/after effective access.
  8. Add regression checks ensuring that read-only diagnostic output never emits mutating OSS commands, including set-acl, recursive ACL changes, Put*, or Delete* operations.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • 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
Findings (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The description promises 'templates only' and 'never writes', but the documented behavior includes fetching online docs and caching them under the user's home directory. This mismatch is dangerous because operators may authorize the skill under a read-only trust model while it actually performs undeclared network and local write actions.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The description promises 'templates only' and 'never writes', but the documented behavior includes fetching online docs and caching them under the user's home directory. This mismatch is dangerous because operators may authorize the skill under a read-only trust model while it actually performs undeclared network and local write actions.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares no explicit tool scope, yet the content requires shell, network, environment-based credential resolution, and local file writes via caching. Without an allowlist or permission boundary, an agent runtime could grant broader capabilities than intended, increasing the blast radius if the skill is misused or prompt-injected.

Content

No source excerpt is available for this finding.

Unrestricted Tool Access

Medium
Category
Excessive Agency
Confidence
88% confidence
Finding

The skill operationally depends on command execution but does not constrain that power through a machine-enforceable boundary; relying on prose like 'only run scripts under scripts/' is not sufficient. In an adversarial or prompt-injected setting, unrestricted shell access can be repurposed for unintended commands, local data access, or broader network activity.

Content

Scanner excerpt · SKILL.md (reported line 28)May include surrounding context.

md
## Absolute Rules

1. **ABSOLUTE PROHIBITION (read-only enforcement):** Under **NO** circumstances may you generate, write, or execute any command/script calling a mutating OSS API — e.g. `PutBucketReferer`, `PutBucketWebsite`, `DeleteBucketWebsite`, `PutBucketCname`/domain-binding calls, `PutObject*`, `DeleteObject*`, or any ACL/policy/configuration change. This includes commands "for the user to run manually". When a configuration change is needed, only output the standard template as text and manual guidance, and declare this skill is read-only.
2. **MANDATORY entry-point enforcement:** All diagnostics MUST be performed by running the scripts under `scripts/` (`oss_direct_access_diagnosis.py` as the entry, `sts_token.py` for identity). The Agent is forbidden from assembling its own ossutil / SDK / curl commands against the OSS control plane or bypassing the scripts — the scripts embed timeout, error degradation, and observability guarantees that ad-hoc commands lack. Read the script output, interpret it, and compose the report; do not re-implement the queries. The anonymous default-domain probe is ONLY permitted through the entry script's `--object` option.
3. **ABSOLUTE PROHIBITION (credential handling):** Never read, print, or pass AK/SK/STS tokens explicitly. The OSS SDK resolves credentials exclusively from the environment variables of the default credential chain; the identity check uses the aliyun CLI default credential chain. Never accept AK/SK from the user or from another script.
4. **NO FABRICATION:** Every conclusion must be grounded in data actually returned by GetBucketInfo / GetBucketReferer / GetBucketWebsite / ListBucketCname / ListBuckets / GetObjectAcl / GetCallerIdentity or the anonymous probe. If a query fails or returns empty, record it and state the limitation — never invent referer rules, bound domains, or response headers.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

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.

Content

Scanner excerpt · SKILL.md (reported line 105)May include surrounding context.

md
- **Page referer** (`--page-referer`): optional; the Referer header value of the embedding page, used to attribute referer false positives.
- **Query endpoint** (`--endpoint`): optional; the endpoint of the region where the bucket was created.
- **Expected region** (`--region`): optional; used to derive the query endpoint when `--endpoint` is absent.
- **UID**: can always be omitted — it is derived via `aliyun sts get-caller-identity` and used only as a traceability label. Auto-fill first, ask second: never ask the user for UID when it can be derived.

**Auto-fill declaration requirement**: Whenever any parameter is auto-filled (query endpoint defaulted, UID derived, probe skipped), the Agent MUST explicitly declare this in the response or report metadata, e.g. "query endpoint auto-defaulted to oss-cn-hangzhou.aliyuncs.com (no --endpoint/--region provided)".

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

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.

Content

Scanner excerpt · SKILL.md (reported line 248)May include surrounding context.

md
- **Page referer** (`--page-referer`): optional; the Referer header value of the embedding page, used to attribute referer false positives.
- **Query endpoint** (`--endpoint`): optional; the endpoint of the region where the bucket was created.
- **Expected region** (`--region`): optional; used to derive the query endpoint when `--endpoint` is absent.
- **UID**: can always be omitted — it is derived via `aliyun sts get-caller-identity` and used only as a traceability label. Auto-fill first, ask second: never ask the user for UID when it can be derived.

**Auto-fill declaration requirement**: Whenever any parameter is auto-filled (query endpoint defaulted, UID derived, probe skipped), the Agent MUST explicitly declare this in the response or report metadata, e.g. "query endpoint auto-defaulted to oss-cn-hangzhou.aliyuncs.com (no --endpoint/--region provided)".

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The embedded topic table includes keywords for scenarios like hotlinking/referer, video playback, app packages, and web assets, while the skill metadata explicitly says this skill must not be used for several adjacent OSS problem classes. That mismatch can cause the helper to retrieve and surface official documentation for out-of-scope user requests, increasing the chance the parent agent proceeds with diagnosis under the wrong skill and gives incorrect or unsafe guidance.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The code applies special-case security diagnostics only when the AccessDenied message matches an English phrase ('does not belong to you'). In non-English locales or with localized service responses, the logic falls back to a generic hint, which can misclassify the cause of an authorization failure and steer operators toward the wrong remediation, reducing reliability of security diagnosis.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/_oss_client.py (reported line 716)May include surrounding context.

python
"--endpoint", _STS_ENDPOINT,
           "--user-agent", user_agent()]
    try:
        result = subprocess.run(cmd, capture_output=True, text=True,
                                timeout=timeout, stdin=subprocess.DEVNULL)
    except subprocess.TimeoutExpired:
        raise CliError(f"aliyun sts get-caller-identity timed out after "

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

When --bucket is omitted, the script automatically calls ListBuckets and returns up to 30 bucket names visible to the current credential. That expands a narrowly scoped diagnosis tool into an account inventory surface and discloses potentially sensitive resource names to the caller, which can aid reconnaissance even though no writes occur.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script returns up to 30 bucket names in the structured report when no bucket is provided, without a strong user-facing warning or explicit consent. Bucket names often encode customer, environment, region, business unit, or application details, so exposing them materially increases reconnaissance value in a tool that is supposed to be narrowly diagnostic and read-only.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The code contains account-wide bucket inventory capability unrelated to the stated direct-access diagnosis purpose. Even limited enumeration of bucket names broadens privilege use and can leak internal naming, environment, tenant, or project information that an attacker can use for targeting.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

At L028 the skill says it must not generate, write, or execute mutating commands and frames itself as strictly read-only. However, L079-L082 instructs the agent to run aliyun upgrade --yes, which is a state-changing local operation; this does not mutate OSS, but it contradicts the broader read-only framing of the comments and rules.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

Instructing an in-place CLI upgrade without an explicit warning can cause unintended local system changes, which is risky in agent-driven environments where users may assume the skill is strictly diagnostic. While the impact is limited to the local toolchain, it violates least surprise and can disrupt existing workflows.

Content

No source excerpt is available for this finding.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · scripts/_oss_client.py (reported line 291)May include surrounding context.

python
def __getattr__(self, name):
        handle = object.__getattribute__(self, "_handle")
        attr = getattr(handle, name)
        if name.startswith("_") or not callable(attr):
            return attr

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The _doc_verification path analyzes the customer's original question and consults a documentation-topic lookup subsystem to augment results. That is broader than the manifest's concrete OSS diagnosis operations and introduces a generic consultative capability not described in the manifest.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.