Back to skill

Security audit

Organization Operations

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real organization-platform API tool, but it handles live account tokens and production actions in ways that need careful review before installation.

Review this skill before installing if it will run with real ZingUp/Groupoo accounts. Use test mode for development, keep session files outside shared repositories, protect or rotate tokens, avoid logging authentication responses, and do not allow prompts or untrusted configuration to set --base-url or ORG_SKILL_BASE_URL for authenticated commands.

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
scripts/org_skill_cli.py:438
Finding

Bearer credentials can be transmitted to an unrestricted caller-controlled destination

Content
View full analysis
None: if auth_mode == "none": return if auth_mode == "access": token = session.get("token") if not token: raise RuntimeError("当前 session 里没有 access token,请先 guest-generate 或 agent-login。") headers["authorization"] = f"Bearer {token}" return if auth_mode == "refresh": refresh_token = session.get("refreshToken") if not refresh_token: raise RuntimeError("当前 session 里没有 refreshToken,请先登录。") headers["RefreshToken"] = f"Bearer {refresh_token}" return raise ValueError(f"不支持的 auth_mode: {auth_mode}") ``` ```python def request_json( *, method: str, base_url: str, path: str, headers: dict[str, str], query: dict[str, Any] | None = None, body: dict[str, Any] | None = None, timeout: int = DEFAULT_TIMEOUT, ) -> Any: target_path = path if path.startswith("/") else f"/{path}" base = base_url.rstrip("/") url = f"{base}{target_path}" if query: encoded = urllib.parse.urlencode({k: v for k, v in query.items() if v is not None}) if encoded: url = f"{url}?{encoded}" data = None if body is not None: data = json.dumps(body, ensure_ascii=False).encode("utf-8") request = urllib.request.Request(url=url, data=data, method=method.upper()) for key, value in headers.items(): request.add_header(key, value) try: with urll ...[truncated 3996 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/org_skill_cli.py:184
Finding

Session tokens are stored with inherited filesystem permissions and exposed in authentication command output

Content
View full analysis
None: SESSIONS_DIR.mkdir(parents=True, exist_ok=True) ``` ```python def save_session(path: Path, data: dict[str, Any]) -> None: path.parent.mkdir(parents=True, exist_ok=True) payload = dict(data) payload["updatedAt"] = now_iso() path.write_text(json.dumps(payload, ensure_ascii=False, indent=2) + "\n", encoding="utf-8") ``` ```python def cmd_guest_generate(args: argparse.Namespace) -> int: path = session_path(args) session = load_session(path) apply_header_args_to_session(session, args) base_url = resolve_base_url(args, session) device_id = resolve_device_id(args, session) headers = build_base_headers(session, device_id=device_id) response = require_success( request_json( method="POST", base_url=base_url, path="/outer/api/nl/v1/guest/generate", headers=headers, timeout=args.timeout, ) ) save_session(path, update_session_with_auth(session, response, base_url=base_url, device_id=device_id)) pretty_print(response) return 0 ``` ```python def cmd_agent_login(args: argparse.Namespace) -> int: path = session_path(args) session = load_session(path) apply_header_args_to_session(session, args) base_url = resolve_base_url(args, session) device_id = resolve_device_id(args, session) body = { "openId": args.open_id, "unionId": args.union_id, "loginType": 99, "nickName": args.nick_name, "gender": args.gender, "avatar": args.avatar, "email": args.email, "clientType": args.client_type, "channelId": args.channel_id, "code": args.code, ...[truncated 3980 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (35)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Start with `scripts/org_skill_cli.py --help`, then read only the documents relevant to the current task.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Start with `scripts/org_skill_cli.py --help`, then read only the documents relevant to the current task.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Start with `scripts/org_skill_cli.py --help`, then read only the documents relevant to the current task.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Start with `scripts/org_skill_cli.py --help`, then read only the documents relevant to the current task.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Start with `scripts/org_skill_cli.py --help`, then read only the documents relevant to the current task.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Start with `scripts/org_skill_cli.py --help`, then read only the documents relevant to the current task.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/org_skill_cli.py (reported line 333)May include surrounding context.

python
if auth_mode == "access":
        token = session.get("token")
        if not token:
            raise RuntimeError("当前 session 里没有 access token,请先 guest-generate 或 agent-login。")
        headers["authorization"] = f"Bearer {token}"
        return
    if auth_mode == "refresh":

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/org_skill_cli.py (reported line 1314)May include surrounding context.

python
if auth_mode == "access":
        token = session.get("token")
        if not token:
            raise RuntimeError("当前 session 里没有 access token,请先 guest-generate 或 agent-login。")
        headers["authorization"] = f"Bearer {token}"
        return
    if auth_mode == "refresh":

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README states that the CLI defaults to production and persists session files under a user home directory, but it does not prominently warn that tokens may grant access to real accounts and organizations. In an agent-operated skill, this increases the chance of unintended actions against live systems or leakage of reusable session credentials through logs, shared workspaces, or weak file permissions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documentation states that the CLI automatically sends x-language=ch, which imposes a locale/language setting by default. Under the policy, forcing a specific language without user opt-in or clear documented justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This markdown file contains natural-language guidance that restricts documentation to English only. Under the policy criteria, forcing a specific language without user choice or a documented justification is a locale/language policy violation.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill describes executable behaviors involving network access, local file reads/writes, environment switching, and session handling, but it does not declare an explicit tool scope or permission boundary. That omission increases the chance an agent will invoke sensitive capabilities implicitly, making review and runtime containment much weaker for a skill that can authenticate, persist sessions, and perform live API mutations.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

The skill explicitly promotes session reuse and local session-file persistence, with automatic default storage under a home-directory path. Persisted tokens on disk can be stolen, reused across tasks, or mixed between accounts/environments if isolation is weak, which is particularly sensitive here because the skill can authenticate and perform live organizational actions.

Content

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

md
A "help post" is currently just a normal post, so publish it through `post-create`.
  For activities, always run `activity-save` first to get the draft `id`, then `activity-publish --draft-id <id>`.
- Multi-agent usage:
  different accounts must use different `--session-file` values so one token does not overwrite another in the same environment.
- Environment convention:
  default to production; explicitly pass `--env test` for integration testing and `--env local` for local backend work.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill defaults to production and documents post/activity publishing flows without a prominent warning that these actions can create or publish live content. In an agent setting, that creates a real risk of unintended writes to production systems, especially because the workflow language is procedural and action-oriented rather than cautionary.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation states that default request headers include x-language=ch, and that English-speaking users must explicitly switch to --language us. This imposes a specific language/locale by default rather than offering a neutral default or user choice, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

The reference requires an x-language header and later recommends a share-link format with t8=ch, which suggests a fixed locale/language behavior. The file does not indicate that users can choose their preferred language or that the locale restriction is justified, which may violate the language/locale policy.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This markdown file documents activity.cancel and activity.delete, which can change or remove user-managed activity data, but it does not warn that these actions are destructive or recommend confirmation before use. Under the markdown-specific SQP-2 criteria, descriptions should disclose behaviors that could affect user data or system integrity.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The reference explicitly states that if no environment is provided, the skill will default to the production API. In an agent skill that can perform organization operations, publishing, and activity workflows, this creates a meaningful risk of unintended writes, data exposure, or operational changes against live systems when a caller omits flags or misconfigures execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The document instructs the tool to automatically persist session state, including token, refreshToken, and deviceId, to disk by default if --session-file is not provided. Storing authentication material in a predictable filesystem location without an explicit warning, permission guidance, or protection requirements increases the risk of credential theft from local compromise, shared environments, backups, or misconfigured permissions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The reference explicitly documents that the CLI will automatically call a configuration endpoint and select a default avatar when organization creation is invoked without one, which normalizes a state-changing action without an explicit user confirmation or warning. In an agent skill, this increases the chance that an autonomous workflow creates server-side resources on a user's behalf unexpectedly, especially if the agent treats documentation as approval to proceed with side effects.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document presents update, join, and related CLI commands as ordinary examples without prominently warning that they modify organization data or account membership state. In the context of an agent-facing operational skill, this can encourage unsafe automation where an agent performs updates or joins as part of a workflow without obtaining clear consent for the side effects.

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 · README.md (reported line 38)May include surrounding context.

md
STATE_DIR = Path(STATE_DIR_OVERRIDE or str(DEFAULT_STATE_DIR)).expanduser()
SESSIONS_DIR = STATE_DIR / "sessions"
LEGACY_BASE_URL_ALIASES = {
    "https://api.zingup.club": "https://api.zingup.club/biz",
}
KNOWN_ENV_BASE_URLS = {
    "prod": "https://api.zingup.club/biz",

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 · SKILL.md (reported line 79)May include surrounding context.

md
STATE_DIR = Path(STATE_DIR_OVERRIDE or str(DEFAULT_STATE_DIR)).expanduser()
SESSIONS_DIR = STATE_DIR / "sessions"
LEGACY_BASE_URL_ALIASES = {
    "https://api.zingup.club": "https://api.zingup.club/biz",
}
KNOWN_ENV_BASE_URLS = {
    "prod": "https://api.zingup.club/biz",

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_reference.md (reported line 10)May include surrounding context.

md
STATE_DIR = Path(STATE_DIR_OVERRIDE or str(DEFAULT_STATE_DIR)).expanduser()
SESSIONS_DIR = STATE_DIR / "sessions"
LEGACY_BASE_URL_ALIASES = {
    "https://api.zingup.club": "https://api.zingup.club/biz",
}
KNOWN_ENV_BASE_URLS = {
    "prod": "https://api.zingup.club/biz",

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/auth_reference.md (reported line 12)May include surrounding context.

md
STATE_DIR = Path(STATE_DIR_OVERRIDE or str(DEFAULT_STATE_DIR)).expanduser()
SESSIONS_DIR = STATE_DIR / "sessions"
LEGACY_BASE_URL_ALIASES = {
    "https://api.zingup.club": "https://api.zingup.club/biz",
}
KNOWN_ENV_BASE_URLS = {
    "prod": "https://api.zingup.club/biz",