T09 · Insecure Skill Coding Practices
Error
- Location
- index.js:60
- Finding
- AdGuard Administrator Credentials and Session Cookies May Be Transmitted Over Plaintext HTTP## 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
- ## 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.
