Back to skill

Security audit

Alumni Career Tracker

Security checks for vulnerabilities and agentic risk

Overview

The skill appears intended for alumni career tracking, but it stores and can export identifiable alumni career and compensation data without enforced privacy safeguards.

Review this before installing if you will store real alumni data. Use it only with consent and a protected local data path, avoid salary and private notes unless necessary, do not share raw exports, and prefer aggregate/anonymized reports. Pin dependencies and consider adding file-permission hardening before operational 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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/main.py:39
Finding

Alumni Personal and Compensation Data Is Stored in Plaintext

Content
View full analysis

Vulnerability Details

File Location: scripts/main.py:39-46 and scripts/main.py:110-114
Vulnerability Type: Plaintext storage of sensitive personal data
Risk Level: Medium

The application model includes names, employment information, locations, salary ranges, and free-form notes:

python
class AlumniRecord:
    """校友记录数据类"""
    name: str
    graduation_year: int
    degree: str  # PhD, Master, Bachelor
    current_status: str  # industry, academia, startup, other
    organization: str
    position: str
    location: str = ""
    field: str = ""
    salary_range: str = ""
    notes: str = ""

All fields are serialized directly to an unencrypted JSON file:

python
def _save_data(self):
    """保存数据到文件"""
    self.data_path.parent.mkdir(parents=True, exist_ok=True)
    with open(self.data_path, 'w', encoding='utf-8') as f:
        json.dump([r.to_dict() for r in self.alumni], f, ensure_ascii=False, indent=2)

Technical Analysis

AlumniRecord.to_dict() serializes every dataclass field, including salary_range and notes. _save_data() then writes those values as plaintext JSON. The file is created using the process's ambient umask rather than explicitly restrictive permissions. No encryption, field minimization, access-control validation, consent metadata, or retention mechanism is implemented.

The precise exposure depends on deployment permissions. If the resulting file is readable by other local users, shared services, backup operators, or processes running under the same account, those principals can recover the complete stored dataset without needing to bypass application controls.

Attack Path

  1. An operator adds or imports alumni records containing names, locations, salary ranges, or private notes.
  2. add_alumni() invokes _save_data().
  3. _save_data() serializes all record fields into alumni_data.json, or into the path supplied through `--d ...[truncated 937 chars]
Remediation
View remediation

Remediation Suggestions

  • Minimize collection: do not store salary information or free-form notes unless they are necessary for a documented purpose.
  • Separate identifiers from analytical data and use pseudonymous record identifiers where possible.
  • Create the data file atomically with owner-only permissions such as 0600; also verify and correct permissions when opening an existing file.
  • Encrypt sensitive fields or the complete datastore using a managed key that is not stored alongside the data.
  • Exclude sensitive fields from default exports and require an explicit, separately authorized option to include them.
  • Add consent status, retention deadlines, and deletion support to the data model.
  • Aggregate or anonymize records before producing reports, particularly for small cohorts.
  • Document backup protections and ensure backups inherit equivalent encryption and access restrictions.
  • Add automated tests that verify restrictive permissions and ensure sensitive fields are omitted from anonymized exports.

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Runtime Dependencies Are Unpinned and Lack Integrity Verification

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:1-3
Vulnerability Type: Uncontrolled third-party dependency resolution
Risk Level: Low

The dependency manifest contains only unrestricted package names:

text
dataclasses
pandas
rich

Technical Analysis

The manifest provides neither exact versions nor package hashes. Consequently, repeated installations can resolve to different releases, and the reviewed source tree does not define the exact third-party code that will be installed and imported.

Package installation and import can execute third-party code with the privileges of the user or build environment. This creates supply-chain exposure if a future dependency release is compromised, removed and replaced, or introduces a security regression. The dataclasses dependency is also unnecessary on Python versions where dataclasses is part of the standard library, increasing supply-chain surface without a demonstrated runtime need.

The listed names do not provide evidence of typosquatting or a presently malicious package. The finding concerns the absence of reproducibility and integrity controls.

Attack Path

  1. A user or deployment pipeline runs pip install -r requirements.txt.
  2. Because no versions are pinned, the resolver selects releases available from the configured package index at installation time.
  3. If an allowed release or its distribution artifact has been compromised, the package manager downloads that artifact without validating it against a project-approved hash.
  4. Third-party code may execute during installation or later when pandas or rich is imported by scripts/main.py.
  5. Such code runs with the privileges and accessible environment of the installing or executing process.

This path requires a compromised or vulnerable dependency release, package index, or configured package source; the repository itself does not demonstrate that such a compromise has occ ...[truncated 566 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove dataclasses when the project supports Python versions that provide it in the standard library.
  • Define and document the supported Python version range.
  • Pin reviewed dependency versions using a lock file or fully resolved requirements file.
  • Generate and enforce cryptographic hashes, for example by installing with pip --require-hashes.
  • Separate direct dependencies from transitive locked dependencies so update intent remains clear.
  • Install only from an approved HTTPS package index and avoid untrusted extra indexes.
  • Run dependency vulnerability and provenance checks in continuous integration.
  • Review automated dependency updates before merging and regenerate lock files and hashes in a controlled environment.
  • Install and run the application as a non-privileged user in an isolated virtual environment or container.
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (13)

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The stated purpose of the skill is career tracking and guidance, but the documented workflow extends into extracting alumni contacts for partnership development and outreach. This scope creep increases the chance that data collected for advising is repurposed for external relationship-building without clear notice or consent, which is a common privacy governance failure.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill explicitly emphasizes aggregated, anonymized reporting, but the industry partnership example exports identifiable alumni contacts for outreach. That creates a privacy and purpose-limitation conflict: users may disclose personal information for secondary uses without documented consent, potentially violating institutional privacy expectations or applicable data-protection rules.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% 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 381)May include surrounding context.

md
- ❌ **Sharing individual salaries** → Violates privacy expectations
  - ✅ Report salary ranges or medians only; aggregate by groups

- ❌ **Identifiable case studies without consent** → Privacy breach
  - ✅ Always get written permission before highlighting individuals

**Interpretation Issues:**

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% 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 426)May include surrounding context.

md
- ❌ **Sharing individual salaries** → Violates privacy expectations
  - ✅ Report salary ranges or medians only; aggregate by groups

- ❌ **Identifiable case studies without consent** → Privacy breach
  - ✅ Always get written permission before highlighting individuals

**Interpretation Issues:**

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This Python file contains natural-language descriptions and prompts exclusively in Chinese, beginning with the module docstring and continuing throughout the CLI. Under the policy, forcing a specific language without user opt-in is a locale/language policy violation unless the regional constraint is explicitly justified.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The data model stores and exports individual-level alumni information including salary_range and free-form notes, which can contain sensitive personal or confidential data not necessary for aggregate career-path analysis. This creates privacy and data-minimization risks, especially because the tool also supports export and bulk handling of the dataset.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill’s stated purpose is analytical guidance, but the implementation includes broad record-management capabilities that let a caller create, modify, delete, and bulk import alumni data. In agent environments, this kind of scope expansion increases the blast radius from a read/analysis skill into a data-handling tool, enabling unintended collection or manipulation of personal information.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

Deletion and bulk import/export capabilities are high-impact administrative operations that are not justified by a simple career-guidance skill. In a larger agent system, these features could be abused to exfiltrate alumni records, poison the dataset used for recommendations, or destroy data integrity.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
87% confidence
Finding

The dependency list is unpinned, so installations may resolve to different versions over time, reducing reproducibility and potentially pulling in a newly introduced vulnerable or incompatible release. In this case, dataclasses is especially questionable because it is primarily a backport package and may be unnecessary or inappropriate on newer Python versions.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
dataclasses
pandas
rich

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

pandas is declared without a version constraint, which means builds are not reproducible and may silently consume a vulnerable or breaking release in the future. Because pandas has had security advisories historically, the lack of pinning increases supply-chain uncertainty for this skill.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
dataclasses
pandas
rich

Unverifiable Dependency: pandas has 1 known advisory(ies) (CVE-2020-13091 (** DISPUTED ** pandas through 1.0.3 can unserialize and execute commands from an)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
90% confidence
Finding

rich is unpinned, so dependency resolution may change across environments and over time, which can introduce unreviewed code or compatibility issues. While this is not evidence of an active exploit by itself, it is a real supply-chain hygiene weakness.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
dataclasses
pandas
rich

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/main.py (reported line 189)May include surrounding context.

python
"""
        result = self.alumni
        for key, value in filters.items():
            result = [a for a in result if getattr(a, key, None) == value]
        return result

    def analyze(

Static analysis

No suspicious patterns detected.