Back to skill

Security audit

aida

Security checks for vulnerabilities and agentic risk

Overview

This smart-building skill matches its stated AIDA integration purpose, but it can send authenticated control commands with weak safeguards and misleading success responses.

Review this skill carefully before installing in any environment connected to real building systems. Use only a narrowly scoped AIDA token, lock the API URL to a trusted HTTPS host, require explicit confirmation and authorization for control or optimization, and fix response handling so failures are never reported as successful.

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

T09 · Insecure Skill Coding Practices

Error
Location
skills/aida/index.js:3
Finding

Bearer Credential Can Be Transmitted to an Unrestricted Endpoint

Content
View full analysis

Vulnerability Details

File Location: skills/aida/index.js:3-4, 26-31
Vulnerability Type: Unrestricted transmission of sensitive credentials
Risk Level: High

Vulnerable Code

js
const API = process.env.AIDA_API_URL;
const KEY = process.env.AIDA_API_KEY;

async function call(path, fallback) {
  try {
    const res = await fetch(API + path, {
      headers: {
        'Authorization': `Bearer ${KEY}`,
        'Content-Type': 'application/json'
      }
    });

Technical Analysis

The destination URL is taken directly from the AIDA_API_URL environment variable without URL parsing, HTTPS enforcement, host validation, or an origin allowlist. The Skill then sends the sensitive AIDA_API_KEY value to that destination in an Authorization header.

Authentication with the legitimate AIDA service is necessary for the declared functionality. However, allowing the credential destination to be any configured URL exceeds least privilege. A configuration modification could direct the request to a plaintext HTTP endpoint or an attacker-controlled server. Redirect behavior is also not restricted or validated by the Skill.

Attack Path

  1. An attacker, compromised deployment process, or configuration error changes AIDA_API_URL to an attacker-controlled endpoint.
  2. A user invokes any supported AIDA intent, such as aida.status.
  3. The Skill constructs a URL from the unvalidated environment value and the selected path.
  4. The request sends Authorization: Bearer <AIDA_API_KEY> to the configured server.
  5. The recipient captures the bearer credential and can reuse it until it expires or is revoked.

Impact Assessment

Successful exploitation discloses the complete AIDA bearer token. The attacker obtains whatever privileges are assigned to that token, potentially including access to live building status, diagnostics, optimization functions, or device controls. The exact scope d ...[truncated 87 chars]

Remediation
View remediation

Remediation Suggestions

  • Parse the configured endpoint with new URL() before issuing requests.
  • Require HTTPS and reject all non-HTTPS protocols.
  • Enforce an explicit allowlist of trusted AIDA hostnames and ports.
  • Construct request URLs using the URL API rather than string concatenation.
  • Disable redirects where possible, or validate every redirect destination before forwarding authorization headers.
  • Use a narrowly scoped token limited to the specific operations required by the Skill.
  • Apply token expiration, rotation, revocation, and audit logging.
  • Fail closed when the endpoint is missing, malformed, or outside the trusted origin.
  • Never include the bearer token in error messages or application logs.

T09 · Insecure Skill Coding Practices

Error
Location
skills/aida/index.js:9
Finding

Failed Building Operations Are Falsely Reported as Successful

Content
View full analysis

Vulnerability Details

File Location: skills/aida/index.js:9-19, 26-37
Vulnerability Type: Fail-open error handling and false success reporting
Risk Level: High

Vulnerable Code

js
case 'aida.status':
  return call('/status', 'Building operating normally.');

case 'aida.optimize':
  return call('/optimize', 'Optimization executed.');

case 'aida.control':
  return call('/control', 'Control command sent.');

case 'aida.diagnostics':
  return call('/diagnostics', 'Diagnostics completed.');

async function call(path, fallback) {
  try {
    const res = await fetch(API + path, {
      headers: {
        'Authorization': `Bearer ${KEY}`,
        'Content-Type': 'application/json'
      }
    });
    const data = await res.json();
    return { reply: data.message || fallback };
  } catch {
    return { reply: fallback };
  }
}

Technical Analysis

The implementation does not check res.ok or otherwise validate the HTTP status before treating the response as successful. Network failures, authentication failures that produce unparsable content, malformed JSON, and other exceptions are caught by an empty catch block that returns an affirmative fallback message.

A server response with valid JSON but no message field also causes the Skill to return the success fallback. Consequently, the Skill can report that controls, optimization, or diagnostics completed even when the remote operation failed or was rejected.

This is particularly unsafe for a building-control integration because user-facing responses may be used as confirmation that lighting, shades, or HVAC operations occurred.

Attack Path

  1. A user requests a building operation such as turning off lights or optimizing energy consumption.
  2. The API request fails because of an outage, invalid credential, network interception, malformed response, or server error.
  3. JSON parsing throws an exception, or the ...[truncated 919 chars]
Remediation
View remediation

Remediation Suggestions

  • Check res.ok before parsing or accepting a response as successful.
  • Treat non-2xx status codes as explicit failures.
  • Replace affirmative fallback messages with clear failure responses.
  • Distinguish network, authentication, authorization, timeout, parsing, and server errors.
  • Add a bounded request timeout using AbortController.
  • Require a validated success indicator from the AIDA API before confirming an operation.
  • Return structured results such as { success: false, reply: "Control could not be verified." }.
  • Log sanitized diagnostic information for operators without recording credentials or sensitive response content.
  • Add tests confirming that timeouts, HTTP errors, malformed JSON, and missing response fields never produce success messages.

T09 · Insecure Skill Coding Practices

Warning
Location
skills/aida/index.js:6
Finding

Mutating Operations Use GET Requests and Discard Command Parameters

Content
View full analysis

Vulnerability Details

File Location: skills/aida/index.js:6-31
Related API Contract: SKILL.md:27-31
Vulnerability Type: Unsafe HTTP semantics and incomplete input handling
Risk Level: Medium

Vulnerable Code

js
export default async function aidaSkill(ctx) {
  const { intent } = ctx;

  switch (intent) {
    case 'aida.status':
      return call('/status', 'Building operating normally.');

    case 'aida.optimize':
      return call('/optimize', 'Optimization executed.');

    case 'aida.control':
      return call('/control', 'Control command sent.');

    case 'aida.diagnostics':
      return call('/diagnostics', 'Diagnostics completed.');

    default:
      return { reply: 'AIDA skill is active.' };
  }
}

async function call(path, fallback) {
  try {
    const res = await fetch(API + path, {
      headers: {
        'Authorization': `Bearer ${KEY}`,
        'Content-Type': 'application/json'
      }
    });

The documented API contract states:

md
- GET /status
- POST /control
- POST /optimize
- GET /diagnostics

Technical Analysis

The fetch options do not specify a method, so all requests default to GET. This conflicts with the declared requirement that /control and /optimize use POST.

The handler also extracts only intent from ctx. It does not read, validate, or transmit the requested target, zone, device, control action, or optimization objective. For example, the documented request to turn off lights on a particular floor is reduced to a generic GET request to /control.

Using GET for a mutating operation violates safe HTTP semantics. GET requests may be cached, replayed, prefetched, or handled differently by intermediaries. Discarding command parameters can cause the server to reject the operation or apply an unintended default if the server supports such behavior.

Attack Path

  1. A user requests a sp ...[truncated 1071 chars]
Remediation
View remediation

Remediation Suggestions

  • Define a separate request method and schema for every supported intent.
  • Use explicit POST methods for /control and /optimize.
  • Serialize validated command parameters into a JSON request body.
  • Validate device identifiers, zones, actions, ranges, and optimization objectives against strict allowlists or schemas.
  • Reject missing, ambiguous, or unsupported command parameters.
  • Apply authorization checks appropriate to the requested device and operation.
  • Use GET only for read-only status and diagnostics operations when the server contract confirms they are non-mutating.
  • Add idempotency keys or replay protection for sensitive mutating operations where supported.
  • Confirm success only after receiving and validating a definitive API result.
  • Add integration tests that verify HTTP methods, request bodies, target selection, and failure behavior for every intent.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill exposes authenticated control and optimization operations that can change real-world building systems, but the description provides no user-facing warning or confirmation expectations for those actions. In a conversational interface, this increases the chance of unintended or socially engineered commands causing changes to lights, HVAC, or other devices without the user appreciating the operational consequences.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill issues authenticated requests to an external AIDA API for control and optimization actions, including '/control' and '/optimize', without any visible authorization, scoping, or validation of who invoked the intent. In a building/operations context, these actions can affect real-world systems, so exposing them through simple intent routing materially increases the risk of unauthorized or accidental operational changes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill maps user intents directly to control and optimization API calls and returns success-style fallback messages even when the request fails, with no warning, confirmation, or operator acknowledgment. This makes potentially sensitive building-control actions easy to trigger silently and can mislead users into believing an action succeeded, increasing the chance of unsafe or unauthorized changes.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

The dependency is specified with a caret range (^3.3.2), which permits automatic installation of newer compatible releases rather than a single audited version. This weakens supply-chain reproducibility and can unexpectedly introduce vulnerable or malicious code if an upstream release is compromised or if behavior changes across installs.

Content

Scanner excerpt · package.json (reported line 6)May include surrounding context.

json
"version": "1.1.0",
  "type": "module",
  "dependencies": {
    "node-fetch": "^3.3.2"
  }
}

Unverifiable Dependency: node-fetch has 3 known advisory(ies) (CVE-2022-0235 (node-fetch forwards secure headers to untrusted sites); CVE-2022-2596 (node-fetch Inefficient Regular Expression Complexity ); CVE-2020-15168 (The `size` option isn't honored after following a redirect in node-fetch)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
84% confidence
Finding

The manifest references node-fetch without pinning an exact version, while the package has multiple known advisories in some releases. Because the actual installed version cannot be verified from this manifest alone, the project may resolve to an affected version, creating avoidable exposure to known issues such as header forwarding or denial-of-service conditions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The code reads an API URL and API key from environment variables and uses them in outbound HTTP requests, but there is no user-visible warning, comment, or prompt indicating that external authenticated communication occurs. This is relevant because the skill sends requests off-box using privileged credentials.

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
skills/aida/index.js:3