Back to skill

Security audit

Openclaw Intune Skill

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real Intune/Graph admin skill, but it can perform high-impact tenant and device changes and one claimed safety gate is weaker than documented.

Review this before installing in any production tenant. Use INTUNE_READ_ONLY=true and read-only Graph permissions unless you specifically need writes. If enabling writes, grant the Azure app only the minimum permissions needed and be aware that destructive Tier 3 actions rely partly on the agent following instructions because the wrapper does not validate the typed confirmation name against Microsoft Graph.

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

Warning
Location
scripts/graph.sh:34
Finding

Tier-3 Exact-Name Confirmation Is Not Validated

Content
View full analysis

Vulnerability Details

File Location: scripts/graph.sh:34-42, 123-126
Vulnerability Type: Confirmation control bypass
Risk Level: Medium

Vulnerable Code

bash
--confirm-name)
  [[ $# -ge 2 && -n "$2" ]] || {
    echo "ERROR: --confirm-name requires the exact object name." >&2
    exit 2
  }
  CONFIRM_NAME="$2"
  shift 2 ;;
bash
if (( TIER == 3 )) && [[ -z "$CONFIRM_NAME" ]]; then
  echo "ERROR: Tier 3 action refused. Re-run with --confirm-name and the exact user-confirmed object name." >&2
  exit 7
fi

Technical Analysis

The wrapper claims to enforce exact-name confirmation for Tier-3 operations, including device wipe, device retirement, Activation Lock bypass, managed-device deletion, Autopilot identity deletion, and Conditional Access policy deletion.

However, --confirm-name accepts any non-empty string. The later authorization check only verifies that CONFIRM_NAME is not empty; it does not retrieve the target object's canonical name or serial number and does not compare that identifier with the supplied value.

Consequently, a value such as --confirm-name x satisfies the wrapper's Tier-3 check. The confirmation is also not cryptographically or logically bound to the HTTP method, endpoint, or target object ID.

Attack Path

  1. An attacker, compromised agent, or incorrectly instructed agent selects an allowed Tier-3 Graph endpoint.

  2. It invokes scripts/graph.sh with the destructive method and target object ID.

  3. It supplies any arbitrary non-empty confirmation value, for example:

    bash
    scripts/graph.sh --confirm-name "x" POST \
      "/deviceManagement/managedDevices/{id}/wipe"
    
  4. The non-empty check succeeds even though "x" is not the target device's name.

  5. If the configured Microsoft Graph application has the required permission, the wrapper sends the destructive request.

Impact Assessment

Successful exploitation can bypass the Skill's principal safety control for destructive a ...[truncated 734 chars]

Remediation
View remediation

Remediation Suggestions

  1. Resolve the target object with a permitted GET request before executing a Tier-3 operation.
  2. Extract its canonical confirmation identifier:
    • Device name for wipe, retire, managed-device deletion, and Activation Lock bypass.
    • Serial number for Autopilot identity deletion.
    • Display name for Conditional Access policy deletion.
  3. Compare the supplied confirmation with that canonical identifier using an exact, case-sensitive comparison unless a clearly documented normalization rule is required.
  4. Refuse execution when the object cannot be retrieved, the identifier is absent, or the supplied value differs.
  5. Bind confirmation to the exact action and target. A stronger design would issue a short-lived confirmation artifact derived from:
    • HTTP method,
    • normalized endpoint,
    • target object ID,
    • canonical object name,
    • expiration time.
  6. Avoid relying solely on an agent-provided assertion that the user confirmed the name.
  7. Add automated tests proving that empty, incorrect, stale, and unrelated names are rejected for every Tier-3 endpoint.
  8. Continue enforcing least-privilege Microsoft Graph permissions and use INTUNE_READ_ONLY=true for reporting-only deployments.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (15)

Credential Access

High
Category
Privilege Escalation
Confidence
83% confidence
Finding

The script intentionally obtains and caches a Microsoft Graph app-only access token on disk. Even though it avoids printing the secret and sets restrictive permissions, the cached bearer token can be reused by any process or user that can read the file, and bearer tokens grant direct API access until expiry. In an Intune/Entra management context, compromise of this token could enable broad device-management actions such as reading inventory or issuing remote actions depending on app permissions.

Content

Scanner excerpt · scripts/get_token.sh (reported line 2)May include surrounding context.

sh
#!/usr/bin/env bash
# get_token.sh — obtain (and cache) a Microsoft Graph app-only access token.
#
# Usage:
#   scripts/get_token.sh            # ensure a valid token is cached; print cache path

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 · scripts/graph.sh (reported line 9)May include surrounding context.

sh
#   scripts/graph.sh --confirm POST "/deviceManagement/managedDevices/{id}/syncDevice"
#   scripts/graph.sh --confirm POST "/deviceManagement/deviceCompliancePolicies" '{"displayName":"..."}'
#   scripts/graph.sh --confirm PATCH "/identity/conditionalAccess/policies/{id}" '{"state":"disabled"}'
#   scripts/graph.sh --confirm-name "DEVICE-NAME" DELETE "/deviceManagement/managedDevices/{id}"
#
# Behaviour:
#   * Paths default to v1.0; prefix with /beta/ for the beta API.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/graph.sh (reported line 146)May include surrounding context.

sh
TOKEN_FILE="$("$SCRIPT_DIR/get_token.sh")"
TOKEN="$(jq -r '.access_token // empty' "$TOKEN_FILE")"
if [[ -z "$TOKEN" ]]; then
  echo "ERROR: token cache did not contain an access token." >&2
  exit 3
fi

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/graph.sh (reported line 187)May include surrounding context.

sh
TOKEN_FILE="$("$SCRIPT_DIR/get_token.sh")"
TOKEN="$(jq -r '.access_token // empty' "$TOKEN_FILE")"
if [[ -z "$TOKEN" ]]; then
  echo "ERROR: token cache did not contain an access token." >&2
  exit 3
fi

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 84)May include surrounding context.

📦 Installation

bash
mkdir -p ~/.openclaw/workspace/skills/intune-graph
cp -r SKILL.md scripts references examples ~/.openclaw/workspace/skills/intune-graph/
chmod +x ~/.openclaw/workspace/skills/intune-graph/scripts/*.sh

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares shell execution capability and documents executable scripts, but it does not define an explicit tool scope such as allowed-tools or permissions. In a high-impact admin skill that can trigger Intune and Entra operations, missing tool scoping increases the risk of unintended command execution paths, weakens least-privilege boundaries, and makes policy enforcement depend on informal documentation rather than machine-enforced constraints.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

md
| Tier | Operations | Rule |
|---|---|---|
| 0 | All GET / read | Execute without confirmation |
| 1 | `syncDevice`, `rebootNow`, `remoteLock`, `locateDevice`, send test notification | One short confirmation ("Soll ich X syncen?") |
| 2 | All other POST/PATCH/PUT/DELETE: create/update/assign/delete policies, apps, groups, filters, categories, `resetPasscode`, pause/resume update rings | Show a summary of exactly what will change, then wait for explicit confirmation |
| 3 | `wipe`, `retire`, DELETE device, DELETE Autopilot identity, `bypassActivationLock`, DELETE Conditional Access policy | Explain consequences, then require the user to **type back the exact device/policy name** before executing |

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

All user and agent examples are written exclusively in German, including operational confirmations and safety prompts, with no indication that language selection is optional or that the skill is intentionally limited to German-speaking users. This can violate the language/locale policy because it implicitly constrains interaction to a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The file expands the skill from device-management operations into broader Entra ID administrative capabilities such as listing users, enumerating groups, and changing group membership. In an agent skill, this materially increases the reachable privilege surface and can enable identity, access, and policy changes that are only indirectly related to the stated Intune/device-management scope, especially because group changes can cascade into Conditional Access, app, and policy assignment changes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The reference includes write-side administrative actions that can create tenant artifacts and send messages, but it does not provide prominent user-facing warnings or confirmation requirements comparable to the stronger warning used for group membership changes. Creating Terms & Conditions, creating notification templates, or sending test notifications can alter compliance/legal workflows or generate confusing outbound communications, making accidental or prompt-induced misuse more likely.

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 · scripts/get_token.sh (reported line 58)May include surrounding context.

sh
# ---- cache ------------------------------------------------------------------
CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/intune-skill"
mkdir -p "$CACHE_DIR"
chmod 700 "$CACHE_DIR"
CACHE_FILE="$CACHE_DIR/token_${CACHE_KEY}.json"

now="$(date +%s)"

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 · scripts/get_token.sh (reported line 66)May include surrounding context.

sh
exp="$(jq -r '.expires_at // 0' "$CACHE_FILE" 2>/dev/null || echo 0)"
  # refresh 5 min before actual expiry
  if [[ "$exp" =~ ^[0-9]+$ ]] && (( now < exp - 300 )); then
    chmod 600 "$CACHE_FILE"
    printf '%s\n' "$CACHE_FILE"
    exit 0
  fi

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 · scripts/get_token.sh (reported line 96)May include surrounding context.

sh
exp="$(jq -r '.expires_at // 0' "$CACHE_FILE" 2>/dev/null || echo 0)"
  # refresh 5 min before actual expiry
  if [[ "$exp" =~ ^[0-9]+$ ]] && (( now < exp - 300 )); then
    chmod 600 "$CACHE_FILE"
    printf '%s\n' "$CACHE_FILE"
    exit 0
  fi

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

Line L25 instructs the skill to compute date ranges from phrases like "letzte Woche," which is a German-only example embedded in the guidance. This can indicate a language-specific behavior without explicitly offering the user a language or locale choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The example confirmation prompt is written only in German: "Soll ich kurz APNS/VPP-Zertifikate prüfen?". This imposes a specific language in the skill text without indicating user choice or that the skill is intentionally German-only.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.