Back to skill

Security audit

Cricket Live

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real cricket scores skill, but it needs review because its local cache and alert files are stored in unsafe shared temporary paths.

Install only if you are comfortable giving the skill a CricketData.org API key and running it on a trusted single-user machine. Avoid shared or multi-user hosts until cache/state storage is moved to a private per-user directory and match IDs are validated before use in filenames or URLs.

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
scripts/helpers.sh:5
Finding

Predictable shared temporary files permit symlink attacks and cache poisoning

Content
View full analysis
/dev/null || stat -f %m "$file" 2>/dev/null) )) if (( age < ttl )); then cat "$file" return 0 fi fi return 1 } cache_set() { local name="$1" local file="$CACHE_DIR/${name}.json" mkdir -p "$CACHE_DIR" cat > "$file" } ``` ```bash # scripts/cricket-alert.sh STATE_FILE="/tmp/cricket-alert-state.json" if [[ ! -f "$STATE_FILE" ]]; then echo '{"last_check":"","matches":{}}' > "$STATE_FILE" fi prev_state=$(cat "$STATE_FILE") # ... echo '{"last_check":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","matches":{}}' > "$STATE_FILE" # ... echo "$prev_state" | jq --arg id "$id" --argjson w "$total_wickets" --argjson r "$total_runs" --arg s "$status" \ '.matches[$id] = {"wickets": $w, "runs": $r, "status": $s}' > "$STATE_FILE.tmp" 2>/dev/null if [[ -f "$STATE_FILE.tmp" ]]; then mv "$STATE_FILE.tmp" "$STATE_FILE" prev_state=$(cat "$STATE_FILE") fi ``` ### Technical Analysis The Skill stores cache and alert state in fixed, predictable paths under the globally shared `/tmp` directory. It creates these paths without: - Ensuring that the directory and files are owned by the current user. - Applying restrictive permissions such as `0700` and `0600`. - Rejecting symbolic links. - Securely creating temporary files. - Atomically publishing cache updates. Shell redirection follows symbolic links. Consequently, an attacker with access to the same host can pre-create `/tmp/cricket-alert-state.json`, `/tmp/c ...[truncated 1621 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/match-details.sh:6
Finding

Unvalidated match identifiers control cache paths and API query parameters

Content
View full analysis
" echo "" echo "Find match IDs via: bash scripts/live-scores.sh" echo "Or search: bash scripts/search-match.sh \"India vs Australia\"" exit 1 fi response=$(api_call "match_scorecard" "scorecard-${MATCH_ID}" 300 "id=${MATCH_ID}") ``` ```bash # scripts/helpers.sh cache_get() { local name="$1" ttl="$2" local file="$CACHE_DIR/${name}.json" mkdir -p "$CACHE_DIR" if [[ -f "$file" ]]; then local age=$(( $(date +%s) - $(stat -c %Y "$file" 2>/dev/null || stat -f %m "$file" 2>/dev/null) )) if (( age < ttl )); then cat "$file" return 0 fi fi return 1 } cache_set() { local name="$1" local file="$CACHE_DIR/${name}.json" mkdir -p "$CACHE_DIR" cat > "$file" } api_call() { local endpoint="$1" cache_name="$2" ttl="$3" extra_params="${4:-}" # ... local url="${BASE_URL}/${endpoint}?apikey=${key}" if [[ -n "$extra_params" ]]; then url="${url}&${extra_params}" fi local response response=$(curl -s --max-time 10 "$url") } ``` ### Technical Analysis `MATCH_ID` is accepted directly from the command line and is used in two security-sensitive contexts without validation or encoding: 1. It becomes part of the cache filename through `"scorecard-${MATCH_ID}"`. 2. It becomes part of the request query string through `"id=${MATCH_ID}"`. A value containing path separators or `..` segments can make the generated cache path resolve outside the intended cache directory. The implementation appends `.json`, which limits target names but does not prevent traversal. If a matching fil ...[truncated 1562 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/helpers.sh:78
Finding

CricketData API key is exposed in curl process arguments

Content
View full analysis
&1) || { echo "$key"; return 1; } local url="${BASE_URL}/${endpoint}?apikey=${key}" if [[ -n "$extra_params" ]]; then url="${url}&${extra_params}" fi local response response=$(curl -s --max-time 10 "$url") ``` The documentation acknowledges the provider constraint: ```markdown - **API key in URL query parameter:** The CricketData.org API (`api.cricapi.com`) requires the API key to be passed as a URL query parameter (`?apikey=...`). This means the key may appear in shell history, process listings, server access logs, and any HTTP proxy/inspection logs. ``` ### Technical Analysis The API key is embedded in the complete URL and passed to `curl` as a command-line argument. During the request, the key can therefore appear in process-inspection interfaces and monitoring or diagnostic systems that record process arguments. Because the remote service requires query-string authentication, placing the credential in the request URL may be unavoidable. However, placing the complete credential-bearing URL directly in the process argument vector creates additional local exposure beyond normal transport to the declared API service. The code uses HTTPS and contacts the fixed, documented CricketData endpoint. No evidence indicates that the key is intentionally transmitted to an unrelated party. ### Attack Path 1. The victim configures `CRICKET_API_KEY` and invokes any script that performs an uncached API request. 2. `helpers.sh` constructs a URL containing the API key. 3. `curl` runs with the credential-bearing URL in its process arguments. 4. Another local user, a process-monitoring agent, or diagnostic logging software captures the command line while the request is active. 5. The observer reuses the ...[truncated 515 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
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (21)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

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

2. Set the Environment Variable

bash
export CRICKET_API_KEY="your-api-key-here"
# Add to your shell profile or ~/.openclaw/.env for persistence

3. Run Any Script

Memory Manipulation

High
Category
Memory Poisoning
Confidence
80% confidence
Finding

Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Content

Scanner excerpt · scripts/cricket-alert.sh (reported line 32)May include surrounding context.

sh
echo "🏏 *CRICKET ALERT*"
        echo ""
        echo "All tracked matches have ended."
        # Clear state
        echo '{"last_check":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","matches":{}}' > "$STATE_FILE"
    fi
    exit 0

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

sh
CACHE_DIR="${CRICKET_CACHE_DIR:-/tmp/cricket-cache}"
BASE_URL="https://api.cricapi.com/v1"

# Get API key from env or config
get_api_key() {
    if [[ -n "${CRICKET_API_KEY:-}" ]]; then
        echo "$CRICKET_API_KEY"

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file states that all times are displayed in IST by default, which imposes a specific locale preference on all users. The document does not mention any user choice, opt-in, or region-specific justification for this behavior.

Content

No source excerpt is available for this finding.

Unrestricted Tool Access

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill grants unrestricted tool access without appropriate constraints. An agent with unfettered tool access can perform arbitrary actions including file modification, network requests, and code execution.

Content

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

Add to your shell profile or ~/.openclaw/.env for persistence

text

### 3. Run Any Script
```bash
bash scripts/live-scores.sh              # What's happening right now?
bash scripts/upcoming-matches.sh         # What's coming up?

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The "Natural Language Mapping" includes generic phrases such as "What's the score?", "What's coming up?", and "Who won?" without narrowing them to cricket context. These are common conversational utterances and could cause unintended invocation because the file does not provide exclusion conditions or negative examples.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The IPL aliases include very broad single-word geographic triggers such as "Mumbai", "Chennai", "Delhi", "Punjab", "Hyderabad", "Gujarat", and "Lucknow". In systems that map free-form user input to teams, these aliases can cause incorrect entity resolution, leading the agent to select the wrong team when a user is referring to a city, state, or region rather than the cricket franchise.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · config/README.md (reported line 10)May include surrounding context.

md
SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
CACHE_DIR="${CRICKET_CACHE_DIR:-/tmp/cricket-cache}"
BASE_URL="https://api.cricapi.com/v1"

# Get API key from env or config
get_api_key() {

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · config/cricket.yaml (reported line 10)May include surrounding context.

yaml
SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
CACHE_DIR="${CRICKET_CACHE_DIR:-/tmp/cricket-cache}"
BASE_URL="https://api.cricapi.com/v1"

# Get API key from env or config
get_api_key() {

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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/helpers.sh (reported line 6)May include surrounding context.

sh
SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
CACHE_DIR="${CRICKET_CACHE_DIR:-/tmp/cricket-cache}"
BASE_URL="https://api.cricapi.com/v1"

# Get API key from env or config
get_api_key() {

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The api_call helper constructs requests to https://api.cricapi.com/v1 and invokes curl to retrieve remote data. Because no manifest is available, there is no stated purpose that justifies external network access, making this an undeclared capability relative to the provided intent context.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The helper explicitly converts UTC timestamps to India Standard Time using the Asia/Kolkata timezone and labels output as IST. This imposes a specific locale on all users without offering a choice or documenting that the skill is intentionally India-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script unconditionally formats match dates using to_ist, which imposes a specific locale/timezone on all users. This is a natural-language/presentation policy issue because it does not offer user opt-in or indicate that the skill is intentionally region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The output format section says times are converted to IST, indicating the locale constraint applies broadly across the skill. Because no alternative timezone or user preference mechanism is described in the markdown, this appears to violate the language/locale choice policy.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

This markdown file describes two ways to provide credentials, including an api_key field in cricket.yaml, but it does not warn users that putting secrets in a config file may expose them through source control, shared files, or backups. Because this is a markdown file and it documents credential handling, a brief warning about secure storage would be an expected user disclosure.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
74% confidence
Finding

The README sets the default timezone to Asia/Kolkata, which implies a locale-specific behavior in a general configuration document. There is no accompanying note that this is only an example, user-selectable, or intended for a region-specific deployment, so it can be read as a fixed locale choice.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script stores persistent state in a predictable path under /tmp, which is world-writable and commonly shared across users. That creates risks such as symlink attacks, state tampering, or information disclosure if another local user can pre-create or modify the file, even though the stored data here appears low sensitivity.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The script fetches live match data via api_call, which is a network operation, but the file provides no user-facing disclosure about contacting an external service. Although expected for an alerting script, the criteria require some form of warning, logging, or documentation when code transmits or retrieves data over the network.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

With no manifest available, the skill's stated purpose is unknown, so accessing credential material from both environment variables and a config file is an undeclared capability. This may be reasonable for a score-fetching skill, but absent any declared purpose or permissions, the credential access is not justified by provided intent context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

This code persists network responses to disk via the cache helper, which is a file write affecting local user/system state. While the helper comments describe caching internally, there is no user-facing prompt, warning, or disclosure at the point where fetched data is saved.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

Line L033 unconditionally converts the match date using to_ist, which imposes a specific locale/timezone presentation. This is a natural-language policy concern because users are not given a choice of timezone and no region-specific justification appears in the file.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.