Back to skill

Security audit

BaiduOCR-LocalFallback

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly aligned with Baidu OCR use, but its install and credential handling create review-worthy security risk.

Review before installing. Prefer the included local installer over the one-click remote command, use a virtual environment with pinned dependencies, avoid the plaintext config file when possible, and do not process sensitive documents unless Baidu Cloud privacy and retention terms are acceptable for your use case.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
Findings (3)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:24
Finding
Unverified Remote Installer Is Downloaded and Executed Directly<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:21-25` **Vulnerability Type**: Remote payload retrieval and execution **Risk Level**: Critical ### Vulnerable Code ```bash ### One-click install ```bash bash <(curl -s https://raw.githubusercontent.com/xx235300/BaiduOCR-LocalFallback/main/install.sh) ``` ``` ### Technical Analysis The documented installation command downloads a shell script from a mutable `main` branch in a personal GitHub repository and immediately executes it with Bash. It does not pin the payload to an immutable commit, verify a cryptographic checksum or signature, preserve the downloaded file for inspection, or cause `curl` to fail explicitly on HTTP errors. The remotely retrieved script is the effective executable payload. It can change independently after this packaged skill has been reviewed, meaning the local `install.sh` is not necessarily the code users will execute. Compromise of the repository, GitHub account, or upstream content can therefore turn this installation command into an arbitrary-code execution channel. This behavior exceeds the minimum privilege necessary to install the supplied skill. A safer installation process can execute the reviewed local installer or retrieve a versioned artifact and verify it before execution. ### Attack Path 1. A user follows the one-click installation instructions in `SKILL.md`. 2. Bash starts process substitution and `curl` retrieves the current contents of the upstream `main/install.sh`. 3. An attacker who has compromised the repository or maintainer account modifies that remote installer. 4. The modified payload is supplied directly to Bash without integrity or authenticity verification. 5. The attacker-controlled commands execute with all privileges of the user running the installation command. ### Impact Assessment Successful exploitation permits arbitrary command execution under the invoking user's account. The payload could read user-accessible files and credent ...[truncated 459 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the pipe-to-shell installation command and direct users to the installer included in the reviewed package: ```bash bash ./install.sh ``` 2. If remote retrieval is unavoidable, publish immutable, versioned release artifacts rather than using the mutable `main` branch. 3. Pin downloads to a reviewed commit or release and publish a SHA-256 or stronger digest. 4. Download the artifact to a local file, verify its checksum or cryptographic signature, allow inspection, and only then execute it. 5. Use strict download options such as `curl --fail --show-error --location` so HTTP failures are not silently passed to Bash. 6. Document that the installer must not be run as root and ensure it refuses unnecessary elevated execution. 7. Ensure the reviewed package includes all required OCR implementation files so installation does not depend on obtaining unreviewed executable content elsewhere. ]]>

T08 · Insecure Dependencies

Error
Location
install.sh:43
Finding
Unpinned Python Dependencies Are Installed from Mutable Package Sources<![CDATA[ ## Vulnerability Details **File Location**: `install.sh:43-68`; related metadata at `package.json:18-25` **Vulnerability Type**: Insecure dependency and supply-chain handling **Risk Level**: High ### Vulnerable Code ```bash # Install dependencies install_dependencies() { echo "" echo "Installing Python dependencies..." if pip3 show requests &> /dev/null; then echo " requests already installed, skipping" else pip3 install requests fi if pip3 show easyocr &> /dev/null; then echo " easyocr already installed, skipping" else pip3 install easyocr fi if pip3 show Pillow &> /dev/null; then echo " Pillow already installed, skipping" else pip3 install Pillow fi echo "✓ Dependencies installed" } ``` The package metadata also uses open-ended minimum constraints: ```json "python": { "version": ">=3.8", "dependencies": [ "requests>=2.28.0", "easyocr>=1.7.0", "Pillow>=9.0.0" ] } ``` ### Technical Analysis The installer invokes `pip3 install` using package names without exact versions, hashes, a lock file, an enforced package index, or an isolated virtual environment. Although the package names shown are established projects rather than evident typosquats, the installation process trusts whichever package index and configuration are active on the user's system. The metadata's minimum-version constraints do not protect the installation because the shell installer does not use them. Even if they were used, constraints such as `>=1.7.0` permit future and unreviewed releases. Transitive dependencies are also unresolved and unpinned. Python packages or their dependencies may execute build backend or installation logic during installation, and subsequently execute code when imported. This creates a supply-chain execution path if a package source, future release, dependency, or configured mirror is compromised. ### Attack Path 1 ...[truncated 1136 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create and use an isolated virtual environment instead of installing into the active system Python environment. 2. Maintain a reviewed lock file that pins every direct and transitive dependency to an exact version. 3. Require hashes for all distributions, for example through a generated requirements file used with: ```bash python3 -m pip install --require-hashes -r requirements.lock ``` 4. Enforce the intended HTTPS package index and do not silently trust arbitrary user-configured mirrors for security-sensitive installations. 5. Review dependency provenance, release signatures where available, transitive dependency changes, and vulnerability advisories. 6. Use `python3 -m pip` so installation targets the same interpreter that the skill will use. 7. Keep dependency updates deliberate and subject each lock-file update to testing and security review. 8. Avoid running dependency installation with root or administrator privileges. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
install.sh:103
Finding
Baidu Secret Key Is Stored in Plaintext and Exposed in Process Arguments<![CDATA[ ## Vulnerability Details **File Location**: `install.sh:86-116` and `install.sh:128-146` **Vulnerability Type**: Insecure credential handling **Risk Level**: Medium ### Vulnerable Code The installer reads and stores the credentials as follows: ```bash read -p "Enter API Key (press Enter to skip, configure later manually): " API_KEY if [ -z "$API_KEY" ]; then echo "Skipped. Run the following to configure later:" echo " python3 scripts/ocr.py --configure" return fi read -p "Enter Secret Key: " SECRET_KEY if [ -z "$SECRET_KEY" ]; then echo "Secret Key cannot be empty" exit 1 fi CONFIG_FILE="$HOME/.openclaw/skills/BaiduOCR-LocalFallback/config.json" cat > "$CONFIG_FILE" << EOF { "api_key": "$API_KEY", "secret_key": "$SECRET_KEY" } EOF # Recommend restricting file permissions chmod 600 "$CONFIG_FILE" 2>/dev/null || true ``` The connection test extracts the plaintext values and places them in the command-line URL: ```bash if command -v curl &> /dev/null; then API_KEY=$(grep -o '"api_key"[[:space:]]*:[[:space:]]*"[^"]*"' "$CONFIG_FILE" | cut -d'"' -f4) SECRET_KEY=$(grep -o '"secret_key"[[:space:]]*:[[:space:]]*"[^"]*"' "$CONFIG_FILE" | cut -d'"' -f4) if [ -n "$API_KEY" ] && [ -n "$SECRET_KEY" ]; then echo "Fetching access_token..." RESPONSE=$(curl -s -X POST "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=${API_KEY}&client_secret=${SECRET_KEY}") if echo "$RESPONSE" | grep -q "access_token"; then echo "✓ API connection successful!" else echo "✗ API connection failed. Please verify your API keys." echo " Response: $RESPONSE" fi fi fi ``` ### Technical Analysis The network request is directed to Baidu's declared OAuth service and is consistent with the advertised connection test. The status message `Fetching access_token...` does not itself transmit information, and the reviewed code d ...[truncated 2484 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Read the secret without terminal echo: ```bash read -r -s -p "Enter Secret Key: " SECRET_KEY echo ``` 2. Do not include credentials in command-line URLs. Send them in the HTTPS request body using a protected temporary input, standard input, or another mechanism that does not expose the values through process arguments. 3. Avoid writing long-lived secrets to plaintext configuration where possible. Prefer an operating-system credential manager, secret service, or environment supplied by a dedicated secret-management facility. 4. If file storage is required: - Set a restrictive umask before creation, such as `umask 077`. - Create the file atomically with mode `600`. - Treat permission-setting failures as fatal rather than ignoring them. - Verify ownership and reject symbolic links. 5. Generate JSON with a proper JSON serializer rather than interpolating unescaped shell variables. 6. Avoid logging full OAuth error responses unless they are verified not to contain sensitive values. 7. Clear credential variables after the test where practical: ```bash unset API_KEY SECRET_KEY RESPONSE ``` 8. Recommend Baidu-side least privilege, quota limits, credential rotation, and immediate revocation if exposure is suspected. ]]>
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
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (8)

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The feature description emphasizes convenience but does not clearly disclose that cloud OCR requests may upload sensitive images and extracted text to Baidu services. Because this skill handles ID cards, passports, bank cards, invoices, and similar high-sensitivity documents, the missing privacy/transmission warning materially increases the risk of unintentional data disclosure and noncompliant use.

Session Persistence

Medium
Category
Rogue Agent
Content
### Method 3: Config file
```bash
mkdir -p ~/.openclaw/skills/BaiduOCR-LocalFallback
cat > ~/.openclaw/skills/BaiduOCR-LocalFallback/config.json << 'EOF'
{
  "api_key": "<your_api_key>",
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.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
"secret_key": "<your_secret_key>"
}
EOF
chmod 600 ~/.openclaw/skills/BaiduOCR-LocalFallback/config.json
```

## Response Format
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The script reads the secret key with a normal `read -p`, which echoes the credential to the terminal and may expose it to shoulder-surfing, screen recording, terminal logging, or shared session capture. In an installer that explicitly collects API credentials, this is a real confidentiality issue even though it is likely an implementation oversight rather than malicious behavior.

Session Persistence

Medium
Category
Rogue Agent
Content
"Detect OS (macOS / Linux / Windows)",
        "Check Python 3.8+",
        "Install Python dependencies (requests, easyocr, Pillow)",
        "Create config directory ~/.openclaw/skills/BaiduOCR-LocalFallback/",
        "Interactive API key configuration (or skip and configure later)",
        "Test Baidu OCR connection"
      ],
Confidence
90% confidence
Finding
The install flow and security notes indicate persistent storage of Baidu API credentials under ~/.openclaw/skills/BaiduOCR-LocalFallback/config.json. Persisting secrets in a user-accessible plaintext file increases the chance of credential theft via local compromise, backups, misconfigured permissions, or other processes reading the file. The skill context makes this more sensitive because the credentials enable outbound use of a third-party OCR service and the skill handles potentially sensitive document images.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
"security": {
      "warnings": [
        "Requires Baidu API Key + Secret Key — do not share credentials",
        "Stores credentials in plaintext at ~/.openclaw/skills/BaiduOCR-LocalFallback/config.json (chmod 600 recommended)",
        "Makes outbound network calls to Baidu OCR API and downloads EasyOCR models (~100MB)",
        "Do not send highly sensitive images to remote OCR without understanding Baidu's data retention policy",
        "For higher security, use environment variables instead of config file"
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
"security": {
      "warnings": [
        "Requires Baidu API Key + Secret Key — do not share credentials",
        "Stores credentials in plaintext at ~/.openclaw/skills/BaiduOCR-LocalFallback/config.json (chmod 600 recommended)",
        "Makes outbound network calls to Baidu OCR API and downloads EasyOCR models (~100MB)",
        "Do not send highly sensitive images to remote OCR without understanding Baidu's data retention policy",
        "For higher security, use environment variables instead of config file"
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Context-Inappropriate Capability

Low
Confidence
90% confidence
Finding
The documentation tells users to hand troubleshooting over to an AI using an external cloud document link, which expands the skill's trust boundary well beyond OCR functionality. This can lead users to disclose configuration details, logs, credentials, or document contents to an unrelated third-party AI service, creating avoidable data exposure and potential prompt-injection risk from externally hosted content.

Static analysis

No suspicious patterns detected.