# What Fields Are Evaluated by the Security Scanning Policy for Claude Plugins

> Discover the fields evaluated by the Claude Plugins security scanning policy. Learn how it validates URLs, repos, SHAs, and file paths to ensure plugin security.

- Repository: [Anthropic/claude-plugins-community](https://github.com/anthropics/claude-plugins-community)
- Tags: security-policy
- Published: 2026-08-29

---

**The security scanning policy inspects the `.source` object of each plugin entry, specifically validating `url`/`repo` fields, enforcing 40‑character hex SHA requirements, scanning every string value for shell metacharacters, and verifying vendored filesystem paths.**

The **anthropics/claude-plugins-community** repository enforces strict supply‑chain controls through the *validate‑plugins* GitHub Action. This automated **security scanning policy** concentrates its checks on the `.source` object within [`marketplace.json`](https://github.com/anthropics/claude-plugins-community/blob/main/marketplace.json) entries to mitigate injection attacks and guarantee repository integrity.

## The `.source` Object: Primary Evaluation Target

According to the source code in [`.github/actions/validate-plugins/scripts/11-validate-invariants.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/scripts/11-validate-invariants.sh), the validation layer "enforces security policy on whichever fields are present" inside the `.source` object (lines 24‑25). The policy applies four specific invariants—**I4**, **I5**, **I8**, and **I9**—that govern remote URLs, commit identifiers, string sanitization, and local directory structure.

### URL and Repository Format (Invariant I4)

**I4** evaluates the `source.url` or `source.repo` field to ensure it references a trustworthy remote location. The check accepts either:

- A safe **HTTPS URL**, or
- A GitHub‑style `owner/repo` shorthand matching the pattern `^[A-Za-z0-9][A-Za-z0-9_.-]*/[A-Za-z0-9][A-Za-z0-9_.-]*$`

Any protocol other than HTTPS (such as HTTP or Git) triggers a validation failure.

### Commit SHA Validation (Invariant I5)

**I5** mandates that `source.sha` contain a full Git commit hash. The invariant requires exactly **40 hexadecimal characters** (`^[0-9a-f]{40}$`). The script allows specific entries to omit the SHA only if they appear in a designated `SHA_EXEMPT` list; otherwise, a missing or malformed hash produces an error.

### Shell Character Sanitization (Invariant I9)

**I9** performs a defensive sweep across **every string‑valued field** nested under `.source`, including `url`, `repo`, `sha`, and `path`. Using a `has_unsafe_chars` helper, the scanner detects metacharacters such as `&`, `|`, `;`, `<`, and `>`. If any field contains these symbols, the policy flags a security violation to prevent command‑injection exploits.

### Vendored Path Integrity (Invariant I8)

When `.source` points to a **local vendored path** rather than a remote URL, **I8** validates the filesystem location. The check verifies that the directory exists and contains a [`.claude-plugin/plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.claude-plugin/plugin.json) file, ensuring bundled plugins are complete and correctly structured before acceptance.

## Implementation in the Validation Script

The security logic resides in [`.github/actions/validate-plugins/scripts/11-validate-invariants.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/scripts/11-validate-invariants.sh). Lines 26‑57 implement the loops for **I4**, **I5**, and **I9**, extracting the `url`, `sha`, and iterating over all string values under `.source`. Lines 72‑84 handle **I8**, confirming the existence of vendored directories and their metadata files.

## Compliance Examples

A minimal configuration that satisfies all invariants:

```json
{
  "name": "example-plugin",
  "description": "A short description.",
  "source": {
    "url": "https://github.com/example/example-plugin",
    "sha": "d3b07384d113edec49eaa6238ad5ff00a6c5b7be"
  }
}

```

An invalid entry that triggers **I4**, **I5**, and **I9** violations:

```json
{
  "name": "bad-plugin",
  "description": "Bad source example.",
  "source": {
    "url": "http://insecure.example.com|rm -rf /",
    "sha": "12345"
  }
}

```

Running the validation action on the second example emits errors resembling:

```bash
::error file=.../marketplace.json:invariant I4: bad-plugin: source url/repo is not a safe https URL or owner/repo shorthand: http://insecure.example.com|rm -rf /
::error file=.../marketplace.json:invariant I5: bad-plugin: source.sha is missing or not a 40-char hex SHA
::error file=.../marketplace.json:invariant I9: bad-plugin: source field contains shell metacharacters: http://insecure.example.com|rm -rf /

```

## Summary

- The **security scanning policy** targets the `.source` object of each plugin entry in [`marketplace.json`](https://github.com/anthropics/claude-plugins-community/blob/main/marketplace.json).
- **I4** enforces HTTPS or strict `owner/repo` formatting for remote sources.
- **I5** requires a valid 40‑character hexadecimal SHA; exemptions are granted only via `SHA_EXEMPT`.
- **I9** scans all string fields under `.source` for unsafe shell characters using `has_unsafe_chars`.
- **I8** validates local vendored paths for required [`.claude-plugin/plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.claude-plugin/plugin.json) metadata.
- All checks execute within [`.github/actions/validate-plugins/scripts/11-validate-invariants.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/scripts/11-validate-invariants.sh) as part of the *validate‑plugins* GitHub Action.

## Frequently Asked Questions

### Does the security scanning policy evaluate fields outside the `.source` object?

While the repository defines eleven total invariants (**I1** through **I11**) that check name length, description size, and schema validity, the specific security‑focused checks (**I4**, **I5**, **I8**, **I9**) exclusively inspect fields within the `.source` object. These constraints prevent arbitrary code execution and ensure supply‑chain provenance.

### What happens if a plugin uses an HTTP URL instead of HTTPS?

The **I4** invariant rejects any `source.url` that does not use the HTTPS protocol. The validation script explicitly checks for safe HTTPS URLs or GitHub `owner/repo` shorthands, flagging plain HTTP as a security violation to prevent man‑in‑the‑middle attacks.

### Are SHA hashes optional for community plugins?

**I5** generally mandates a 40‑character hex SHA for every plugin entry. However, the policy allows specific exceptions through the `SHA_EXEMPT` list. If an entry is not exempt and lacks a valid SHA, the validation action fails, blocking the submission from the marketplace.

### How does the policy prevent command injection vulnerabilities?

**I9** mitigates injection risks by scanning every string value inside `.source` for shell metacharacters such as `&`, `|`, `;`, `<`, and `>`. The script utilizes a `has_unsafe_chars` function to detect these symbols; if found, the validator emits an error and halts processing, ensuring malicious payloads cannot reach the build pipeline.