Back to skill

Security audit

NextCloud AIO OpenClaw

Security checks for vulnerabilities and agentic risk

Overview

This Nextcloud skill is mostly purpose-aligned, but it handles account credentials and can modify or delete remote data without enforcing HTTPS or tight path scoping.

Install only if you trust the publisher and can configure a dedicated, revocable, least-privilege Nextcloud app password. Use an HTTPS-only NEXTCLOUD_URL, avoid untrusted redirects, test on non-production data first, and be careful with delete/upload commands because they modify remote account data.

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/files_binary.py:47
Finding

Basic Authentication Credentials Can Be Sent Without TLS or Exposed Through Unsafe Redirects

Content
View full analysis
tuple[str, str, str]: url = os.environ.get("NEXTCLOUD_URL", "").rstrip("/") user = os.environ.get("NEXTCLOUD_USER", "") token = os.environ.get("NEXTCLOUD_TOKEN", "") if not (url and user and token): print( "ERROR: NEXTCLOUD_URL, NEXTCLOUD_USER, and NEXTCLOUD_TOKEN must be set.", file=sys.stderr, ) sys.exit(1) return url, user, token def _auth(user: str, token: str) -> dict: creds = base64.b64encode(f"{user}:{token}".encode()).decode() return {"Authorization": f"Basic {creds}"} def cmd_download(nc_path: str, local_path: str) -> None: url, user, token = _config() dav_url = _dav_url(nc_path, url, user) req = urllib.request.Request(dav_url, headers=_auth(user, token)) try: with urllib.request.urlopen(req) as resp: data = resp.read() ``` The JavaScript client has the same absence of URL and TLS validation: ```javascript var CONFIG = { url: process.env.NEXTCLOUD_URL, user: process.env.NEXTCLOUD_USER, token: process.env.NEXTCLOUD_TOKEN, timeZone: process.env.NEXTCLOUD_TIMEZONE || process.env.TZ || "UTC" }; if (!CONFIG.url || !CONFIG.user || !CONFIG.token) { console.error(JSON.stringify({ status: "error", message: "Missing configuration. Set NEXTCLOUD_URL, NEXTCLOUD_USER, and NEXTCLOUD_TOKEN." })); process.exit(1); } var AUTH_HEADER = "Basic " + Buffer2.from(`${CONFIG.user}:${CONFIG.token}`).toString("base64"); async function request(endpoint, options = {}) { const url = `${CONFIG.url}${endpoint}`; const headers = { "Authorization": AUTH_HEADER, "User-Agent": "OpenClaw-Nextcloud-Skill", ...options.headers }; try { ...[truncated 2716 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/nextcloud.js:15564
Finding

Insufficient DAV Path Validation Permits Dot-Segment Traversal Outside the Intended File Namespace

Content
View full analysis
str: nc_path = nc_path.lstrip("/") encoded = urllib.parse.quote(nc_path, safe="/") return f"{url}/remote.php/dav/files/{user}/{encoded}" ``` ### Technical Analysis Neither path-normalization routine rejects `.` or `..` components. Dot characters remain unescaped by normal URL quoting, and standard URL processing performed by clients, proxies, or servers may resolve these segments before routing the request. For example, a value containing `../../` can cause a URL initially constructed under: ```text /remote.php/dav/files// ``` to normalize into a different DAV or application path. The exact reachable endpoint depends on URL normalization and Nextcloud routing, but the application no longer guarantees that the operation remains in the intended user-file namespace. The JavaScript function also accepts any absolute HTTP or HTTPS URL and extracts its pathname without verifying that the supplied URL belongs to the configu ...[truncated 1857 chars]
Remediation
View remediation
/`. 6. When accepting a full DAV href: - Require HTTPS. - Require an origin equal to `NEXTCLOUD_URL`. - Require the exact expected DAV path prefix. - Reject URLs containing credentials or fragments. 7. Do not locate the expected prefix with an unrestricted substring search. Require it at the beginning of the normalized pathname. 8. Add tests for raw, encoded, and double-encoded traversal payloads, mixed separators, absolute URLs from foreign origins, and malformed percent encoding. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (24)

Tainted flow: 'req' from os.environ.get (line 144, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/files_binary.py (reported line 79)May include surrounding context.

python
dav_url = _dav_url(nc_path, url, user)
    req = urllib.request.Request(dav_url, headers=_auth(user, token))
    try:
        with urllib.request.urlopen(req) as resp:
            data = resp.read()
        os.makedirs(os.path.dirname(os.path.abspath(local_path)), exist_ok=True)
        with open(local_path, "wb") as f:

Tainted flow: 'req' from os.environ.get (line 144, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/files_binary.py (reported line 101)May include surrounding context.

python
dav_url = _dav_url(nc_path, url, user)
    req = urllib.request.Request(dav_url, headers=_auth(user, token))
    try:
        with urllib.request.urlopen(req) as resp:
            data = resp.read()
        os.makedirs(os.path.dirname(os.path.abspath(local_path)), exist_ok=True)
        with open(local_path, "wb") as f:

Tainted flow: 'req' from os.environ.get (line 144, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/files_binary.py (reported line 146)May include surrounding context.

python
dav_url = _dav_url(nc_path, url, user)
    req = urllib.request.Request(dav_url, headers=_auth(user, token))
    try:
        with urllib.request.urlopen(req) as resp:
            data = resp.read()
        os.makedirs(os.path.dirname(os.path.abspath(local_path)), exist_ok=True)
        with open(local_path, "wb") as f:

Tainted flow: 'req' from os.environ.get (line 144, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/files_binary.py (reported line 118)May include surrounding context.

python
method="PROPFIND",
    )
    try:
        with urllib.request.urlopen(req):
            pass
        print(f"EXISTS {nc_path}")
        sys.exit(0)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The code interacts only with Nextcloud file storage via WebDAV endpoints under /remote.php/dav/files/{user}/. It supports binary file MIME handling, upload/download, path existence checks, and listing directory contents. There is no logic for notes, tasks, calendars, contacts, vCard parsing, or CardDAV-safe contact create/update. Because the declared description presents a broad multi-domain Nextcloud integration and specifically highlights contact handling, while the actual code chunk is narrowly focused on file transfer, the description does not accurately represent this code chunk's behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

This code appears to be third-party date utility/library code rather than Nextcloud integration logic. The excerpt implements token-based date formatters, locale data, relative date formatting, and miscellaneous date helpers. There is no evidence of network access, Nextcloud endpoints, file operations, notes/tasks/calendar/contact synchronization, or CardDAV-safe vCard create/update handling. Because the actual behavior shown is materially different from the declared purpose, this is a clear description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The code shown consists of transpilation helpers and date-fns parsing components such as year/month/day/hour/timezone parsers. These are support libraries for date parsing and object/class helpers. There is no evidence in this chunk of connecting to Nextcloud, making HTTP/WebDAV/CardDAV/CalDAV requests, accessing notes/tasks/files/contacts, or implementing robust contact create/update logic. Because the declared description specifically promises a reliable Nextcloud integration across several resource types, while the actual chunk is generic parsing infrastructure with a materially different apparent purpose, this is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

This code chunk is unrelated support/library code from date-fns. It implements generic date parsing and date/time helpers such as parse, parseISO, isMatch, isPast, isSameWeek, rounding, conversions, and setters. There is no evidence of Nextcloud API calls, DAV/CardDAV operations, file handling, notes/tasks/calendar/contact CRUD, authentication, or external service interaction. Because the declared description centers on a broad Nextcloud integration skill while the actual code shown is only date utility logic, the description does not accurately represent this chunk's behavior.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- Never hardcode credentials in `SKILL.md`, scripts, examples, commit messages, or changelog text.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
The skill ships two scripts: `scripts/nextcloud.js` (Node.js, text operations) and `scripts/files_binary.py` (Python 3, binary file transfers). Review both befo

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
The skill ships two scripts: `scripts/nextcloud.js` (Node.js, text operations) and `scripts/files_binary.py` (Python 3, binary file transfers). Review both befo

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
The skill ships two scripts: `scripts/nextcloud.js` (Node.js, text operations) and `scripts/files_binary.py` (Python 3, binary file transfers). Review both befo

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
The skill ships two scripts: `scripts/nextcloud.js` (Node.js, text operations) and `scripts/files_binary.py` (Python 3, binary file transfers). Review both befo

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
The skill ships two scripts: `scripts/nextcloud.js` (Node.js, text operations) and `scripts/files_binary.py` (Python 3, binary file transfers). Review both befo

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
The skill ships two scripts: `scripts/nextcloud.js` (Node.js, text operations) and `scripts/files_binary.py` (Python 3, binary file transfers). Review both befo

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
The skill ships two scripts: `scripts/nextcloud.js` (Node.js, text operations) and `scripts/files_binary.py` (Python 3, binary file transfers). Review both befo

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
The skill ships two scripts: `scripts/nextcloud.js` (Node.js, text operations) and `scripts/files_binary.py` (Python 3, binary file transfers). Review both befo

Lp1

High
Category
MCP Least Privilege
Confidence
91% confidence
Finding

Undeclared network capability is significant in a skill because it enables outbound authenticated communication without transparent permission gating. Given this script handles file upload/download and uses Basic authentication headers, hidden or undeclared network access materially raises the risk of unauthorized data transfer if the skill is misused or modified.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
91% confidence
Finding

Undeclared network capability is significant in a skill because it enables outbound authenticated communication without transparent permission gating. Given this script handles file upload/download and uses Basic authentication headers, hidden or undeclared network access materially raises the risk of unauthorized data transfer if the skill is misused or modified.

Content

No source excerpt is available for this finding.

Memory Manipulation

High
Category
Memory Poisoning
Confidence
80% confidence
Finding

Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Content

Scanner excerpt · scripts/nextcloud.js (reported line 16804)May include surrounding context.

js
if (updates.fullName !== void 0 || Object.values(nameUpdates).some((value) => value !== void 0)) {
      const resolvedFullName = updates.fullName !== void 0 ? String(updates.fullName || "").trim() : buildDisplayName(nextName, "");
      if (!resolvedFullName) {
        throw new Error("Updated name is empty. Provide --name or structured name fields.");
      }
      vcard = this._updateVCardField(vcard, "FN", encodeVCardText(resolvedFullName));
      vcard = this._updateVCardField(vcard, "N", buildStructuredNameValue(nextName));

Persistent Context Injection

Medium
Category
Memory Poisoning
Confidence
80% confidence
Finding

The skill explicitly instructs the agent to persist operational rules in memory, including behavior defaults and error-handling heuristics. Persistent context injection is risky because these instructions can outlive the current task, influence unrelated future interactions, and cause the agent to follow skill-authored policies as durable memory without user consent or trust-boundary checks.

Content

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

md
- If no writable event calendar exists, mark calendar mutation tests as intentionally skipped (environment limitation), and still run `calendar list`.
- Do not treat this as a skill failure; treat it as a server capability/permission constraint.

## Persistent Rules (Store These)

Persist these high-value rules in memory/rules:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The note deletion path issues a DELETE request directly, and similar direct delete handlers exist for files, calendar events, tasks, and contacts, without any confirmation prompt, warning log, or explanatory comment in the code. Because these operations permanently modify or remove user data, the file lacks the user disclosure expected for safety-critical actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The upload handler performs a PUT to the user's Nextcloud files area, creating or overwriting remote content, but there is no confirmation prompt, warning log, or code comment disclosing that user data will be written remotely. Since file writes are safety-relevant operations, this lacks the expected explicit disclosure in a code file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The configuration block reads NEXTCLOUD_USER and NEXTCLOUD_TOKEN from the environment and later uses them for authenticated requests, but the code does not include a warning or explanatory comment about handling credentials. Access to credentials is in scope for missing-warning checks when there is no user disclosure.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/nextcloud.js:15147