Back to skill

Security audit

Controld

Security checks for vulnerabilities and agentic risk

Overview

This Control D skill is coherent for DNS management, but it needs review because it can make live account changes and includes high-risk endpoint deployment commands without strong safeguards.

Install only if you are comfortable giving the skill access to a Control D API token. Prefer a least-privilege or read-only token unless you truly need write operations, restrict the token by IP where possible, and require manual confirmation before deletes, organization updates, default-rule changes, provisioning changes, or mass deployment. Do not run the documented RMM installer one-liners across endpoints unless you independently verify the installer source, signature or checksum, and test it in a controlled environment first.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:421
Finding
Unpinned Remote Installer Is Downloaded and Executed<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:421-424` **Vulnerability Type**: Execution of mutable remote code without integrity verification **Risk Level**: High ### Vulnerable Code ```powershell # Windows (PowerShell as Admin) (Invoke-WebRequest -Uri 'https://api.controld.com/dl/rmm' -UseBasicParsing).Content | Set-Content "$env:TEMP\ctrld_install.ps1"; Invoke-Expression "& '$env:TEMP\ctrld_install.ps1' 'CODE'" ``` ```bash # macOS/Linux sh -c 'sh -c "$(curl -sSL https://api.controld.com/dl/rmm)" -s CODE' ``` ### Technical Analysis The documented deployment commands retrieve an installer from `https://api.controld.com/dl/rmm` and immediately execute the returned content. The downloaded payload is not tied to a fixed release, cryptographic digest, or verified digital signature. Consequently, the effective code executed by this skill workflow can change after the repository has been audited. HTTPS authenticates the server connection but does not establish that the returned script is a particular reviewed version. If the distribution endpoint, its hosting infrastructure, DNS resolution, TLS trust chain, or vendor release process is compromised, arbitrary replacement code can be delivered. The Windows workflow is explicitly intended to run from an administrative PowerShell session and uses `Invoke-Expression`. The Unix workflow passes the response directly to `sh`. Both patterns cross a network-to-code execution boundary without an independent integrity control. ### Attack Path 1. A user or automation operator creates or obtains a provisioning code. 2. Following the skill instructions, the operator runs the documented deployment command, potentially across many systems through an RMM platform. 3. The command retrieves the current response from `/dl/rmm`. 4. An attacker who has compromised the distribution endpoint or an equivalent trusted delivery component substitutes a malicious script. 5. PowerShell or `sh` interprets the substitute ...[truncated 970 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the mutable endpoint with a versioned, immutable artifact URL. 2. Publish a cryptographic SHA-256 or stronger digest through a separately protected release channel. 3. Download the installer to a newly created, access-restricted temporary file rather than piping it directly into an interpreter. 4. Verify the artifact digest before execution and abort on any mismatch. 5. On Windows, require a valid Authenticode signature from an explicitly trusted publisher. 6. On macOS, verify code signing and notarization where applicable. 7. Avoid `Invoke-Expression` and `curl | sh`; invoke a verified local artifact using a fixed interpreter and constrained arguments. 8. Display the artifact version, signer identity, and verification result before requesting explicit execution approval. 9. For RMM deployment, stage and approve the verified artifact internally rather than downloading mutable code independently on every endpoint. 10. Apply least privilege and avoid administrative execution unless the documented installation step demonstrably requires it. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/controld.sh:105
Finding
Unescaped CLI Arguments Are Interpolated into Privileged API JSON Payloads<![CDATA[ ## Vulnerability Details **File Location**: `scripts/controld.sh:105-109, 116-119, 136-140, 260-264, 285-289, 304-308, 326-330, 449-457` **Vulnerability Type**: JSON injection and malformed request construction **Risk Level**: Medium ### Vulnerable Code Representative affected functions include: ```bash profiles_create() { local name="$1" local clone_id="${2:-}" if [[ -n "$clone_id" ]]; then api POST /profiles -d "{\"name\":\"$name\",\"clone_profile_id\":\"$clone_id\"}" else api POST /profiles -d "{\"name\":\"$name\"}" fi | jq '.body' } ``` ```bash profiles_clone() { local name="$1" local clone_id="$2" api POST /profiles -d "{\"name\":\"$name\",\"clone_profile_id\":\"$clone_id\"}" | jq '.body' } ``` ```bash devices_create() { local name="$1" local profile_id="$2" local icon="${3:-router}" api POST /devices -d "{\"name\":\"$name\",\"profile_id\":\"$profile_id\",\"icon\":\"$icon\"}" | jq '.body' } ``` ```bash folders_create() { local profile_id="$1" local name="$2" local do_action="${3:-0}" api POST "/profiles/$profile_id/groups" -d "{\"name\":\"$name\",\"do\":$do_action}" | jq '.body' } ``` ```bash rules_create() { local profile_id="$1" local do_action="$2" shift 2 local hostnames hostnames=$(printf '"%s",' "$@" | sed 's/,$//') api POST "/profiles/$profile_id/rules" -d "{\"hostnames\":[$hostnames],\"do\":$do_action,\"status\":1}" | jq '.body' } ``` ```bash default_set() { local profile_id="$1" local do_action="$2" api PUT "/profiles/$profile_id/default" -d "{\"do\":$do_action,\"status\":1}" | jq '.body' } ``` ```bash access_learn() { local device_id="$1" shift local ips ips=$(printf '"%s",' "$@" | sed 's/,$//') api POST /access -d "{\"device_id\":\"$device_id\",\"ips\":[$ips]}" | jq '.' } ``` ```bash provision_create() { local profile_id="$1" local device_type="${2:-windows}" local expires_after= ...[truncated 3438 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Construct every JSON body with `jq` rather than string concatenation. For example: ```bash payload=$(jq -n \ --arg name "$name" \ --arg clone_profile_id "$clone_id" \ '{name: $name, clone_profile_id: $clone_profile_id}') api POST /profiles -d "$payload" ``` 2. Construct arrays through `jq` so every element is correctly encoded: ```bash hostnames_json=$(printf '%s\n' "$@" | jq -R . | jq -s .) payload=$(jq -n \ --argjson hostnames "$hostnames_json" \ --argjson action "$do_action" \ '{hostnames: $hostnames, do: $action, status: 1}') ``` 3. Validate input types and allowed values before request construction: - Restrict actions to documented integer enums. - Require `limit` to match an allowed positive-integer range. - Restrict device types and icons to documented values. - Validate IP addresses using an IPv4/IPv6 parser. - Validate hostnames according to the accepted Control D rule syntax. - Validate identifiers against the documented identifier format. 4. Use `jq --argjson` only after validating that a value is valid JSON of the expected primitive type. Use `--arg` for all ordinary strings. 5. Reject control characters and unexpected empty values where the API does not permit them. 6. Add regression tests containing quotation marks, backslashes, newlines, brackets, commas, and Unicode characters. 7. Apply least-privilege API tokens and separate read-only operations from modification workflows. 8. Require explicit confirmation before high-impact operations such as changing default DNS actions, creating provisioning codes, or modifying organization settings. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (110)

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The provisioning section includes remote deployment commands that download and execute scripts directly on endpoints, including PowerShell `Invoke-Expression` and shell piping from `curl`. This materially expands the skill from DNS management into remote code execution on managed devices, creating a severe compromise path if misused, substituted, or invoked without strong operator review.

Missing User Warnings

High
Confidence
98% confidence
Finding
The provisioning workflow presents downloaded-script execution on endpoints without an explicit warning that it runs remote code with elevated privileges. This normalizes a high-risk practice and could lead operators or agents to execute unreviewed code across many systems.

Ae1

High
Category
analysis-evasion
Content
Use `scripts/controld.sh` for common operations:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
Use `scripts/controld.sh` for common operations:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
Use `scripts/controld.sh` for common operations:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
Use `scripts/controld.sh` for common operations:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
Use `scripts/controld.sh` for common operations:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
Use `scripts/controld.sh` for common operations:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
Use `scripts/controld.sh` for common operations:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
Use `scripts/controld.sh` for common operations:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
Use `scripts/controld.sh` for common operations:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
Use `scripts/controld.sh` for common operations:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
Use `scripts/controld.sh` for common operations:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
Use `scripts/controld.sh` for common operations:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
Use `scripts/controld.sh` for common operations:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
Use `scripts/controld.sh` for common operations:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
Use `scripts/controld.sh` for common operations:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
Use `scripts/controld.sh` for common operations:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
Use `scripts/controld.sh` for common operations:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
Use `scripts/controld.sh` for common operations:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
Use `scripts/controld.sh` for common operations:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Tool Parameter Abuse

High
Category
Tool Misuse
Content
profiles_delete() {
    local id="$1"
    api DELETE "/profiles/$id" | jq '.'
}

profiles_options() {
Confidence
94% confidence
Finding
The function deletes a profile based solely on a supplied identifier, with no validation of intent, confirmation, or guardrails. In an agent setting, untrusted prompt content or parameter manipulation could coerce deletion of critical DNS policy objects, causing loss of service controls or operational disruption.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
devices_delete() {
    local id="$1"
    api DELETE "/devices/$id" | jq '.'
}

# Filters
Confidence
94% confidence
Finding
This endpoint removes devices by arbitrary supplied ID without safety checks. Abuse could disconnect endpoints from intended DNS policies or delete production device registrations, leading to outages or security policy bypass.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
folders_delete() {
    local profile_id="$1"
    local folder_id="$2"
    api DELETE "/profiles/$profile_id/groups/$folder_id" | jq '.'
}

# Custom rules
Confidence
92% confidence
Finding
Folder deletion is performed directly from user-controlled parameters with no confirmation or validation. An incorrect or injected folder ID could remove groups of DNS rules, potentially weakening or disabling filtering policy at scale.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
rules_delete() {
    local profile_id="$1"
    local hostname="$2"
    api DELETE "/profiles/$profile_id/rules/$hostname" | jq '.'
}

# Default rule
Confidence
93% confidence
Finding
The script deletes custom DNS rules using a raw hostname path parameter, again without guardrails. If driven by an LLM agent, an attacker could influence parameters to remove allow/block rules, undermining protections or changing traffic handling for targeted domains.

Static analysis

No suspicious patterns detected.