Skip to content

pensarai/cursor-pentest-plugin

Repository files navigation

apex-pentest — Cursor plugin

Catch security bugs before you ship them. When Cursor's agent changes security-critical code (auth, access control, payments, admin, uploads, webhooks, SSRF-prone fetches, new/changed API handlers, …), this plugin has it run a Pensar Apex targeted pentest against a reachable app target, then triage and fix what it finds — without you having to remember to ask.

Apex needs a reachable HTTP target. In Cursor, that can be the localhost server or snapshot environment the agent spins up while working, a dev server you already have running, or a deployed preview/staging URL. The plugin supplies the policy, methodology, and automatic trigger so validation isn't forgotten.


Setup

Four steps, ~5 minutes. You only do steps 1–3 once.

1. Install the Pensar Apex CLI

npm i -g @pensar/apex
pensar doctor          # confirms the install + any system tools (e.g. nmap)

Requires Node.js (the plugin's hooks are Node scripts too).

2. Sign in to Pensar ($20 in free credits)

Apex needs a model provider. The easiest path — and the one we recommend — is to sign in to Pensar: it routes inference through Pensar's gateway and new accounts come with $20 in free credits, so there's nothing to configure and no API keys to manage.

pensar login

This opens console.pensar.dev — sign in with GitHub, create a workspace, and you'll land on your credits page with your $20 in free credits already applied. Inference draws down that balance; you can top up anytime at console.pensar.dev/credits.

Prefer to bring your own provider key?

Instead of pensar login, export one of these in your shell profile (~/.zshrc, ~/.bashrc):

export ANTHROPIC_API_KEY=…    # or PENSAR_API_KEY / OPENAI_API_KEY / OPENROUTER_API_KEY

With your own key, pensar doctor reports the provider. After pensar login it may still say "No AI provider configured" — that check only inspects environment variables, so ignore it; login auth still works.

3. Install the plugin in Cursor

If the plugin is available in Cursor's marketplace, install it there and reload Cursor.

For local development or pre-marketplace installs, clone it directly into Cursor's local-plugins directory. It must be a real directory at this path, not a symlink to a checkout elsewhere:

git clone https://github.com/pensarai/cursor-pentest-plugin.git ~/.cursor/plugins/local/apex-pentest
chmod +x ~/.cursor/plugins/local/apex-pentest/hooks/*.sh   # usually already executable

Then reload Cursor: Cmd/Ctrl+Shift+P → "Developer: Reload Window" (or restart).

4. Verify it loaded

After reload you should see:

  • Apex Pentest in Cursor's plugin list (with the green Pensar mark)
  • /apex-pentest when you type / in the agent chat
  • the always-on security rule and the afterFileEdit / stop hooks active

If it's not there, see Troubleshooting.


Using it

Just work in Cursor as usual. The plugin does the rest:

  1. Edit code with the agent. When the agent finishes a turn that changed code, a 🔒 follow-up message asks it to check whether any change touched security-critical behavior.
  2. If nothing is security-critical, the agent says so in one line and moves on — no pentest.
  3. If something is, the agent needs a reachable app URL to test. This can be a Cursor-started localhost/snapshot environment, your own local dev server, or a preview/staging deploy. It resolves the URL in this order:
    • target in apex.config.json at your repo root — see Configure
    • the APEX_TARGET_URL environment variable
    • .apex/cursor/live-url — the agent can write this after it starts or discovers the app URL
  4. The agent runs the pentest (pensar targeted-pentest) with objectives derived from its own diff, reports findings, fixes critical/high issues, and re-runs to confirm.

You can also trigger it manually anytime with /apex-pentest (optionally pass a URL or a specific route/objective).

What it can target

The pentest sends real HTTP traffic, so source code alone isn't enough. The target can be:

  • Cursor-started localhost — the agent starts the app (npm run dev, docker compose up, …), waits for it to respond, and records the URL.
  • Cursor snapshot environments — including cloud-agent snapshot environments booted to test the current changes; point Apex at the app URL exposed inside that environment.
  • Your existing local dev server — if you already have the app running, provide its base URL.
  • A deployed preview / staging environment — e.g. the preview deploy for the PR the change belongs to, so you validate exactly what reviewers and users will hit.

If no URL is configured, the agent should start or discover the appropriate environment and write the base URL to .apex/cursor/live-url.

Authorization: only point this at an app or environment you're authorized to test. It runs an active pentest against the target. See Pensar's Responsible Use.


Configure (optional)

You don't need a config file. To set defaults, copy apex.config.example.json to apex.config.json at your repo root:

Field Purpose
enabled Set false to turn off the automatic stop-gate prompt.
target Base URL to pentest, if you want to pin one instead of letting the agent discover it.
baseBranch Also diff against this branch (the full "what this PR changes" view).
model Model id for pensar targeted-pentest --model (empty = auto).
headersFrom Path to a JSON headers file (auth cookie/token) for authenticated routes.
extraObjectives Objectives always included in every run.

Add .apex/ to your project's .gitignore — it holds per-conversation hook state and the discovered target URL pointer, and shouldn't be committed.


Troubleshooting

  • No /apex-pentest / plugin didn't load — the plugin must be a real directory under ~/.cursor/plugins/local/ (Cursor rejects a symlink whose target is outside that folder). Confirm ~/.cursor/plugins/local/apex-pentest/.cursor-plugin/plugin.json exists, then reload. Cursor logs the reason under ~/Library/Application Support/Cursor/logs/<newest>/ (look for loadUserLocalPlugin apex-pentest …).
  • pensar: command not found during a pentest — Apex isn't installed or isn't on the PATH that Cursor's agent shell uses. Re-run npm i -g @pensar/apex and pensar doctor.
  • The gate never prompts — it only fires when the agent finished cleanly and detected code changes (edited files or a dirty git tree). Also check apex.config.json doesn't have "enabled": false, and that hooks/*.sh are executable.
  • Pentest can't reach the target — make sure the app is actually serving and the URL (apex.config.json target / $APEX_TARGET_URL / .apex/cursor/live-url) is correct and reachable.
  • It keeps asking about an unrelated change — that change set hashed to a new signature. Tell the agent it isn't security-critical; the gate records the prompt and won't ask again for that set.

How it works (under the hood)

Piece What it does
rules/apex-security-pentest.mdc Always-on policy: security-critical changes aren't "done" until validated by an Apex pentest against a reachable app target.
hooks/ (afterFileEdit, stop) afterFileEdit records edited files; the stop gate detects code changes and hands the change set back to the agent. Fast, idempotent — never pentests itself.
skills/apex-targeted-pentest/SKILL.md The methodology the agent follows: decide criticality → resolve/start a target → handle auth → derive objectives → run the pentest → triage & fix → record.
commands/apex-pentest.md /apex-pentest — on-demand entry point that runs the skill.

The loop: the agent edits files (afterFileEdit logs each to .apex/cursor/<id>.edits) → finishes (stop); if code changed and that set hasn't been handled, the gate posts the 🔒 follow-up → the agent assesses and, if needed, runs /apex-pentest against the resolved app target → it records .apex/cursor/validated-<sig>.json so the gate stays quiet for that change set (it also never prompts twice for the same set, so there's no nag loop).

The agent is the brain (it decides what's security-critical and resolves or starts the target); Apex is the tool; the plugin is the policy + trigger.


Publishing (maintainers)

This repo uses Cursor's single-plugin layout: .cursor-plugin/plugin.json lives at the repository root, with the plugin components beside it.

Before submitting, validate the manifest, referenced paths, and component frontmatter:

node scripts/validate-template.mjs

Submit at cursor.com/marketplace/publish. Once published, users can install it from Cursor's plugin marketplace directly instead of cloning.

About

Cursor plugin: validate security-critical changes with a Pensar Apex targeted pentest against a live version of the app.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors