Back to skill

Security audit

GDrive Owncloud sync

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent sync-report purpose, but it installs a persistent network-exposed OwnCloud inventory service with hardcoded default secrets and unsafe temporary-file handling.

Treat this as installing a persistent OwnCloud inventory web service, not just a local sync check. Before use, replace all credentials, restrict config and service-file permissions, firewall or otherwise limit port 8443, move the inventory file out of /tmp into a protected service directory, and confirm exactly what filename/status metadata will be emailed and to whom.

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
owncloud.json:2
Finding
Hardcoded Shared Credentials Expose the OwnCloud File Inventory Service## Vulnerability Details **File Location**: `owncloud.json:2-4`; `allfiles-service/allfiles.service.txt:7-8` **Vulnerability Type**: Hardcoded credentials and insecure secret storage **Risk Level**: High ### Vulnerable Code `owncloud.json:2-4`: ```json "ALLFILES_URL": "https://xxxx.xxx:8443/allfiles", "ALLFILES_USER": "admin", "ALLFILES_PASS": "SuperSecretPasswordChangeMe2026!", ``` `allfiles-service/allfiles.service.txt:7-8`: ```ini Environment="ALLFILES_USER=admin" Environment="ALLFILES_PASS=SuperSecretPasswordChangeMe2026!" ``` ### Technical Analysis The project includes the same static username and password in both the client configuration and the systemd service definition. The service uses these values for HTTP Basic Authentication. Although traffic is protected by TLS, TLS does not mitigate disclosure of credentials stored in source-controlled or locally readable files. The documentation instructs administrators to configure matching values, which increases the likelihood that the supplied credentials will be deployed without modification. Static credentials in a systemd unit may also be visible to users who can read the unit file or inspect deployment artifacts. The authenticated endpoint returns the generated OwnCloud filename and modification-time inventory. Filenames can contain sensitive information such as customer names, project identifiers, medical subjects, financial records, or internal document titles. ### Attack Path 1. An attacker obtains a copy of the project, a deployment archive, `owncloud.json`, or the installed systemd unit. 2. The attacker extracts the supplied username and password. 3. The attacker identifies the externally or internally reachable endpoint on TCP port 8443. 4. The attacker sends an authenticated request such as: ```bash curl --proto '=https' \ -u 'admin:SuperSecretPasswordChangeMe2026!' \ 'https://target.example:8443/allfiles' ``` ...[truncated 807 chars]
Remediation
## Remediation Suggestions 1. Remove all real or usable credentials from tracked configuration and service files. 2. Replace committed values with clearly invalid placeholders and reject known placeholder values during startup. 3. Generate a unique, high-entropy password for every deployment. 4. Store server credentials using systemd credentials, for example `LoadCredential=`, rather than inline `Environment=` directives. 5. Alternatively, use a root-owned environment file with permissions set to `0600`, while ensuring the service only receives the specific secret it needs. 6. Protect `owncloud.json` with restrictive ownership and mode `0600`. 7. Rotate the published password in every existing deployment. 8. Restrict port 8443 using a host firewall, VPN, reverse-proxy access policy, or IP allowlist. 9. Consider replacing Basic Authentication with short-lived tokens or mutual TLS. 10. Add authentication failure rate limiting and audit logging without logging credentials.

T09 · Insecure Skill Coding Practices

Error
Location
allfiles-service/findallfiles.sh:13
Finding
Predictable Shared Temporary File Permits Symlink Race Attacks## Vulnerability Details **File Location**: `allfiles-service/findallfiles.sh:13-17,41`; `allfiles-service/allfiles-service.go:41-58` **Vulnerability Type**: Unsafe temporary file and time-of-check-to-time-of-use race **Risk Level**: High ### Vulnerable Code `allfiles-service/findallfiles.sh:13-17,41`: ```bash if [[ -L "/tmp/allfiles.txt" ]]; then echo "FATAL: /tmp/allfiles.txt is a symbolic link — possible symlink attack detected." >&2 exit 1 fi /usr/bin/find "$OWNCLOUD_ROOT_INSTALL_DIR"/"$OWNCLOUD_USERNAME"/ -type f -printf '%f|%TY-%Tm-%Td %TH:%TM\n' > /tmp/allfiles.txt ``` `allfiles-service/allfiles-service.go:41-58`: ```go info, err := os.Lstat("/tmp/allfiles.txt") if err != nil { http.Error(w, "File not found", http.StatusNotFound) return } if info.Mode()&os.ModeSymlink != 0 { log.Println("SECURITY: /tmp/allfiles.txt is a symbolic link — possible symlink attack detected.") http.Error(w, "Internal server error", http.StatusInternalServerError) return } f, err := os.Open("/tmp/allfiles.txt") if err != nil { http.Error(w, "File not found", http.StatusNotFound) return } ``` ### Technical Analysis `/tmp` is normally shared and writable by multiple local users. The fixed pathname `/tmp/allfiles.txt` is therefore attacker-predictable. The shell script first tests whether the path is a symbolic link and later opens it through shell redirection. These are separate filesystem operations. An attacker can replace the checked path with a symbolic link after the check but before the redirection. Shell redirection follows the replacement link. The Go service has the same time-of-check-to-time-of-use weakness. It calls `os.Lstat` and subsequently calls `os.Open` on the pathname. A local attacker can replace the regular file with a symbolic link between those calls. The application verifies the original directory entry but may open a different one ...[truncated 2257 chars]
Remediation
## Remediation Suggestions 1. Stop storing service state directly under the shared `/tmp` directory. 2. Create a dedicated directory such as `/var/lib/allfiles` owned by the service account and set its mode to `0700`. 3. Run the indexing task and network service under the same dedicated, unprivileged account where operationally possible. 4. Create the inventory using `mktemp` inside the protected directory. 5. Set `umask 077` and explicitly enforce file mode `0600`. 6. Write the complete inventory to the temporary file, flush it, and atomically rename it to the final inventory path. 7. Ensure temporary files are removed with a cleanup trap. 8. In Go, open the file using no-follow semantics such as `O_NOFOLLOW` on supported systems. 9. Validate the already-opened file descriptor with `f.Stat()` and confirm that it is a regular file with the expected owner and permissions. 10. Do not rely on a separate `Lstat` call as the security boundary. 11. Add stricter systemd hardening, including `PrivateTmp=true`, `ProtectHome=true`, a dedicated `StateDirectory=allfiles`, and the narrowest required filesystem access. 12. Document the required cron execution identity and explicitly prohibit running the indexing job as root unless strictly necessary.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (14)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill description understates behavior by implying a simple presence check while the detected behavior includes modification-date comparisons and authenticated HTTP(S) access using credentials not declared in permissions/resources. Undeclared credentialed network access is dangerous because it expands the trust boundary and can expose secrets or interact with sensitive services without informed approval.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The skill description understates behavior by implying a simple presence check while the detected behavior includes modification-date comparisons and authenticated HTTP(S) access using credentials not declared in permissions/resources. Undeclared credentialed network access is dangerous because it expands the trust boundary and can expose secrets or interact with sensitive services without informed approval.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The skill description understates behavior by implying a simple presence check while the detected behavior includes modification-date comparisons and authenticated HTTP(S) access using credentials not declared in permissions/resources. Undeclared credentialed network access is dangerous because it expands the trust boundary and can expose secrets or interact with sensitive services without informed approval.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
An authenticated HTTPS endpoint for serving local file contents is not justified by the stated business purpose of checking file synchronization and sending email reports. Even with basic authentication and TLS, this introduces an unnecessary remote data exposure surface that could be abused to retrieve sensitive local data or operational artifacts. In this skill context, the extra capability makes the code more dangerous because it appears hidden behind an unrelated description.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
The implemented behavior is materially different from the declared skill purpose. Instead of performing Google Drive/OwnCloud synchronization and email reporting, this code exposes a network endpoint that serves a local file over HTTPS with authentication, creating an undisclosed data access channel. The mismatch is especially suspicious because the service is intentionally reachable over the network and the code contains commentary about preventing file exfiltration via symlink abuse.

Credential Access

High
Category
Privilege Escalation
Content
# ---------------------------------------------------------------------------
# Guard against symlink attacks: reject any attempt to serve /tmp/allfiles.txt
# if it has been replaced by a symbolic link. A local attacker could otherwise
# point it to an arbitrary file (e.g. /etc/passwd) and leak its contents
# through the /allfiles endpoint.
# ---------------------------------------------------------------------------
if [[ -L "/tmp/allfiles.txt" ]]; then
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# ---------------------------------------------------------------------------
# Guard against symlink attacks: reject any attempt to serve /tmp/allfiles.txt
# if it has been replaced by a symbolic link. A local attacker could otherwise
# point it to an arbitrary file (e.g. /etc/passwd) and leak its contents
# through the /allfiles endpoint.
# ---------------------------------------------------------------------------
if [[ -L "/tmp/allfiles.txt" ]]; then
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill declares required binaries and a local config file but does not declare any explicit tool scope or permissions despite clearly requiring shell execution and environment/config access. This is dangerous because consumers and policy engines cannot accurately constrain what the skill is allowed to do, increasing the chance of overbroad execution and unnoticed access to local or network resources.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill says it emails a report about files but does not warn that file names, statuses, timestamps, or other metadata may be transmitted externally. In this context, the skill handles storage inventory across Google Drive and OwnCloud, so even metadata-only reports may reveal sensitive project names, document presence, or synchronization gaps to unintended recipients.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The README instructs operators to place service credentials in a systemd service definition and keep them aligned with credentials in another config file, but provides no guidance on secret handling, file permissions, or safer alternatives. This can lead to credentials being exposed through world-readable unit files, process/environment inspection, backups, or source control, increasing the likelihood of unauthorized access to the file indexing service.

Missing User Warnings

Low
Confidence
89% confidence
Finding
The code accesses sensitive credentials via ALLFILES_USER and ALLFILES_PASS, but there is no user-facing warning, confirmation, or explanatory comment that the skill depends on secret environment variables. Under the code-file criteria, access to sensitive environment variables should be disclosed unless the behavior is otherwise documented for users.

Natural-Language Policy Violations

Low
Confidence
79% confidence
Finding
The unit description is fixed as English text, which can be a natural-language locale choice embedded in the file. Under the stated policy, forcing a specific language without opt-in or documented justification can be considered a locale-policy violation.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
The script contains natural-language comments in French such as "Nettoyage agressif" and "Si on a exactement...", and later additional French-only comments appear in parsing logic. This introduces a language/locale inconsistency without any stated user choice or justification, matching the policy's language/locale violation criterion.

Natural-Language Policy Violations

Low
Confidence
83% confidence
Finding
This manifest-like file contains natural-language/config values that fix account and recipient settings to specific email identities, with no indication that users can choose or override locale- or identity-related behavior. Under the policy rule for natural-language organizational violations, forcing a fixed identity context without documented opt-in can violate user-choice expectations.

Static analysis

No suspicious patterns detected.