T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:398
- Finding
- Reversed Grade Comparisons Cause Health Checks to Fail Open<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 398–438 **Vulnerability Type**: Incorrect security-state escalation logic **Risk Level**: High ### Vulnerable Code ```bash elif [ "$DISK_USAGE" -gt 90 ]; then [ "$GRADE" \< "D" ] || GRADE="D"; ISSUES+=("Disk usage at ${DISK_USAGE}%") elif [ "$DISK_USAGE" -gt 80 ]; then [ "$GRADE" \< "C" ] || GRADE="C"; ISSUES+=("Disk usage at ${DISK_USAGE}%") fi # Check memory file count (too many = potential issue) MEMORY_COUNT=$(find "$HOME/.openclaw/workspace/memory" -name "*.md" 2>/dev/null | wc -l | tr -d ' ') if [ "$MEMORY_COUNT" -gt 500 ]; then [ "$GRADE" \< "C" ] || GRADE="C" ISSUES+=("Memory file count high: $MEMORY_COUNT") elif [ "$MEMORY_COUNT" -gt 200 ]; then [ "$GRADE" \< "B" ] || GRADE="B" ISSUES+=("Memory file count elevated: $MEMORY_COUNT") fi # Check WAL for incomplete entries if [ -d "$HOME/.openclaw/workspace/logs/wal" ]; then INCOMPLETE=$(grep -l '"status":"pending"' "$HOME/.openclaw/workspace/logs/wal/"*.jsonl 2>/dev/null | wc -l | tr -d ' ') if [ "$INCOMPLETE" -gt 0 ]; then [ "$GRADE" \< "C" ] || GRADE="C" ISSUES+=("$INCOMPLETE incomplete WAL entries found") fi fi # --- API Connectivity --- # Check Anthropic API (lightweight) HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \ -H "x-api-key: ${ANTHROPIC_API_KEY:-missing}" \ -H "content-type: application/json" \ "https://api.anthropic.com/v1/messages" \ -d '{"model":"claude-haiku-4-5-20251001","max_tokens":1,"messages":[{"role":"user","content":"health"}]}' 2>/dev/null || echo "000") if [ "$HTTP_CODE" = "000" ]; then [ "$GRADE" \< "D" ] || GRADE="D" ISSUES+=("Cannot reach Anthropic API") elif [ "$HTTP_CODE" = "401" ]; then [ "$GRADE" \< "D" ] || GRADE="D" ISSUES+=("Anthropic API key is invalid") elif [ "$HTTP_CODE" != "200" ]; then [ "$GRADE" \< "C" ] || GRADE="C" ISSUES+=("Anthropic API returned HTTP $HTTP_CODE") fi ``` ### Technical Analysis The script initializes the health grad ...[truncated 3023 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Replace lexicographic grade comparisons with an explicit numeric severity model: ```bash declare -A SEVERITY=( [A]=0 [B]=1 [C]=2 [D]=3 [F]=4 ) escalate_grade() { local requested="$1" if (( SEVERITY[$requested] > SEVERITY[$GRADE] )); then GRADE="$requested" fi } ``` Use it consistently: ```bash if [ "$DISK_USAGE" -gt 95 ]; then escalate_grade F ISSUES+=("Disk usage at ${DISK_USAGE}%") elif [ "$DISK_USAGE" -gt 90 ]; then escalate_grade D ISSUES+=("Disk usage at ${DISK_USAGE}%") elif [ "$DISK_USAGE" -gt 80 ]; then escalate_grade C ISSUES+=("Disk usage at ${DISK_USAGE}%") fi ``` 2. Ensure severity is monotonic. Once the grade reaches a given severity, later checks must never reduce it. 3. Add automated tests covering every current/requested grade pair. Verify that the final grade is always the more severe of the two. 4. Add integration tests for each monitored failure: - disk usage over 80%, 90%, and 95%; - incomplete WAL records; - elevated memory counts; - API connection failures; - HTTP 401 responses; and - unexpected non-200 responses. 5. Validate the generated `system-health.json` before it is used by an integrity gate. If grade computation or JSON generation fails, default to a fail-closed grade such as `F`. 6. Avoid relying on alphabetic ordering for security states. Use explicit mappings or a `case`-based escalation function so the intended ordering is clear and portable across shell environments. ]]>
