Grades are a hygiene check, not a security guarantee.

MCP, MCP server

codebadger

codebadger is a containerized Model Context Protocol (MCP) server that gives AI agents and LLMs deep, queryable access to a codebase's structure and data flow through Joern Code Property Graphs (CPGs).

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 857adcabe386, unchanged since the check below.

INSTALL_REMOTE_SCRIPT

Why this grade

  • INSTALL_REMOTE_SCRIPT Medium

    Fetches a script from the network and runs it (a pipe to a shell, or an install hook with a URL).

    Dockerfile, line 43 RUN curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain stable

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.

If you think this grade is wrong, email [email protected] with the entry link and your evidence. We aim to acknowledge within two working days and decide within seven. If we confirm an error, we aim to correct it within 24 hours of confirming it. These are aims, not guarantees.

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

    Concern

    can delete files.

    PERMISSION_DELETE_FILES

    src/services/cpg_generator.py, line 306

    result = subprocess.run(

    src/services/cpg_generator.py, line 340

    subprocess.run(

    src/services/cpg_generator.py, line 370

    result = subprocess.run(

    Show more

    src/services/git_manager.py, line 235

    shutil.rmtree(target_path)

    src/tools/core_tools.py, line 195

    shutil.rmtree(target, ignore_errors=True)

    src/tools/core_tools.py, line 454

    process = subprocess.run(

    src/tools/core_tools.py, line 680

    shutil.rmtree(tmp_dir, ignore_errors=True)

    src/tools/core_tools.py, line 682

    shutil.rmtree(tmp_dir, ignore_errors=True)

    src/tools/core_tools.py, line 868

    shutil.rmtree(codebase_dir, ignore_errors=True)

    src/tools/taint_analysis_tools.py, line 110

    "eval", "exec", "os.system", "os.popen", "subprocess.call",

    src/tools/taint_analysis_tools.py, line 111

    "subprocess.Popen", "subprocess.run", "pickle.load", "yaml.load",

    src/tools/taint_analysis_tools.py, line 115

    "eval", "setTimeout", "setInterval", "child_process.exec",

    src/tools/taint_analysis_tools.py, line 116

    "child_process.spawn", "fs.writeFile", "res.send", "res.render",

    src/utils/logging.py, line 108

    os.remove(link)

  • Install and update

    Serious

    install fetches a script from the network.

    INSTALL_REMOTE_SCRIPT

    requirements.txt, line 2

    fastmcp>=3.4.2

    Dockerfile, line 43

    RUN curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain stable

  • Network

    Concern

    can reach a host that is not written as a fixed address.

    NETWORK_NO_FIXED_HOST

    scripts/deploy.sh, line 77

    if body="$(curl -fsS "$HEALTH_URL" 2>/dev/null)" || body="$(curl -sS "$HEALTH_URL" 2>/dev/null)"; then

    scripts/deploy.sh, line 118

    curl -fsS "$HEALTH_URL" | (python3 -m json.tool 2>/dev/null || cat) || true

    src/services/joern_server_manager.py, line 1216

    response = requests.get(url, timeout=2)

    Show more

    config.example.yaml, line 340

    - axios.get

  • Secrets

    Concern

    reads a credential or environment file.

    SECRETS_ENV_READ SECRETS_PATH_DOTENV

    scripts/deploy.sh, line 19

    # Read KEY from .env. `docker compose` auto-loads .env, but THIS script does not, so

    scripts/deploy.sh, line 20

    # a value set only in .env is otherwise invisible here - leading to a health probe

    scripts/deploy.sh, line 21

    # on the wrong port, or an exported default that overrides the .env value in compose

    Show more

    scripts/deploy.sh, line 22

    # (shell env > .env). Read it the way compose resolves: exported shell var > .env.

    scripts/deploy.sh, line 24

    # where a non-zero return (e.g. no .env file) would abort the whole script.

    scripts/deploy.sh, line 25

    env_file_value() { [[ -f .env ]] && sed -n "s/^$1=//p" .env | tail -1 || true; }

    scripts/deploy.sh, line 28

    # Honor a PLAYGROUND_HOST_PATH set only in .env instead of clobbering it with the

    scripts/deploy.sh, line 29

    # default (export would make our value win over .env inside compose).

    src/config.py, line 52

    server_auth_password=os.getenv("JOERN_SERVER_AUTH_PASSWORD"),

    src/defaults.py, line 34

    f"{os.getenv('POSTGRES_PASSWORD', POSTGRES_PASSWORD)}@"

  • 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 857adcabe386. can delete files. install fetches a script from the network. can reach a host that is not written as a fixed address. reads a credential or environment file.

Date and source

Date checked:

View source

github.com

Commit graded: 857adcabe38677c53d068b310ab4f6ca51828c61

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