Back to skill

Security audit

Adguard Home

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but it can send AdGuard admin credentials over unencrypted HTTP and has confusing guidance about storing credentials in local files.

Review before installing. Use HTTPS-only AdGuard Home URLs, avoid the documented http:// examples, and do not store administrator passwords in adguard-instances.json unless the file is strictly local and locked down. Install only if you are comfortable granting this skill access to DNS query history, client identifiers, filtering rules, and other AdGuard control-plane 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 (1)

T09 · Insecure Skill Coding Practices

Error
Location
index.js:60
Finding

AdGuard Administrator Credentials and Session Cookies May Be Transmitted Over Plaintext HTTP

Content
View full analysis

Vulnerability Details

File Location: index.js:60-67, index.js:112-164, index.js:169-176, SKILL.md:59-62, SKILL.md:202-204, SKILL.md:225-228, README.md:43-45, README.md:62-65
Vulnerability Type: Cleartext transmission of sensitive information
Risk Level: High

The URL validator explicitly permits both HTTP and HTTPS. The HTTP client then selects the unencrypted Node.js http transport whenever the configured URL uses the http: scheme. Authentication credentials are submitted in the request body, and the resulting session cookie is attached to subsequent requests using the same unencrypted transport.

Complete relevant code:

javascript
/**
 * Validate URL format
 */
function validateUrl(urlStr) {
  try {
    const parsed = new URL(urlStr);
    return (parsed.protocol === 'http:' || parsed.protocol === 'https:') && parsed.hostname;
  } catch {
    return false;
  }
}
javascript
/**
 * Make HTTP POST request with cookie handling
 */
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) {
        cookieValu
...[truncated 3536 chars]
Remediation
View remediation

Remediation Suggestions

  1. Require HTTPS in the URL validator:

    javascript
    function validateUrl(urlStr) {
      try {
        const parsed = new URL(urlStr);
        return parsed.protocol === 'https:' && Boolean(parsed.hostname);
      } catch {
        return false;
      }
    }
    
  2. If plaintext HTTP is necessary for isolated development environments, require an explicit opt-in such as ADGUARD_ALLOW_INSECURE_HTTP=true. Reject HTTP by default and display a prominent warning that credentials and cookies will be exposed in transit.

  3. Replace every http:// configuration example in README.md, SKILL.md, and runtime error messages with an https:// example.

  4. Preserve Node.js certificate verification. Do not set rejectUnauthorized: false. Document how users can configure a trusted internal certificate authority for self-hosted AdGuard Home deployments.

  5. Recommend a dedicated least-privileged account where supported rather than a general-purpose administrator account.

  6. Update SECURITY_AUDIT.md so it does not characterize the current implementation as providing secure HTTP communication while plaintext HTTP remains accepted.

  7. Add automated tests confirming that HTTP URLs are rejected by default and that credentials and cookies are only transmitted over TLS.

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

Tool Parameter Abuse

High
Category
Tool Misuse
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).

Content

Scanner excerpt · SECURITY_AUDIT.md (reported line 33)May include surrounding context.

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

**Fix:**

Tool Parameter Abuse

High
Category
Tool Misuse
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).

Content

Scanner excerpt · TEST_REPORT.md (reported line 39)May include surrounding context.

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

**Fix:**

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · SECURITY_AUDIT.md (reported line 33)May include surrounding context.

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

**Fix:**

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
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · SECURITY_AUDIT.md (reported line 33)May include surrounding context.

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

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- **Entrypoint | 入口文件:** `index.js`

Tool Parameter Abuse

High
Category
Tool Misuse
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).

Content

Scanner excerpt · TEST_REPORT.md (reported line 39)May include surrounding context.

1. Command Injection Prevention

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

Result: ✅ BLOCKED

text

Tool Parameter Abuse

High
Category
Tool Misuse
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).

Content

Scanner excerpt · TEST_REPORT.md (reported line 39)May include surrounding context.

1. Command Injection Prevention

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

Result: ✅ BLOCKED

text

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · TEST_REPORT.md (reported line 39)May include surrounding context.

1. Command Injection Prevention

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

Result: ✅ BLOCKED

text

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SECURITY_AUDIT.md (reported line 28)May include surrounding context.

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:

File System Enumeration

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.

Content

Scanner excerpt · SECURITY_AUDIT.md (reported line 206)May include surrounding context.

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

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SECURITY_AUDIT.md (reported line 205)May include surrounding context.

  1. Secure the config file | 保护配置文件:

    bash
    chmod 600 ~/.openclaw/workspace/adguard-instances.json
    
  2. Test the skill | 测试技能:

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

  1. Secure the config file | 保护配置文件:

    bash
    chmod 600 ~/.openclaw/workspace/adguard-instances.json
    
  2. Test the skill | 测试技能:

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · TEST_REPORT.md (reported line 120)May include surrounding context.

  1. Secure the config file | 保护配置文件:

    bash
    chmod 600 ~/.openclaw/workspace/adguard-instances.json
    
  2. Test the skill | 测试技能:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill explicitly surfaces recent DNS queries, blocked domains, and client IP activity, which may reveal sensitive browsing patterns, internal hostnames, and device identifiers. Without a privacy warning or access-control guidance, operators may expose highly sensitive monitoring data to users who should not see it.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The document claims file-based credential loading was removed, yet it still instructs users to create adguard-instances.json containing an admin username and password. This inconsistency can mislead users into storing sensitive credentials on disk despite the stated security posture, increasing risk of accidental exposure through backups, workspace sharing, or version control.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SECURITY_AUDIT.md (reported line 225)May include surrounding context.

md
### 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

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · TEST_REPORT.md (reported line 153)May include surrounding context.

md
### 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

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The URL validation explicitly allows both http and https, and the tool then sends AdGuard credentials to /control/login and later retrieves query logs, client details, and DNS configuration over whatever scheme is configured. If an instance is configured with plain HTTP, credentials and sensitive operational data can be exposed to interception or manipulation by anyone on the network path.

Content

No source excerpt is available for this finding.

Excessive Permissions

Low
Category
Privilege Escalation
Confidence
80% confidence
Finding

Skill requests more permissions than appear necessary for its stated functionality. Review if elevated access is justified.

Content

Scanner excerpt · SECURITY_AUDIT.md (reported line 203)May include surrounding context.

cat ~/.openclaw/workspace/adguard-instances.json

text

3. **Restrict config file permissions:**
```bash
chmod 600 ~/.openclaw/workspace/adguard-instances.json
ls -la ~/.openclaw/workspace/adguard-instances.json

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The FAQ/version history asserts that file-config references were removed from the documentation, but the same document still includes multiple file-based configuration examples. While this is primarily a documentation integrity issue, it can cause users to trust inaccurate security claims and follow weaker credential-handling practices.

Content

No source excerpt is available for this finding.

Excessive Permissions

Low
Category
Privilege Escalation
Confidence
98% confidence
Finding

This report explicitly documents that credentials are stored in plaintext in adguard-instances.json and shows the file as world-readable by others on the system (-rw-rw-r--). On a multi-user host, local users could read the file and recover AdGuard administrative credentials, enabling unauthorized access to the DNS management interface.

Content

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

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

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

Line L62 identifies the checker as "Programming Master (编程大师)", introducing a specific language/locale element in natural-language content without any user opt-in or documented justification. This can conflict with language/locale policy requirements that avoid forcing or implicitly imposing a language choice.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.