Back to skill

Security audit

Adguard Test

Security checks for vulnerabilities and agentic risk

Overview

This AdGuard Home skill mostly does what it claims, but it can send administrator credentials and session cookies over unencrypted HTTP while also exposing sensitive DNS activity data.

Review before installing. Use HTTPS-only AdGuard URLs, avoid plaintext adguard-instances.json with real admin passwords, prefer environment variables or a secrets manager, and assume querylog/clients output may reveal browsing history and internal network details. Do not use this in shared or multi-user workspaces without tightening credential handling and redacting outputs.

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

T09 · Insecure Skill Coding Practices

Error
Location
index.js:62
Finding
Administrator Credentials and Session Cookies May Be Transmitted over Plaintext HTTP<![CDATA[ ## Vulnerability Details **File Location**: `index.js:62-66`, `index.js:113-155`, `index.js:169-176`, `README.md:40-45`, `README.md:58-65`, `SKILL.md:56-62`, `SKILL.md:199-204`, `SKILL.md:240-244` **Vulnerability Type**: Plaintext transmission of sensitive authentication data **Risk Level**: High ### Vulnerable Code The URL validator explicitly accepts both HTTP and HTTPS: ```javascript function validateUrl(urlStr) { try { const parsed = new URL(urlStr); return (parsed.protocol === 'http:' || parsed.protocol === 'https:') && parsed.hostname; } catch { return false; } } ``` The HTTP client selects the unencrypted Node.js HTTP implementation whenever an `http:` URL is configured. It then sends any session cookie through that connection: ```javascript function httpRequest(baseUrl, endpoint, method = 'GET', postData = null, cookie = null) { return new Promise((resolve, reject) => { const fullUrl = new URL(endpoint, baseUrl); const protocol = fullUrl.protocol === 'https:' ? https : http; const options = { hostname: fullUrl.hostname, port: fullUrl.port || (fullUrl.protocol === 'https:' ? 443 : 80), path: fullUrl.pathname + fullUrl.search, method: method, headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', } }; if (cookie) { options.headers['Cookie'] = cookie; } if (postData) { options.headers['Content-Length'] = Buffer.byteLength(postData); } const req = protocol.request(options, (res) => { const cookies = res.headers['set-cookie']; let cookieValue = null; if (cookies) { cookieValue = cookies.map(c => c.split(';')[0]).join('; '); } let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => { resolve({ statusCode: res.statusCode, data: data, cookie: cookieValue }); }); ...[truncated 3901 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Require HTTPS by default** - Change URL validation to accept only `https:` URLs. - Reject plaintext HTTP before any authentication request is made. ```javascript function validateUrl(urlStr) { try { const parsed = new URL(urlStr); return parsed.protocol === 'https:' && Boolean(parsed.hostname); } catch { return false; } } ``` 2. **Provide an explicit unsafe local-network override only if necessary** - If legacy AdGuard Home deployments require HTTP, require a clearly named setting such as `ADGUARD_ALLOW_INSECURE_HTTP=true`. - Keep the override disabled by default. - Print a prominent warning before transmitting credentials. - Document that the override must only be used over a separately secured transport, such as a loopback connection, trusted tunnel, or mutually authenticated VPN. 3. **Correct all documentation** - Replace every `http://` example in `README.md`, `SKILL.md`, and runtime error messages with `https://`. - Explain that environment variables protect secret storage but do not encrypt network traffic. - Do not describe an HTTP deployment as secure merely because credentials come from environment variables or a secrets manager. 4. **Use least-privilege credentials** - Recommend a dedicated account limited to the monitoring operations required by the skill where AdGuard Home supports such authorization. - Avoid using a general administrator account when a restricted account is available. 5. **Preserve certificate verification** - Continue using Node.js HTTPS certificate verification. - Do not introduce a global `rejectUnauthorized: false` workaround for private certificates. - Support a configured private certificate authority when deployments use an internal PKI. 6. **Add regression tests** - Verify that `http://` configurations are rejected by default. - Verify that `https://` configurations remain accepted. ...[truncated 218 chars]
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (25)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
**Attack Vector:**
- Malicious instance configuration with crafted `url`, `username`, or `password`
- Example: `password: "admin' && rm -rf / #"`
- Shell command injection via unescaped parameters

**Fix:**
Confidence
90% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
**Attack Vector:**
- Malicious instance configuration with crafted `url`, `username`, or `password`
- Example: `password: "admin' && rm -rf / #"`
- Shell command injection via unescaped parameters

**Fix:**
Confidence
90% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Chaining Abuse

High
Category
Tool Misuse
Content
**Attack Vector:**
- Malicious instance configuration with crafted `url`, `username`, or `password`
- Example: `password: "admin' && rm -rf / #"`
- Shell command injection via unescaped parameters

**Fix:**
Confidence
75% confidence
Finding
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

YARA rule 'agent_skill_destructive_autonomous_actions': Autonomous destructive filesystem, shell history, or repository actions in AI agent skills [agent_skills]

High
Category
YARA Match
Content
verity:** CRITICAL  
**CVSS Score:** 9.8 (Critical)

**Issue:**
```javascript
// VULNERABLE CODE (v1.1.1)
execSync(`curl -s -X POST ${url}/control/login -H "Content-Type: application/json" -d '{"name":"${username}","password":"${password}"}' -c ${cookieFile}`);
```

**Attack Vector:**
- Malicious instance configuration with crafted `url`, `username`, or `password`
- Example: `password: "admin' && rm -rf / #"`
- Shell command injection via unescaped parameters

**Fix:**
```javascript
// SECURE CODE (v1.2.0)
async function authenticate(baseUrl, username, password) {
  const response = await httpRequest(
    baseUrl, 
    '/control/login', 
    'POST', 
    JSON.stringify({ name: username, password: password })
  );
  return response.cookie;
}
```

**Mitigation:**
- ✅ Removed all `execSync` and `child_process` usage
- ✅ Implemented native `http`/`https` module for API calls
- ✅ No shell command execution

---

### 2. Missing Input Validation (CWE-20) - **FIXED** ✅

**Severity:** H
Confidence
75% confidence
Finding
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Ae1

High
Category
analysis-evasion
Content
- **Entrypoint | 入口文件:** `index.js`
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Tool Parameter Abuse

High
Category
Tool Misuse
Content
### 1. Command Injection Prevention

**Test:** `node index.js stats "invalid;rm -rf /"`

**Result:** ✅ **BLOCKED**
```
Confidence
85% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
### 1. Command Injection Prevention

**Test:** `node index.js stats "invalid;rm -rf /"`

**Result:** ✅ **BLOCKED**
```
Confidence
90% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Chaining Abuse

High
Category
Tool Misuse
Content
### 1. Command Injection Prevention

**Test:** `node index.js stats "invalid;rm -rf /"`

**Result:** ✅ **BLOCKED**
```
Confidence
75% confidence
Finding
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

External Transmission

Medium
Category
Data Exfiltration
Content
**Issue:**
```javascript
// VULNERABLE CODE (v1.1.1)
execSync(`curl -s -X POST ${url}/control/login -H "Content-Type: application/json" -d '{"name":"${username}","password":"${password}"}' -c ${cookieFile}`);
```

**Attack Vector:**
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

File System Enumeration

Medium
Category
Data Exfiltration
Content
3. **Restrict config file permissions:**
   ```bash
   chmod 600 ~/.openclaw/workspace/adguard-instances.json
   ls -la ~/.openclaw/workspace/adguard-instances.json
   # Should show: -rw------- (only owner can read/write)
   ```
Confidence
60% confidence
Finding
Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
This report explicitly labels the skill as 'SECURE' and recommends production deployment even though it also documents a remaining plaintext credential risk and warns against multi-user use. That creates a misleading security assurance that could cause operators to deploy the skill in environments where credential compromise is still plausible.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
3. **Secure the config file | 保护配置文件:**
   ```bash
   chmod 600 ~/.openclaw/workspace/adguard-instances.json
   ```

4. **Test the skill | 测试技能:**
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
3. **Secure the config file | 保护配置文件:**
   ```bash
   chmod 600 ~/.openclaw/workspace/adguard-instances.json
   ```

4. **Test the skill | 测试技能:**
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
3. **Secure the config file | 保护配置文件:**
   ```bash
   chmod 600 ~/.openclaw/workspace/adguard-instances.json
   ```

4. **Test the skill | 测试技能:**
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The skill prominently supports retrieving recent DNS query logs and shows examples containing domains and client IP addresses, which are sensitive operational and browsing-activity data. Without an explicit privacy warning, access-control expectations, and guidance on safe handling/redaction, users may expose personal or organizational telemetry in shared terminals, logs, screenshots, or chat transcripts.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The version history asserts plaintext credential storage instructions were removed, but the document still includes examples that place admin usernames and passwords in JSON configuration files. This mismatch can mislead users into believing the skill has been fully hardened when it still normalizes insecure secret handling, increasing the chance of credential disclosure through local file leakage, backups, or accidental commits.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The report explicitly acknowledges plaintext credential storage in `adguard-instances.json` with world-readable/group-readable permissions, yet still concludes the skill is 'Production Ready' and recommends deployment. This weak warning can normalize insecure handling of sensitive secrets and lead users to deploy a configuration where local users or backup/sync systems can read administrative credentials.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
### Recommendations
1. ✅ **Deploy to production** - Safe for use
2. ⚠️ **Restrict config file permissions** - `chmod 600`
3. 📝 **Update ClawHub** - Publish v1.2.0
4. 🔍 **Monitor for updates** - Security patches as needed
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
### Recommendations
1. ✅ **Deploy to production** - Safe for use
2. ⚠️ **Restrict config file permissions** - `chmod 600`
3. 📝 **Update ClawHub** - Publish v1.2.0
4. 🔍 **Monitor for updates** - Security patches as needed
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Intent-Code Divergence

Medium
Confidence
93% confidence
Finding
The module header explicitly claims secure credential handling, but the implementation still loads plaintext credentials from a local JSON file in the skill directory. This creates a misleading security posture and increases the risk of accidental credential exposure through source control, workspace sharing, backups, or local compromise.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The querylog command retrieves and prints recent DNS queries, including domains, clients, timestamps, and filtering rules, which can reveal sensitive browsing history and internal network activity. In an agent skill context, exposing this data without an explicit privacy warning, confirmation step, or output minimization increases the chance of unintended disclosure to users, logs, transcripts, or downstream tooling.

Excessive Permissions

Low
Category
Privilege Escalation
Content
cat ~/.openclaw/workspace/adguard-instances.json
   ```

3. **Restrict config file permissions:**
   ```bash
   chmod 600 ~/.openclaw/workspace/adguard-instances.json
   ls -la ~/.openclaw/workspace/adguard-instances.json
Confidence
80% confidence
Finding
Skill requests more permissions than appear necessary for its stated functionality. Review if elevated access is justified.

Intent-Code Divergence

Low
Confidence
93% confidence
Finding
The documentation is internally inconsistent about where configuration is stored and searched: the changelog claims workspace-only behavior, while earlier install/FAQ text references a broader global workspace path. Such inconsistency can cause users to place secrets in unexpected locations, weakening assumptions about access controls and making credentials easier to overlook, expose, or retain unintentionally.

Excessive Permissions

Low
Category
Privilege Escalation
Content
**Issue:** Credentials stored in plaintext in `adguard-instances.json`

**Current Permissions:**
```bash
-rw-rw-r-- 1 foxleoly foxleoly 268 Feb 24 00:39 adguard-instances.json
```
Confidence
98% confidence
Finding
The file permissions shown (`-rw-rw-r--`) allow group and other read access to a file containing plaintext credentials. On a multi-user system or in environments with shared accounts, this can expose admin credentials to unauthorized local users and facilitate takeover of the managed AdGuard Home instances.

Missing User Warnings

Low
Confidence
80% confidence
Finding
The clients command enumerates configured and auto-discovered client information, exposing device names, identifiers, and policy details that form a useful network inventory. While this is an intended administrative function, presenting it without warning or scoping can leak internal topology and host metadata through console output, logs, or agent transcripts.

Static analysis

No suspicious patterns detected.