Back to skill

Security audit

Doc Ocr Skills

Security checks for vulnerabilities and agentic risk

Overview

This OCR skill appears purpose-aligned, but its installation path asks users to execute mutable remote code and an unauthenticated native binary that is not included for review.

Review this skill carefully before installing. Prefer building from reviewed source or using a release with published checksums/signatures, avoid the curl | bash command, do not run the installer with elevated privileges, and use local OCR engines for sensitive documents unless you are comfortable sending the selected files to Gemini. If you use Gemini, protect and rotate the API key because the documented config stores it in plaintext.

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 (4)

T03 · Remote Payload Retrieval and Execution

Error
Location
README.md:28
Finding
Remote installation script is streamed directly into Bash<![CDATA[ ## Vulnerability Details **File Location**: `README.md:28-32`; duplicated in `README_CN.md:28-32` **Vulnerability Type**: Remote payload retrieval and immediate execution **Risk Level**: High ### Complete Code Snippet ```markdown Use our convenient install script to download the latest pre-compiled binary for your system: ```bash curl -sSL https://raw.githubusercontent.com/scottkiss/doc-ocr-skills/main/scripts/install.sh | bash ``` ``` The Chinese README contains the same command: ```bash curl -sSL https://raw.githubusercontent.com/scottkiss/doc-ocr-skills/main/scripts/install.sh | bash ``` ### Technical Analysis The documented command retrieves a shell script from the mutable `main` branch of a personal GitHub repository and passes its contents directly to Bash. Users cannot inspect or authenticate the retrieved content before it executes. HTTPS protects the connection in transit but does not establish that the repository account, branch, or fetched script remains trustworthy. The command does not pin a commit, verify a cryptographic digest, validate a signature, or otherwise confirm that the downloaded script matches the version reviewed with this Skill. The bundled `scripts/install.sh` currently behaves as a binary downloader, but the documented command does not guarantee that the bundled version is the one that will execute. The effective payload can change after the Skill package has been reviewed. ### Attack Path 1. An attacker compromises the repository owner account, gains write access, or otherwise modifies `scripts/install.sh` on the remote `main` branch. 2. A user follows the installation instructions in either README. 3. `curl` downloads the modified script. 4. The shell begins executing the downloaded data immediately through the pipe. 5. The attacker-controlled script runs with all privileges of the invoking user. 6. It can access user-readable documents and credentials, modify files, download additional payloads, or establish ...[truncated 531 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the `curl | bash` installation method from both README files. 2. Instruct users to download a versioned installer to disk before execution: ```bash curl --fail --location --output install.sh \ https://raw.githubusercontent.com/scottkiss/doc-ocr-skills/<immutable-commit>/scripts/install.sh ``` 3. Publish an expected SHA-256 digest through a separately authenticated release channel and require verification before execution: ```bash echo "<expected-sha256> install.sh" | sha256sum --check - ``` 4. Cryptographically sign release scripts and document signature verification using a pinned maintainer key or Sigstore. 5. Pin installation URLs to an immutable release tag and commit rather than `main`. 6. Encourage users to inspect the downloaded script before invoking it explicitly with `bash install.sh`. 7. Do not recommend running the installer with `sudo` or from a privileged account. ]]>

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/install.sh:28
Finding
Installer downloads and enables an unauthenticated native executable<![CDATA[ ## Vulnerability Details **File Location**: `scripts/install.sh:28-47`; invoked by `SKILL.md:76-84` **Vulnerability Type**: Unverified remote native-code installation **Risk Level**: High ### Complete Code Snippet ```bash # Construct filename and URL FILENAME="docr-$OS-$ARCH$EXT" DOWNLOAD_URL="https://github.com/scottkiss/doc-ocr/releases/download/$VERSION/$FILENAME" # Set target directory relative to the script location SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" TARGET_DIR="$SCRIPT_DIR/docr" TARGET_FILE="$TARGET_DIR/docr$EXT" echo "Downloading docr $VERSION for $OS ($ARCH)..." # Ensure the target directory exists mkdir -p "$TARGET_DIR" # Download the binary curl -L -o "$TARGET_FILE" "$DOWNLOAD_URL" if [ $? -eq 0 ]; then # Make it executable chmod +x "$TARGET_FILE" ``` The Skill directs users to execute this installer: ```bash cd doc-ocr-skills/scripts ./install.sh ``` ### Technical Analysis The installer downloads a native executable from the separate `scottkiss/doc-ocr` repository and marks it executable. It does not verify a checksum, digital signature, release provenance, expected file type, or expected size. Although `VERSION` is fixed to `v1.0.0`, a version label alone does not authenticate the contents of the release asset. A compromised repository or replaced release asset could deliver a different executable under the expected filename. The audited package contains neither the downloaded executable nor its OCR source code. Consequently, the audit cannot verify how it handles documents, whether it limits network activity, how it reads `~/.ocr/config`, or whether it performs unrelated system operations. The script also uses `curl -L` without `--fail`, so an HTTP error response can still result in a successful curl exit and be marked executable. Downloading a binary is useful for distribution, but executing an unauthenticated native artifact is not a least-privilege installation design. ### Attack Path 1. A ...[truncated 1198 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Publish SHA-256 hashes for every supported platform artifact and verify the selected binary before granting execute permission. 2. Sign release artifacts and verify signatures against a pinned maintainer identity. 3. Use reproducible builds and publish build provenance so users can correlate binaries with reviewed source. 4. Include the complete OCR source in the audited project or use a verifiable source reference. 5. Harden the download operation: ```bash curl --fail --show-error --location \ --proto '=https' --tlsv1.2 \ --output "$TARGET_FILE.tmp" "$DOWNLOAD_URL" ``` 6. Validate the temporary file before atomically moving it to the final path. 7. Delete temporary or failed downloads and never mark them executable. 8. Use `set -euo pipefail` and explicit error handling rather than checking only the final curl status. 9. Run the OCR binary in a sandbox with access limited to the selected input, output directory, required configuration, and necessary network destinations. ]]>

T08 · Insecure Dependencies

Warning
Location
README.md:20
Finding
Installation instructions use unpinned third-party dependencies<![CDATA[ ## Vulnerability Details **File Location**: `README.md:20-24,48-52`; duplicated in `README_CN.md:20-24,48-52`; local dependency commands also appear in `SKILL.md:10-14` **Vulnerability Type**: Unpinned package and transitive dependency installation **Risk Level**: Medium ### Complete Code Snippet ```bash npx skills add scottkiss/doc-ocr-skills ``` ```markdown - **RapidOCR** (Default): `pip install rapidocr_onnxruntime` - **PaddleOCR**: `pip install paddleocr paddlepaddle` ``` The Skill repeats the Python package commands: ```markdown - For RapidOCR engine: `pip install rapidocr_onnxruntime` - For PaddleOCR engine: `pip install paddleocr paddlepaddle` ``` ### Technical Analysis The documented package installation commands do not pin exact package versions or verify package hashes. The installed result can therefore change over time without a corresponding change to the audited Skill. Python package installation can download multiple transitive dependencies, and package build or installation behavior may execute code in the user's environment. The `npx` command also invokes external package tooling without documenting an immutable package version or artifact digest. No evidence in the audited files establishes that these named packages are currently malicious. The confirmed issue is that the instructions leave dependency selection and integrity to mutable external registries, expanding the supply-chain trust boundary. ### Attack Path 1. A package maintainer account, release pipeline, registry entry, or transitive dependency is compromised. 2. A new malicious package version is published under a dependency name used by the instructions. 3. A user executes the unpinned `pip install` or `npx` command. 4. The package manager resolves the newest acceptable version and downloads it. 5. Malicious installation or runtime code executes under the user's account. 6. The compromised OCR dependency can access documents supplied for processing and other res ...[truncated 465 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin all direct dependencies to reviewed, exact versions. 2. Generate and publish a lockfile or constraints file containing the complete transitive dependency graph. 3. Require package hashes, for example through pip's `--require-hashes` mode. 4. Pin the exact version used by `npx` and document the expected package source and integrity metadata. 5. Install dependencies in an isolated, non-privileged virtual environment rather than globally. 6. Review package provenance, maintainers, release history, and build artifacts before updating pins. 7. Use automated dependency scanning while requiring manual approval for version changes. 8. Avoid `sudo pip install`, privileged Node package installation, or execution from accounts with unnecessary access. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
README.md:54
Finding
Gemini API key is written to plaintext configuration without enforced permissions<![CDATA[ ## Vulnerability Details **File Location**: `README.md:54-62`; duplicated in `README_CN.md:54-62`; repeated in `SKILL.md:16-25` **Vulnerability Type**: Insecure sensitive configuration storage **Risk Level**: Medium ### Complete Code Snippet ```bash mkdir -p ~/.ocr cat > ~/.ocr/config << EOF # Google Gemini API Key gemini_api_key=your_gemini_key_here EOF ``` The Skill provides the equivalent configuration procedure: ```bash mkdir -p ~/.ocr cat > ~/.ocr/config << EOF # Google Gemini API Key gemini_api_key=your_gemini_key EOF ``` ### Technical Analysis The instructions store a long-lived API credential in a plaintext file. They do not set restrictive permissions on either `~/.ocr` or `~/.ocr/config`; resulting permissions depend on the user's current umask and any pre-existing directory permissions. On systems with an unusually permissive umask or shared-home configuration, other local principals or processes may be able to read the credential. The risk is compounded because the unaudited downloaded OCR executable is expected to read this file. Plaintext local storage may be operationally necessary when a tool lacks credential-store integration, but the instructions should explicitly enforce owner-only access. ### Attack Path 1. A user follows the documented configuration command under a permissive umask or in a home directory with insufficient access restrictions. 2. `~/.ocr/config` is created with permissions that allow an unintended local principal or process to read it. 3. That principal reads the `gemini_api_key` value. 4. The exposed key is used to submit API requests, consume quota, incur costs, or access any API capabilities assigned to it. ### Impact Assessment The primary impact is disclosure and unauthorized use of the Gemini API key. The attacker obtains the permissions and quota granted to that credential, but this finding alone does not establish operating-system privilege escalation. Potential consequences include unauthorized ...[truncated 117 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create the credential directory with owner-only access: ```bash install -d -m 700 "$HOME/.ocr" ``` 2. Create the configuration file with mode `600`, for example: ```bash umask 077 cat > "$HOME/.ocr/config" <<'EOF' gemini_api_key=your_gemini_key_here EOF chmod 600 "$HOME/.ocr/config" ``` 3. Prefer an operating-system credential store or secret manager rather than a plaintext file. 4. Support reading the key from a protected environment or file-descriptor-based secret supplied only to the OCR process. 5. Ensure the application never logs the key or includes it in error output. 6. Document key rotation and immediate revocation procedures. 7. Scope the API key to only the required Gemini service, with quotas and billing alerts where supported. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (15)

Chaining Abuse

High
Category
Tool Misuse
Content
Use our convenient install script to download the latest pre-compiled binary for your system:

```bash
curl -sSL https://raw.githubusercontent.com/scottkiss/doc-ocr-skills/main/scripts/install.sh | bash
```

*Note: The script installs the `docr` binary into a `docr` directory relative to where it's run. Add it to your PATH for global access.*
Confidence
97% confidence
Finding
Piping remote content straight into `bash` is dangerous because it chains retrieval and execution with no opportunity for validation. In the context of a CLI installation flow, this materially increases the chance of immediate arbitrary code execution from a compromised upstream source.

Chaining Abuse

High
Category
Tool Misuse
Content
使用我们的安装脚本下载适用于您系统的最新预编译二进制文件:

```bash
curl -sSL https://raw.githubusercontent.com/scottkiss/doc-ocr-skills/main/scripts/install.sh | bash
```

*注意:脚本会将 `docr` 二进制文件安装到运行目录下的 `docr` 文件夹中。建议将其添加到 PATH 以便全局访问。*
Confidence
99% confidence
Finding
Piping `curl` output directly into `bash` removes the user's opportunity to review the downloaded script and amplifies supply-chain risk. In the context of an install command, this can lead to immediate arbitrary code execution with the user's privileges if the remote content is tampered with.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The feature list promotes Gemini support but does not clearly warn that using the Gemini engine sends document contents to a third-party cloud service. For an OCR tool that may process sensitive PDFs and images, this omission can lead users to unintentionally transmit confidential material off-device.

Rp1

Medium
Category
MCP Rug Pull
Confidence
88% confidence
Finding
The README recommends `npx skills add scottkiss/doc-ocr-skills` without pinning a specific package version or immutable reference. This can cause users to fetch whatever package/version is current at execution time, increasing supply-chain risk if the package is compromised or a breaking/malicious release is published.

Session Persistence

Medium
Category
Rogue Agent
Content
- **PaddleOCR**: `pip install paddleocr paddlepaddle`

### API Configuration (For Gemini)
To use the Gemini engine, create a configuration file at `~/.ocr/config`:

```bash
mkdir -p ~/.ocr
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.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The feature list advertises Gemini support but does not clearly warn that using the Gemini engine sends document contents to a third-party cloud service for processing. For an OCR tool that may handle sensitive PDFs or images, this omission can cause users to disclose confidential data unintentionally.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Session Persistence

Medium
Category
Rogue Agent
Content
要使用 Gemini 引擎,请在 `~/.ocr/config` 创建配置文件:

```bash
mkdir -p ~/.ocr
cat > ~/.ocr/config << EOF
# Google Gemini API Key
gemini_api_key=您的_gemini_密钥
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.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill explicitly instructs users to run shell commands and an installer script, but the manifest does not declare any tool scope such as permissions or allowed-tools. This weakens reviewability and containment because consumers cannot easily tell that shell execution and binary download are required before using the skill.

Session Persistence

Medium
Category
Rogue Agent
Content
### API Key Configuration

Create the config file:

```bash
mkdir -p ~/.ocr
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.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The Gemini engine sends document contents to a cloud service, but the skill does not provide a clear privacy or data-transmission warning near usage instructions. Users may unintentionally upload sensitive PDFs or images to an external provider, creating confidentiality and compliance risk.

Session Persistence

Medium
Category
Rogue Agent
Content
| Error | Solution |
|-------|----------|
| `config file not found` | Create `~/.ocr/config` with API keys |
| `gemini_api_key not found` | Add `gemini_api_key=VALUE` to config |
| `file not found` | Verify the document file path |
| API timeout | Retry; large files may need longer |
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.

External Script Fetching

Low
Category
Supply Chain
Content
Use our convenient install script to download the latest pre-compiled binary for your system:

```bash
curl -sSL https://raw.githubusercontent.com/scottkiss/doc-ocr-skills/main/scripts/install.sh | bash
```

*Note: The script installs the `docr` binary into a `docr` directory relative to where it's run. Add it to your PATH for global access.*
Confidence
95% confidence
Finding
The README instructs users to fetch and execute a remote script directly with `curl ... | bash`, which prevents inspection before execution and creates a straightforward supply-chain execution path. If the GitHub account, repository, branch, or network path is compromised, arbitrary code will run on the user's machine.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
该 README 全文以中文编写,未在正文中说明语言可由用户选择,也未提示这是面向特定中文受众的区域化文档。虽然 L006 链接到英文版本,但当前文档本身未提供用户可选语言或明确的本地化范围说明。

External Script Fetching

Low
Category
Supply Chain
Content
使用我们的安装脚本下载适用于您系统的最新预编译二进制文件:

```bash
curl -sSL https://raw.githubusercontent.com/scottkiss/doc-ocr-skills/main/scripts/install.sh | bash
```

*注意:脚本会将 `docr` 二进制文件安装到运行目录下的 `docr` 文件夹中。建议将其添加到 PATH 以便全局访问。*
Confidence
98% confidence
Finding
The README instructs users to fetch and execute a remote shell script directly from the network. If the GitHub account, repository, branch, or delivery path is compromised, users may immediately run attacker-controlled code on their system without inspection.

Static analysis

No suspicious patterns detected.