Back to skill

Security audit

Skill Tracker

Security checks for vulnerabilities and agentic risk

Overview

This skill appears to be a local usage tracker with no evidence of exfiltration, but it should be reviewed because it stores per-call user/session/error context in plaintext and its retention controls are not actually enforced.

Install only if you are comfortable with local plaintext usage logs. Avoid passing real names, session IDs, tokens, request payloads, or raw exception messages into the tracker until raw logging can be disabled or redacted and retention cleanup is implemented. Prefer local source installation over the future pip/npm commands unless the publisher and exact package version are verified.

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

T08 · Insecure Dependencies

Warning
Location
README.md:29
Finding

Unverified Public Registry Installation Instructions Create a Dependency-Confusion Risk

Content
View full analysis

Vulnerability Details

File Location: README.md:29-31 and README.md:40-42
Vulnerability Type: Unverified package source and dependency confusion
Risk Level: Medium

Vulnerable Code

bash
# Method 2: pip installation (coming soon)
pip install skill-tracker
bash
# Method 2: npm installation (coming soon)
npm install skill-tracker

Technical Analysis

The documentation instructs users to install skill-tracker from the public Python and npm registries while simultaneously stating that these distribution methods are “coming soon.” The instructions do not identify a verified registry publisher, pin an exact version, provide a package hash, or otherwise establish that the downloaded registry artifacts correspond to the audited source code.

If either package name is unregistered, abandoned, or controlled by an unrelated party, an attacker could publish malicious content under that name. Package installation can execute package-controlled code, including npm lifecycle scripts and Python build-system logic. Consequently, following these commands may execute code that was not included in this audit.

Attack Path

  1. An attacker registers or gains control of the skill-tracker name on PyPI or npm.
  2. The attacker publishes a package containing malicious installation or runtime code.
  3. A user follows the installation command in README.md.
  4. The package manager retrieves the attacker-controlled artifact from the public registry.
  5. Malicious build, installation, lifecycle, import, or runtime code executes with the privileges of the user running the package manager.

Impact Assessment

Successful exploitation could provide arbitrary code execution under the installing user's account. The resulting access could include reading or modifying files available to that user, accessing environment variables and developer credentials, altering the project, or installing additional mal ...[truncated 123 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the public registry installation commands until official packages have been published and registry ownership has been verified.
  2. In the interim, direct users to install the audited local source, such as pip install ., or use an authenticated and pinned repository reference.
  3. Once published, document the verified publisher identity and official registry URLs.
  4. Pin exact release versions rather than using an unconstrained package name.
  5. For Python deployments, publish hashes and recommend hash-verified installation with a locked requirements file.
  6. For Node.js deployments, commit and verify a lockfile and use npm ci in automated environments.
  7. Ensure that published registry artifacts are reproducibly generated from tagged, reviewed source releases.
  8. Protect publisher accounts with multi-factor authentication and trusted publishing.

T09 · Insecure Skill Coding Practices

Warning
Location
index.js:154
Finding

Sensitive Tracking Context Is Stored Indefinitely in Plaintext

Content
View full analysis

Vulnerability Details

File Location: index.js:154-167, skill_tracker.py:139-157, and config.yaml:7-29
Vulnerability Type: Plaintext sensitive-data logging and ineffective retention controls
Risk Level: Medium

Vulnerable Code

index.js:154-167:

javascript
const logEntry = {
  timestamp,
  date,
  skill: skillName,
  action,
  duration_ms: duration,
  context: {
    user: context.user || '韩先生',
    channel: context.channel || 'feishu',
    session_id: context.session_id || null,
    success: context.success !== false,
    error: context.error || null
  }
};

The resulting object is appended to a plaintext file:

javascript
const logLine = JSON.stringify(logEntry) + '\n';
await fs.promises.appendFile(Config.USAGE_LOG, logLine, 'utf8');

skill_tracker.py:139-157:

python
log_entry = {
    'timestamp': timestamp,
    'date': date,
    'skill': skill_name,
    'action': action,
    'duration_ms': duration_ms,
    'context': {
        'user': context.get('user', '韩先生'),
        'channel': context.get('channel', 'feishu'),
        'session_id': context.get('session_id'),
        'success': context.get('success', True),
        'error': context.get('error')
    }
}

# Append log entry
with Config.USAGE_LOG.open('a', encoding='utf-8') as f:
    f.write(json.dumps(log_entry, ensure_ascii=False) + '\n')

config.yaml:7-29 advertises retention and cleanup controls:

yaml
# Log retention in days (0 means permanent)
retentionDays: 90

# Report settings
report:
  # Default number of entries to display
  topN: 10
  # Include detailed information
  includeDetails: true
  # Alert when success rate is below this value
  alertSuccessRate: 80

# Automatic cleanup
autoClean:
  # Whether old logs are automatically cleaned
  enabled: true
  # Cleanup time
  cron: '0 3 * * *'

Technical Analysis

...[truncated 2041 chars]

Remediation
View remediation

Remediation Suggestions

  1. Disable raw context logging by default and make it an explicit opt-in feature.
  2. Store only fields required for aggregate statistics; omit user names, session identifiers, and raw error text whenever possible.
  3. Hash or pseudonymize identifiers with a keyed construction when correlation is necessary.
  4. Apply centralized secret redaction before serialization, covering tokens, cookies, authorization headers, credentials, URLs containing secrets, and other sensitive patterns.
  5. Replace raw error messages with controlled error categories or sanitized summaries.
  6. Create the data directory and log files with restrictive permissions appropriate to the operating system.
  7. Load and validate config.yaml, then enforce logRaw, retentionDays, and autoClean consistently in both implementations.
  8. Implement tested log rotation and deletion based on record timestamps, including safe handling of backups and rotated files.
  9. Consider authenticated encryption at rest when logs must contain sensitive context.
  10. Update the privacy documentation to describe the fields actually collected, their retention period, access requirements, and deletion behavior.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (24)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

A second documented mismatch exists around claimed language/runtime support and actual implementation behavior, combined with persistence of extra contextual data beyond the stated analytics scope. Misrepresenting supported implementations and data handling can cause unsafe integration assumptions, especially if downstream skills pass rich context objects into a tracker that stores them without clear notice.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

A second documented mismatch exists around claimed language/runtime support and actual implementation behavior, combined with persistence of extra contextual data beyond the stated analytics scope. Misrepresenting supported implementations and data handling can cause unsafe integration assumptions, especially if downstream skills pass rich context objects into a tracker that stores them without clear notice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The README is written entirely in Chinese and presents the skill as a general-purpose tracker, but it does not offer any language choice or indicate that the Chinese-only locale is a justified regional constraint. Under the stated policy, forcing a specific language without opt-in is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README explicitly demonstrates collecting and persisting user identifiers such as user, channel, and session_id into local logs, but it does not clearly warn integrators about the privacy implications or recommend minimization, consent, or redaction. In a tracking library, this can normalize logging personally identifiable or linkable activity data, increasing privacy risk if logs are accessed, retained too long, or copied into less protected environments.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
80% confidence
Finding

The skill explicitly requires filesystem read/write access and documents local data storage, but it does not declare any tool scope such as permissions or allowed-tools. This creates an authorization transparency gap: operators cannot easily constrain or review what file operations the skill is expected to perform, increasing the chance of unintended or overly broad file access.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The natural-language content of the skill is presented exclusively in Chinese, including description, usage instructions, triggers, and warnings, with no opt-in or alternative language indicated. This can violate language/locale policy when a skill forces a specific language without user choice or a documented region-specific reason.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The configuration exposes logRaw: true and describes a raw usage log file, but the documentation does not present a strong, prominent warning that raw local logs may contain sensitive operational context. In a tracking skill, this omission materially increases privacy risk because users may enable or leave defaults in place without understanding that detailed local event records are being retained.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The code advertises file-lock and concurrency safety, but the actual lock is only an in-memory Map and the declared lock file is never used. In multi-process or multi-instance deployments, concurrent reads and writes can race, causing lost updates or corrupted statistics despite the safety claims.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill claims to provide aggregate usage statistics, but it persists per-invocation metadata including user, channel, session_id, and error details to disk. This creates unnecessary data retention and possible privacy exposure if logs are accessed, copied, or later repurposed beyond the stated function.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The tracker writes user/context information and error data to persistent local storage without any visible notice, consent flow, or configuration defaulting to privacy-preserving behavior. Even if storage is local, this can expose personal or sensitive operational data to administrators, backups, or other processes on the host.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The tracker persists per-call context including user identity, channel, session_id, success state, and error details to disk, which exceeds the stated purpose of simple usage statistics. This creates unnecessary collection and retention of potentially sensitive operational and personal data, increasing privacy and disclosure risk if the files are accessed by other local users, bundled, backed up, or exposed later.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code writes user and session context to local disk without any user-facing disclosure, consent mechanism, or indication that identifiers and error information are being retained. In a telemetry component advertised as privacy-protecting and focused on aggregate usage stats, silent persistence of such data materially raises privacy, compliance, and inadvertent secret-leak risks.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

This markdown file presents core project documentation only in Chinese, including the title and versioning notes. The stated policy flags language or locale constraints when a skill forces a specific language without user opt-in, and no alternative language option or justification is provided here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

This manifest contains human-facing natural-language comments entirely in Chinese, but there is no indication that users can choose a language or that the file is intended only for a Chinese-speaking environment. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The report formatting explicitly calls toLocaleString('zh-CN'), which forces a specific locale in generated output regardless of user preference. The file also uses exclusively Chinese-language user-facing strings, and there is no indication of user choice or documented region-specific justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The package description is written entirely in Chinese, which can impose a language choice on users without offering an alternative or indicating that the skill is region- or language-specific. This is a natural-language policy concern because the metadata presents the skill in a fixed locale with no documented opt-in.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 36)May include surrounding context.

json
},
  "dependencies": {},
  "devDependencies": {
    "jest": "^29.0.0",
    "eslint": "^8.0.0"
  },
  "files": [

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 37)May include surrounding context.

json
"dependencies": {},
  "devDependencies": {
    "jest": "^29.0.0",
    "eslint": "^8.0.0"
  },
  "files": [
    "index.js",

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

This Python file contains user-facing natural-language text entirely in Chinese in the module docstring, including installation guidance. The stated policy flags language/locale constraints across all file types when the skill does not offer user opt-in or justify the locale restriction.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The package description string is user-facing metadata and is written only in Chinese. Under the stated policy, forcing a specific language without opt-in or a documented regional justification is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The module title, comments, docstrings, and CLI messages are presented in Chinese with no indication that users may choose another language. This can violate language/locale policy when a skill forces a specific language without offering opt-in or alternatives.

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

python
def setup_logger():
    """配置统一日志"""
    logger = logging.getLogger('SkillTracker')
    logger.setLevel(getattr(logging, Config.LOG_LEVEL))
    
    # 避免重复添加 handler
    if not logger.handlers:

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

python
def setup_logger():
    """配置统一日志"""
    logger = logging.getLogger('SkillTracker')
    logger.setLevel(getattr(logging, Config.LOG_LEVEL))
    
    # 避免重复添加 handler
    if not logger.handlers:

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

track() 的文档在 L125-L147 强调“非阻塞、立即返回”,但模块在导入阶段就执行 init_stats_file(),首次加载时可能创建目录并写入统计文件。虽然这不属于 track() 调用本身,但作为该追踪器的实际运行行为,与其“非阻塞”意图宣传存在偏差,尤其在首次导入时会产生同步文件副作用。

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.