Grades are a hygiene check, not a security guarantee.

MCP, MCP server

HEIDES

HEIDES is a deterministic harness that gives AI coding agents what they do not have on their own: a persistent map of the code, warnings derived from that map, and a verdict before a patch lands.

Compatibility: Not stated.

Grade C

One Medium finding. Read the findings before installing.

Graded by PlugVetRubric v2

Not a guarantee. A hygiene check of the source at the commit shown, not a security audit.

Rescanned at commit 5bcd68ecc94e, unchanged since the check below.

SECRETS_PATH_CREDENTIAL

Why this grade

  • SECRETS_PATH_CREDENTIAL Medium

    Mentions a credential store path (~/.ssh, id_rsa, .npmrc, .aws/credentials, credentials.json, .netrc).

    src/config.rs, line 112 // A private key file: `id_rsa`, `server.pem`, `.ssh/id_ed25519`. These have

Any High, or two or more Medium findings, give D. One Medium gives C. Low findings or a security Note give B. Each code names a finding behind the letter.

Grades are a hygiene check of the source at the commit shown, on the date checked, not a security audit or a guarantee. The free directory grades are automated. Before release, a PlugVet engineer reviews every paid report and any grade we hold back, including all F grades, against the source code and the evidence we quote.

What was checked

Plain notes from the hygiene checks.

  • Permissions

    Note

    requests shell access. The manifest names this permission.

    PERMISSION_SHELL_DECLARED

    src/harmony.rs, line 921

    = input()\n+ import subprocess\n+ subprocess.run(cmd, shell=True)\n+ token = \"ghp_ab

    src/harmony.rs, line 974

    " subprocess.run(cmd, shell=True)",

    src/practice.rs, line 179

    /// These do not need a taint flow to be wrong. `subprocess.run(cmd, shell=True)`

    Show more

    src/taint.rs, line 584

    // `subprocess.run(`, `.call(`, `.check_output(` and `.Popen(` all reach a

    src/taint.rs, line 2022

    /// parameter is not a source, so `def go(cmd): os.system(cmd)` is silent

    src/taint.rs, line 2030

    let src = "def go(cmd):\n os.system(cmd)\n";

    src/taint.rs, line 2069

    let src = "def run():\n name = input()\n os.system(name)\n";

    CHANGELOG.md, line 558

    * **`staged` ran no security guards at all.** A patch adding `subprocess.run(cmd, shell=True)`, `requests.get(url, verify=False)`, `eval(cmd)` and a hardcoded `ghp_` token reported

  • Install and update

    Note

    README documents an installer that pipes a download into a shell. The docs document an installer that pipes a download into a shell.

    INSTALL_DOCUMENTED_INSTALLER

    README.md, line 173

    curl -fsSL https://raw.githubusercontent.com/AbduljabbarBXR/heides/main/scripts/install.sh | bash

    README.md, line 180

    HEIDES_VERSION=v0.16.0 curl -fsSL https://raw.githubusercontent.com/AbduljabbarBXR/heides/main/scripts/install.sh | bash

    scripts/install.sh, line 4

    # curl -fsSL https://raw.githubusercontent.com/AbduljabbarBXR/heides/main/scripts/install.sh | bash

  • Network

    Concern

    can reach a host that is not written as a fixed address. can reach api.example.com. The description does not name that host. can reach 169.254.169.254. The description does not name that host.

    NETWORK_NO_FIXED_HOST NETWORK_UNNAMED_HOST

    npm/install.js, line 18

    // and HEIDES_VERSION is honoured so the same pin works for the curl installer

    npm/test.js, line 28

    // The same variable the curl installer uses, so one pin works everywhere.

    scripts/install.sh, line 55

    curl -fsSL "$(url_for)" -o "$dest.tmp"

    Show more

    src/taint.rs, line 2048

    let src = "def go():\n requests.get(url)\n";

    src/taint.rs, line 2256

    let src = "async function proxy(req, res) {\n const target = req.query.url;\n const r = await fetch(target);\n res.send(r);\n}\n";

    src/taint.rs, line 2268

    "app.get('/p', (req, res) => {\n fetch(req.query.url).then(r => r.text());\n});\n";

    src/taint.rs, line 2280

    let js = "function p(req) {\n const u = req.query.u;\n return axios.get(u);\n}\n";

    src/taint.rs, line 2285

    let py = "def proxy(request):\n target = request.args['u']\n return requests.get(target)\n";

    README.md, line 110

    const r = await fetch('https://api.internal/health'); // ...and this must stay silent

  • Secrets

    Concern

    reads a credential or environment file.

    SECRETS_PATH_CREDENTIAL SECRETS_PATH_DOTENV

    src/config.rs, line 3

    // A credential sitting in a committed `.env`, a Dockerfile, a Terraform variable

    src/config.rs, line 6

    // reads it. These files are not even collected today, because a `.env` has no

    src/config.rs, line 112

    // A private key file: `id_rsa`, `server.pem`, `.ssh/id_ed25519`. These have

    Show more

    src/config.rs, line 75

    /// ones with no extension: `.env` and `Dockerfile`. A name containing `env` is

    src/config.rs, line 111

    // `.env`, `.env.local`, `env.production`, `.env.example`.

    src/config.rs, line 113

    // no extension to match on, which is the same reason `.env` and

    src/config.rs, line 119

    if lower == ".env" || lower.starts_with(".env.") || lower == "env" {

    src/config.rs, line 122

    // `creds.env`, `secrets.env`, `prod.env`. The `.env` extension is the same

  • Agent instructions

    Pass

    No instruction to ignore earlier instructions or to hide a step.

  • Obfuscation

    Pass

    No encoded or minified payload found.

  • Licence

    Pass

    A licence file is present (LICENSE).

  • Maintainer activity

    Pass

    The latest commit is within the last 365 days.

Note

Hygiene check of commit 5bcd68ecc94e. requests shell access. The manifest names this permission. README documents an installer that pipes a download into a shell. The docs document an installer that pipes a download into a shell. can reach a host that is not written as a fixed address. can reach api.example.com. The description does not name that host. can reach 169.254.169.254. The description does not name that host. reads a credential or environment file.

Date and source

Date checked:

View source

github.com

Commit graded: 5bcd68ecc94edc95a3cf42a1f10e8ccb4c3331ea

This link goes to the original host. PlugVet does not host or check what you download from there, and installing it is your own decision and risk.

Read how this letter is chosen