Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Teach agents to run Nuclei DAST and API security scans in CI, write templates, and gate builds on actionable findings.
.claude/skills/pramoddutta-nuclei-api-security-scanning/SKILL.md| Model | Eval pass | Runs |
|---|---|---|
| gemini-3.6-flash | 100% | 21 |
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 55% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 52% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 58% | 0% |
| case-08 | ✗→✓ | ▲ Improved | -5% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 21% | 0% |
You are an API security automation engineer who uses Nuclei templates to find real DAST risks in CI while keeping scans scoped, repeatable, and safe for shared environments.
Install Nuclei in CI and local developer environments.
bashmkdir -p security/nuclei/templates security/nuclei/results curl -s https://api.github.com/repos/projectdiscovery/nuclei/releases/latest \ | grep browser_download_url \ | grep linux_amd64.zip \ | cut -d '"' -f 4 \ | xargs curl -L -o nuclei.zip unzip -o nuclei.zip -d ./bin ./bin/nuclei -version
For local macOS development, use a package manager if approved by your team.
bashbrew install nuclei nuclei -update nuclei -update-templates nuclei -version
Keep security automation separate from application tests.
textsecurity/ nuclei/ targets/ pull-request.txt staging.txt templates/ exposed-openapi.yaml missing-security-headers.yaml unsafe-debug-endpoint.yaml results/ .gitkeep scripts/ run-nuclei-api-scan.sh
Generate a target file from CI environment variables.
bash#!/usr/bin/env bash set -euo pipefail : "${API_BASE_URL:?API_BASE_URL is required}" mkdir -p security/nuclei/targets printf '%s\n' "$API_BASE_URL" > security/nuclei/targets/pull-request.txt echo "Prepared Nuclei target for ${API_BASE_URL}"
Write focused templates for product-specific API risks.
yamlid: unsafe-debug-endpoint info: name: Unsafe debug endpoint exposed author: qa-security severity: high tags: api,debug,exposure requests: - method: GET path: - "{{BaseURL}}/debug" - "{{BaseURL}}/actuator/env" matchers-condition: or matchers: - type: word words: - "environment" - "JAVA_HOME" - "process.env" condition: or - type: status status: - 200
Use a wrapper script so local and CI runs match.
bash#!/usr/bin/env bash set -euo pipefail TARGET_FILE="${TARGET_FILE:-security/nuclei/targets/pull-request.txt}" TEMPLATE_DIR="${TEMPLATE_DIR:-security/nuclei/templates}" RESULT_FILE="${RESULT_FILE:-security/nuclei/results/nuclei-results.jsonl}" SEVERITY="${SEVERITY:-medium,high,critical}" mkdir -p "$(dirname "$RESULT_FILE")" nuclei \ -list "$TARGET_FILE" \ -templates "$TEMPLATE_DIR" \ -severity "$SEVERITY" \ -rate-limit 20 \ -retries 1 \ -timeout 10 \ -jsonl \ -output "$RESULT_FILE" if grep -E '"severity":"(high|critical)"' "$RESULT_FILE" >/dev/null 2>&1; then echo "Nuclei found high or critical findings" exit 1 fi echo "Nuclei scan completed without high or critical findings"
Run the gate after the API preview deployment is reachable.
yamlname: api-security on: pull_request: jobs: nuclei: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: bash scripts/install-nuclei.sh - run: bash scripts/prepare-nuclei-target.sh env: API_BASE_URL: ${{ secrets.API_PREVIEW_URL }} - run: bash scripts/run-nuclei-api-scan.sh - uses: actions/upload-artifact@v4 if: always() with: name: nuclei-api-results path: security/nuclei/results/*.jsonl
Use a policy that the team can enforce.
| Scenario | Template Scope | Gate Behavior | |---|---|---| | Pull request | Custom API templates | Fail on high and critical | | Nightly staging scan | Official and custom templates | Open security report | | New endpoint | Endpoint-specific templates | Require clean result | | Authenticated API | Token from CI secret | Mask logs and limit rate | | Legacy API | Medium plus high | Track baseline before enforcing | | Public production | Approved safe templates only | Prefer scheduled low-rate run |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 18,649 | 26,266 | +41% | 1 | 1 | 0% | 3,701 | 5,742 | +55% | 0 | 0 | — |
case-02 | fail→pass | 20,803 | 22,054 | +6% | 1 | 1 | 0% | 2,908 | 4,428 | +52% | 0 | 0 | — |
case-03 | fail→fail | 16,027 | 16,113 | +1% | 1 | 1 | 0% | 1,924 | 3,614 | +88% | 0 | 0 | — |
case-04 | fail→fail | 16,919 | 14,107 | -17% | 1 | 1 | 0% | 1,974 | 3,377 | +71% | 0 | 0 | — |
case-05 | fail→pass | 17,673 | 14,216 | -20% | 1 | 1 | 0% | 2,296 | 3,637 | +58% | 0 | 0 | — |
case-06 | pass→pass | 14,785 | 21,417 | +45% | 1 | 1 | 0% | 2,381 | 3,790 | +59% | 0 | 0 | — |
case-07 | fail→fail | 20,395 | 16,845 | -17% | 1 | 1 | 0% | 2,406 | 3,299 | +37% | 0 | 0 | — |
case-08 | fail→pass | 17,352 | 11,434 | -34% | 1 | 1 | 0% | 2,667 | 2,531 | -5% | 0 | 0 | — |
case-09 | fail→pass | 18,046 | 15,863 | -12% | 1 | 1 | 0% | 2,459 | 2,982 | +21% | 0 | 0 | — |
case-10 | pass→pass | 12,560 | 10,559 | -16% | 1 | 1 | 0% | 964 | 2,215 | +130% | 0 | 0 | — |
case-11 | pass→pass | 16,813 | 16,809 | -0% | 1 | 1 | 0% | 1,586 | 3,215 | +103% | 0 | 0 | — |
case-12 | pass→pass | 26,879 | 11,645 | -57% | 1 | 1 | 0% | 1,235 | 2,453 | +99% | 0 | 0 | — |
case-13 | fail→pass | 19,742 | 14,740 | -25% | 1 | 1 | 0% | 2,088 | 3,101 | +49% | 0 | 0 | — |
case-14 | pass→pass | 20,239 | 20,340 | +0% | 1 | 1 | 0% | 2,142 | 3,841 | +79% | 0 | 0 | — |
case-15 | pass→pass | 25,665 | 20,619 | -20% | 1 | 1 | 0% | 2,935 | 4,003 | +36% | 0 | 0 | — |
case-16 | pass→pass | 20,630 | 18,819 | -9% | 1 | 1 | 0% | 2,547 | 3,918 | +54% | 0 | 0 | — |
case-17 | pass→pass | 17,597 | 14,227 | -19% | 1 | 1 | 0% | 1,811 | 2,998 | +66% | 0 | 0 | — |
case-18 | pass→pass | 19,389 | 17,135 | -12% | 1 | 1 | 0% | 1,747 | 3,162 | +81% | 0 | 0 | — |
case-19 | pass→pass | 22,970 | 25,664 | +12% | 1 | 1 | 0% | 2,239 | 4,424 | +98% | 0 | 0 | — |
case-20 | fail→pass | 19,601 | 12,412 | -37% | 1 | 1 | 0% | 2,169 | 2,570 | +18% | 0 | 0 | — |
case-21 | pass→pass | 19,963 | 23,596 | +18% | 1 | 1 | 0% | 2,894 | 4,653 | +61% | 0 | 0 | — |
case-22 | pass→pass | 34,603 | 16,794 | -51% | 1 | 1 | 0% | 4,626 | 4,370 | -6% | 0 | 0 | — |
case-23 | pass→pass | 19,770 | 17,192 | -13% | 1 | 1 | 0% | 2,444 | 4,268 | +75% | 0 | 0 | — |
case-24 | pass→pass | 22,415 | 22,667 | +1% | 1 | 1 | 0% | 2,986 | 4,625 | +55% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 24 cases were attempted. The headline lift of +29 percentage points is the difference between those two pass rates over the 24 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.