Back to skill

Security audit

petkit-monitor

Security checks for vulnerabilities and agentic risk

Overview

The skill’s monitoring purpose is coherent, but it ships a live-looking PETKIT account password and handles user passwords in unsafe plaintext ways.

Review this skill before installing. Do not use it with the bundled config.json; rotate that PETKIT password if it is real, remove the bundled credentials, and prefer a secure credential store or interactive password prompt instead of command-line passwords and plaintext config files.

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

Error
Location
config.json:1
Finding
Plaintext PETKIT Account Credentials Included in the Project<![CDATA[ ## Vulnerability Details **File Location**: `config.json:1-4` **Vulnerability Type**: Hardcoded plaintext credentials **Risk Level**: High ### Vulnerable Code ```json { "username": "18055988330", "password": "[REDACTED LIVE-LOOKING PASSWORD]" } ``` The password value has been redacted from this report to prevent further disclosure. The audited file contains the complete plaintext value. ### Technical Analysis The project includes a phone-number username and a non-placeholder password directly in a tracked configuration file. Secrets stored in project files can be exposed through source repositories, skill packages, release archives, backups, logs, or file sharing. The application reads these values without any additional protection and submits them to the PETKIT client: ```python config = load_config() result = asyncio.run(get_petkit_status(config['username'], config['password'])) ``` Because the credentials appear usable rather than illustrative, possession of the project files may be sufficient to attempt authentication to the associated PETKIT account. ### Attack Path 1. An attacker obtains a copy of the project, repository, skill archive, backup, or build artifact. 2. The attacker opens `config.json`. 3. The attacker recovers the plaintext PETKIT username and password. 4. The attacker submits the credentials to the PETKIT service or compatible client. 5. If the credentials remain valid, the attacker can access data and devices associated with the account. ### Impact Assessment Successful exploitation could expose PETKIT account information and household device data, including linked feeders, litter boxes, water fountains, and purifiers. Depending on the capabilities exposed by the service and account, an attacker may also gain unauthorized control over linked devices. The documented behavior indicates that authentication may terminate the legitimate user's mobile application session, creating an additional account-availability im ...[truncated 97 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Immediately rotate the exposed PETKIT password and invalidate existing sessions or tokens. 2. Remove the real credentials from the current project and all distributed artifacts. 3. Purge the secret from repository history rather than deleting only the latest version. 4. Add `config.json` to `.gitignore` and distribute a credential-free `config.example.json`. 5. Retrieve credentials from an operating-system credential store, dedicated secret manager, or protected environment variables. 6. Add automated secret scanning to development and release pipelines. 7. Review PETKIT account activity and linked devices for unauthorized access. 8. If plaintext fallback storage is unavoidable, restrict the file to the owning user with mode `0600`. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
petkit_monitor.py:172
Finding
Password Exposed Through Command-Line Arguments and Insecure Plaintext Storage<![CDATA[ ## Vulnerability Details **File Location**: `petkit_monitor.py:28-31` and `petkit_monitor.py:172-177` **Vulnerability Type**: Insecure credential input and storage **Risk Level**: Medium ### Vulnerable Code ```python def save_config(config): """保存配置""" with open(CONFIG_PATH, 'w') as f: json.dump(config, f, indent=2) ``` ```python if sys.argv[1] == '--configure': # 配置账号 if len(sys.argv) > 3: config['username'] = sys.argv[2] config['password'] = sys.argv[3] save_config(config) print(f"✅ 配置已保存: {config['username']}") ``` ### Technical Analysis The configuration command requires the user to provide the account password as a command-line argument. Command-line secrets can be exposed through shell history, terminal logging, process inspection, diagnostic tools, job-management systems, and command auditing. The password is subsequently written as plaintext JSON. The application does not explicitly enforce owner-only permissions; access is determined by the process umask and any existing file permissions. In an environment with permissive defaults, other local users or processes may be able to read the credentials. The file is also written directly rather than through an atomic, permission-controlled creation procedure. Although no concurrent attack is demonstrated in the reviewed code, the current approach provides no explicit confidentiality guarantees. ### Attack Path 1. A user runs: `petkit-monitor.py --configure <username> <password>`. 2. A local attacker reads the command from shell history, process metadata, terminal logs, or process-monitoring tools. 3. Alternatively, the attacker locates `config.json` and reads it if filesystem permissions allow access. 4. The attacker recovers the PETKIT password. 5. The attacker authenticates to the PETKIT account and obtains the privileges associated with that account. ### Impact Assessment An attacker with local observation or file-read access ...[truncated 412 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove password input from command-line arguments. 2. Prompt interactively with `getpass.getpass()` so the password is not echoed or included in process arguments. 3. Prefer an operating-system credential store or dedicated secret-management service instead of a plaintext JSON file. 4. If a local file must be used, create it atomically with mode `0600` and verify that it is owned by the expected user. 5. Avoid placing secrets in shell history, automation logs, exception messages, or diagnostic output. 6. Migrate existing plaintext credentials into the selected secure storage mechanism and securely delete obsolete copies. 7. Document the local security assumptions and warn users not to pass passwords directly on the command line. ]]>

T08 · Insecure Dependencies

Note
Location
petkit_monitor.py:10
Finding
Unpinned Third-Party Dependency Installation Guidance<![CDATA[ ## Vulnerability Details **File Location**: `petkit_monitor.py:10-18` **Vulnerability Type**: Unpinned and unverified third-party dependency **Risk Level**: Low ### Vulnerable Code ```python # Patch FEEDER_LIST to include additional feeder models from petkitaio import constants additional_feeders = ['D4H', 'S0HO', 'SOHO', 'D4HSOLO', 'D3', 'D4', 'D4s', 'Feeder', 'FeederMini'] for m in additional_feeders: if m not in constants.FEEDER_LIST: constants.FEEDER_LIST.append(m) try: from petkitaio import PetKitClient except ImportError: print("Error: petkitaio not installed. Run: pip3 install petkitaio") sys.exit(1) ``` ### Technical Analysis The error message directs users to install `petkitaio` without specifying a reviewed version or cryptographic hash. This makes installation non-reproducible and causes users to trust whichever package release the configured package index currently serves. If the package, a future release, the package index, or the user's package-index configuration is compromised, package installation or import may execute attacker-controlled code. Python packages may execute code during installation and always execute top-level module code when imported. The code also imports `petkitaio.constants` before entering the `try` block. Therefore, when the dependency is entirely absent, that first import raises `ImportError` before the intended installation guidance can run. This ordering defect is not itself a supply-chain vulnerability, but it weakens dependency handling. ### Attack Path 1. A user runs the program without the expected dependency or follows the documented installation instruction. 2. The user executes `pip3 install petkitaio` without a version or hash constraint. 3. The configured package index supplies an unexpected, compromised, or malicious release. 4. Package-controlled code executes during installation or when the project imports `petkitaio`. 5. The malicious code obtains the same operati ...[truncated 802 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Declare a reviewed, exact `petkitaio` version in a dependency manifest or lockfile. 2. Use hash verification, such as pip requirements with `--hash` entries and `--require-hashes`. 3. Install dependencies in an isolated virtual environment under a non-privileged account. 4. Review dependency updates before changing the locked version. 5. Configure trusted package indexes explicitly and protect package-index configuration from tampering. 6. Add dependency vulnerability and provenance scanning to the release process. 7. Move all `petkitaio` imports inside the same guarded import block so missing dependencies are handled consistently. 8. Replace the generic installation command with a pinned, reproducible setup procedure. ]]>
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 (7)

Lp3

Medium
Category
MCP Least Privilege
Confidence
83% confidence
Finding
The skill requires sensitive credentials and the analyzer detected file_write capability, yet the manifest does not declare any tool scope or permissions boundary. That mismatch is dangerous because it hides the skill's effective capabilities from reviewers and users, increasing the risk that credentials, tokens, or device data could be written to local files without explicit authorization or review.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The manifest description and all user-facing instructions are written only in Chinese, with no indication that other languages are supported or that Chinese is a required locale. Under the policy provided, forcing a specific language without user opt-in is a natural-language policy violation.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
The manifest describes a monitoring skill for retrieving feeder, litter box, fountain, and purifier status. In addition to status retrieval, the code writes user credentials to a local config file and exposes a `--configure` flow to store them, which is behavior beyond pure monitoring.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The code creates a client with username and password and then logs in to the PetKit service, which necessarily sends sensitive credentials over the network. There is no visible warning, prompt, or explanatory comment telling the user that their account data will be transmitted to an external service.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill stores the PetKit username and password in plaintext in a local config.json file without warning, encryption, or restricted handling. If the local filesystem is accessed by another user, process, backup system, or malware, the account credentials can be recovered and reused against the user's PetKit account.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
User-facing strings, help text, and output formatting are all hard-coded in Chinese, which imposes a specific language on users. The file does not offer any language selection, opt-in, or documented justification for a Chinese-only experience.

Description-Behavior Mismatch

Low
Confidence
81% confidence
Finding
The stated purpose is to get device status, but the script changes `petkitaio.constants.FEEDER_LIST` at import time to alter library behavior. This is not just fetching status; it extends runtime support by patching upstream constants, which goes beyond the narrow monitoring description.

Static analysis

No suspicious patterns detected.