Back to skill

Security audit

Digital Clawatar

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a legitimate UNITH avatar-management skill, but it needs Review because credential-bearing API calls can be redirected by an undocumented environment override and token handling is too broad for the sensitivity involved.

Install only if you are comfortable giving the skill authority over your UNITH account and uploaded knowledge documents. Before use, unset or lock down API_BASE, consider disabling UNITH_TOKEN_CACHE or moving it to a private user-owned directory, avoid putting secrets in logged payloads or command-line fields, and require an explicit user confirmation that names the exact digital human before any delete operation.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/_utils.sh:5
Finding

Environment-Controlled API Base Can Redirect Credentials, Tokens, and Documents

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/auth.sh:45
Finding

Predictable Shared Token Cache Allows Cache Poisoning and Unsafe File Replacement

Content
View full analysis
/dev/null || echo "") CACHED_TOKEN=$(cut -f2 "$TOKEN_CACHE" 2>/dev/null || echo "") CACHED_TIME=$(cut -f3 "$TOKEN_CACHE" 2>/dev/null || echo "0") NOW=$(date +%s) AGE=$((NOW - CACHED_TIME)) if [ "$CACHED_EMAIL" = "$UNITH_EMAIL" ] && [ -n "$CACHED_TOKEN" ] && [ "$AGE" -lt "$CACHE_MAX_AGE" ]; then export UNITH_TOKEN="$CACHED_TOKEN" REMAINING_DAYS=$(( (CACHE_MAX_AGE - AGE) / 86400 + 1 )) log_ok "Reusing cached token (valid ~${REMAINING_DAYS} more days). To force refresh: rm $TOKEN_CACHE" return 0 2>/dev/null || exit 0 fi fi ``` ```bash # Write to cache if [ -n "$TOKEN_CACHE" ]; then printf '%s\t%s\t%s\n' "$UNITH_EMAIL" "$TOKEN" "$(date +%s)" > "$TOKEN_CACHE" chmod 600 "$TOKEN_CACHE" fi ``` ### Technical Analysis The default token cache is a fixed, predictable path in the globally shared `/tmp` directory. Before trusting the cached token, the script does not verify that the path is a regular file, that it is owned by the current user, that its permissions are sufficiently restrictive, or that it is not a symbolic link. When writing, shell redirection opens or truncates the destination before `chmod 600` runs. Consequently, applying restrictive permissions afterward does not make path resolution or file creation safe. The write is also not atomic. The cached bearer token remains usable for up to six days and represents remote account authority, making integrity and confide ...[truncated 1476 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/update-head.sh:98
Finding

Update Script Prints Credential-Bearing Payloads to Logs

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
references/embedding.md:38
Finding

Embedding Guidance Executes an Unpinned Mutable Third-Party Script

Content
View full analysis
``` ```jsx useEffect(() => { const script = document.createElement('script'); script.src = 'https://cdn.unith.ai/widget/latest/unith-widget.js'; script.onload = () => { window.UnithWidget.init({ ``` ### Technical Analysis The recommended integration loads a JavaScript resource from a mutable `latest` path. No fixed version or Subresource Integrity hash is supplied. Every website following this guidance therefore executes whatever code the CDN serves at request time, even if that code differs from what was reviewed when the integration was deployed. Remote JavaScript executes with the privileges of the embedding page's origin. An upstream compromise, CDN compromise, DNS or account takeover, or malicious future release could therefore affect all consumers automatically. This is dependency guidance rather than malicious code shipped in the Skill itself. No evidence was found that the current remote widget is malicious. ### Attack Path 1. A website adopts the documented widget integration. 2. The remote `latest` asset is modified through an upstream release or supply-chain compromise. 3. A visitor opens the integrating website. 4. The browser downloads the modified script without verifying a pinned version or integrity hash. 5. The modified code executes in the page context and accesses data and browser APIs available to that script. ### Impact Assessment Compromised widget code can manipulate page content, monitor avatar conversations, make authenticated same-origin requests where browser controls permit them, read non-HttpOnly browser storage, and exfiltrate data accessible to JavaScript. The exact scope depends on the integrating site's ...[truncated 73 chars]
Remediation
View remediation
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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (15)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% 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 · references/api-payloads.md (reported line 226)May include surrounding context.

md
---

## Delete a Digital Human — `DELETE /head/<headId>`

Permanently removes a digital human.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% 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 · references/api-payloads.md (reported line 231)May include surrounding context.

Permanently removes a digital human.

text
DELETE /head/<headId>
Authorization: Bearer <token>

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill instructs the agent to invoke multiple shell scripts and use tools like curl and jq, but it does not declare any explicit tool scope such as permissions or allowed-tools. That creates an authorization gap where an agent runtime may permit broader shell execution than intended, increasing the chance of command misuse, unintended external network access, or destructive operations like deletion through available scripts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The document-upload instructions tell users to upload local files to the service via script or multipart API, but do not warn that uploaded documents may contain sensitive or regulated data. In an agent setting, this can lead to inadvertent exfiltration of private files to a third-party platform because the docs normalize file transmission without any privacy or data-handling caveats.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The documentation exposes a destructive delete endpoint and explicitly states it 'Permanently removes' a digital human, but provides no guidance about confirmation prompts, irreversible effects, or safeguards before invoking it. In an agent skill context, this omission increases the chance an LLM-driven workflow could delete resources from ambiguous or malicious user prompts without adequate human confirmation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The embedding guidance explicitly requests camera and microphone permissions but does not instruct integrators to provide a user-facing privacy notice, consent flow, or justification for why those permissions are needed. In the context of a conversational avatar product, this can lead downstream adopters to deploy a widget that surprises users with access requests for sensitive sensors, increasing privacy, compliance, and trust risks.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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 · scripts/auth.sh (reported line 68)May include surrounding context.

sh
log_info "Authenticating with UNITH API as $UNITH_EMAIL..."

unith_curl -X POST "$API_BASE/auth/token" \
  -H 'Content-Type: application/json' \
  -H 'accept: application/json' \
  -d "$(jq -n --arg e "$UNITH_EMAIL" --arg k "$UNITH_SECRET_KEY" '{email:$e, secretkey:$k}')"

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/auth.sh (reported line 102)May include surrounding context.

sh
# Write to cache
if [ -n "$TOKEN_CACHE" ]; then
  printf '%s\t%s\t%s\n' "$UNITH_EMAIL" "$TOKEN" "$(date +%s)" > "$TOKEN_CACHE"
  chmod 600 "$TOKEN_CACHE"
fi

log_ok "Authenticated successfully. Token stored in UNITH_TOKEN (valid 7 days)."

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script reads an arbitrary JSON payload and sends it directly to the UNITH API, and for voiceflow mode it explicitly requires a voiceflowApiKey inside that payload. This creates a real risk of transmitting third-party credentials or other sensitive fields without any explicit warning, redaction, or safer secret-handling path, which can lead to accidental disclosure to the remote service, shell history, or logs if users are not careful.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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 · scripts/create-head.sh (reported line 136)May include surrounding context.

sh
PAYLOAD=$(cat "$PAYLOAD_FILE")

if ! unith_curl -X POST "$API_BASE/head/create" \
  -H "Authorization: Bearer $UNITH_TOKEN" \
  -H 'Content-Type: application/json' \
  -H 'accept: application/json' \

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% 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 · scripts/delete-head.sh (reported line 9)May include surrounding context.

sh
#
# Usage:
#   bash scripts/delete-head.sh <headId>
#   bash scripts/delete-head.sh <headId> --confirm    # skip confirmation prompt

set -euo pipefail

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% 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 · scripts/delete-head.sh (reported line 28)May include surrounding context.

sh
echo "Usage: $0 <headId> [--confirm]"
  echo ""
  echo "  headId      - The digital human ID (from list-resources.sh heads)"
  echo "  --confirm   - Skip confirmation prompt"
  echo ""
  echo "WARNING: This permanently deletes the digital human and cannot be undone."
  exit 1

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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 · scripts/update-head.sh (reported line 102)May include surrounding context.

sh
log_info "Payload:"
echo "$PAYLOAD" | jq .

if ! unith_curl -X PUT "$API_BASE/head/update" \
  -H "Authorization: Bearer $UNITH_TOKEN" \
  -H 'Content-Type: application/json' \
  -H 'accept: application/json' \

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The React example sets autoStart to true without warning that the avatar may begin speaking or initiating conversation automatically. This can cause unexpected audio playback, accessibility issues, and poor user experience, especially when embedded in consumer-facing pages or environments where autoplay is disruptive.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The usage example sets both languageSpeechRecognition and language to en-US, which can implicitly steer users toward a fixed locale. There is no accompanying note that these are merely examples or that other locales are supported, so the natural-language guidance may conflict with a language-choice policy.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.