Guide · DerScanner

Claude Code Security Review and Code Quality — Claude Opus Wrote It, We Scanned It

A step-by-step Claude Code security review of a synthetic ShipDesk Express service generated by Claude Opus in Cursor — baseline DerScanner scan with SAST and Code Quality on JavaScript, a remediation prompt, a rescan under identical settings, and hybrid before/after reports built from the REST API on a local installation.

  • Steps16
  • Time40 minutes
  • AudienceApplication security engineers reviewing JavaScript written by Claude Opus or another AI coding model

What this guide covers

How do I run a security review and a code quality review on JavaScript generated by Claude Opus, remediate the findings, and prove what actually changed on the rescan?

One Claude Opus prompt produced a working shipment desk and eleven security rule families in a single upload. Running the same scan settings again after one remediation prompt shows exactly which families moved and which need a human decision.

DerScanner runs security (SAST) and Code Quality (CQ) in one scan when you pass both languages and cqLanguages. JavaScript supports both, so a single upload covers the security review and the quality review.

A security review of Claude-generated code is not a formality. Weak hashing, hardcoded credentials, plain-HTTP egress, and string-concatenated SQL all shipped in code that ran correctly on the first try.

Before you start

  • A DerScanner installation you can reach over HTTP, and an administrator account that can create users if needed.
  • A user account for this work that is not the administrator account. The screenshots were taken under a dedicated account named Cursor.
  • curl, or any HTTP client that can send multipart form data.
  • Cursor with the Claude Opus model selected, for the generation and remediation prompts.

Environment

DerScanner deployment
Self-hosted installation on a single host at http://localhost/. Replace the host in every command with your own. Cloud DerScanner uses the same API paths under your tenant URL.
AI coding tool and model
Cursor with Claude Opus selected as the model. Both the generation prompt and the remediation prompt were sent from Cursor; no code was written by hand except the three string literals noted in the remediation step.
Scan target
Synthetic ShipDesk Express + plain JavaScript + SQLite service, 630 analyzed lines in the baseline archive, generated from one prompt with no hand-edits before the first scan.
SAST engine
Classic JavaScript engine (sastEngineByLanguage.JAVASCRIPT = CLASSIC). Code Quality for JavaScript runs through the same pass when cqLanguages is set.
Baseline scan UUID
a14e4890-66ce-4260-b6dd-277b323b9fa3 — 31 security findings (6 critical, 24 medium, 1 low), score 16 across 630 LOC; 700 Code Quality findings with 431 critical and a CQ score of 1.
After-remediation scan UUID
ede2a8b0-db59-40c2-9db8-f3f89e0ec4c2 — 5 security findings (3 critical, 2 medium), score 65 across 822 LOC; 315 Code Quality findings with zero critical and a CQ score of 92.

The walkthrough

Step 1

Generate the application with Claude Opus in Cursor

Start from code that was never reviewed line by line, the way AI-assisted delivery usually works.

This guide uses a synthetic ShipDesk shipment and waybill desk written for the walkthrough only. It is not a real product and was never deployed. Everything under src/ came from one prompt sent to Claude Opus in Cursor; nothing was edited by hand before the baseline scan.

The prompt asked for a small logistics desk — staff login, searchable shipment lists, CSV waybill reports that can be zipped and emailed, waybill scan upload and download, a column layout import from an old desktop tool, and admin endpoints for warehouse sync and server stats. It deliberately did not ask for security hardening, tests, or Docker.

The result ran correctly. That is the point worth holding onto before the scan: working and reviewed are different properties, and a Claude Code security review exists to test the second one.

Save the prompt text alongside the archive you upload so later readers can see what the model was asked to produce.

The prompt sent to Claude Opus in Cursortext
We need a small internal shipment desk so the logistics team stops tracking waybills
in a shared spreadsheet. Build it with Express and plain JavaScript, SQLite is fine.

What it has to do:

- warehouse staff log in with username and password
- list shipments with search (filter by whichever column the user picks) and sort
- create and update shipments, assign a carrier
- export a waybill report as CSV for a date range, optionally zip it for email
- upload and download waybill scans (PDF, photos)
- import a saved column layout from our old desktop tool (it exports JSON we can load)
- admin endpoints: run the warehouse inventory sync script and show server stats

Keep it in a handful of files under src/, no ORM, plain SQL is fine. Skip tests
and Docker for now. Peak season starts next week, just make it work.

Step 2

Issue an API token

Drive both scans from a shell without installing anything into the IDE.

Request a token with the account credentials and a name you will recognise later. Send the access token as a bearer credential on every subsequent request.

If token creation returns SESSION_LIMIT_REACHED, revoke unused tokens or clear active JWT sessions on the installation before retrying. Tokens on the captured installation expire after fifteen minutes of inactivity, so reissue before a long session.

Request a named API tokenbash
curl -s -X POST "https://derscanner.example.com/app/api/v1/auth/jwt" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "username=$DERSCANNER_USER" \
  --data-urlencode "password=$DERSCANNER_PASSWORD" \
  --data-urlencode "token_name=shipdesk-api"

# {"accessToken":"eyJhbGciOiJIUzUxMiJ9..."}

Step 3

Run the baseline scan with SAST and Code Quality

Capture the first security and quality snapshot before any remediation.

Start the scan with languages=JAVASCRIPT and cqLanguages=JAVASCRIPT so DerScanner analyses security rules and code-quality rules in the same pass. Passing a name on the first scan creates the project; reuse the returned project UUID for the rescan so both scans sit side by side.

Keep AI triage flags off for every severity. The scan analyses the code and leaves every finding unverified until you choose otherwise.

The scan finished in about a second on this sample and reported 31 security findings — six critical, twenty-four medium, one low — with a security score of 16 across 630 lines. Code Quality on the same scan reported 700 findings with 431 critical and a CQ score of 1.

Upload the archive and start the baseline scanbash
TOKEN="$DERSCANNER_TOKEN"

curl -s -X POST "https://derscanner.example.com/app/api/v1/scan/start" \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@shipdesk-javascript.zip" \
  -F "name=ShipDesk JavaScript sample" \
  -F "languages=JAVASCRIPT" \
  -F "cqLanguages=JAVASCRIPT" \
  -F "checkboxNoBuild=true" \
  -F "preprocessing=true" \
  -F "aiTriageCritical=false" \
  -F "aiTriageMedium=false" \
  -F "aiTriageLow=false" \
  -F "aiTriageInfo=false" \
  -F "applyTriage=false"

# {"projUuid":"543e6449-...","scanUuid":"a14e4890-..."}
The scan list for the project. The baseline scan completes before the remediation prompt is applied.

Step 4

Read the baseline security metrics

Record the numbers you will compare after remediation.

Poll the project scan list until status is COMPLETE. Each scan DTO carries the security counts (critical, medium, low, info, score, loc) and the quality counts (criticalCq, mediumCq, lowCq, scoreCq, locCq) in one response, so a single call gives you both halves of the review.

A security score of 16 out of 100 is the headline, but the rule families matter more. Eleven fired on the baseline: SQL injection, reflected XSS, weak hashing, plain HTTP usage, hardcoded password, hardcoded crypto key, insecure randomness, three separate cookie rules, and unexpected network activity.

Note that DerScanner does not ship a single report that merges security and quality. Export the fields you need from the API or the Overview page, then assemble the combined view in Cursor Canvas or your own reporting tool.

Poll the scan and list findingsbash
TOKEN="$DERSCANNER_TOKEN"
PROJECT="543e6449-7c41-47ea-b293-cbbf8fe4b395"
BASELINE="a14e4890-66ce-4260-b6dd-277b323b9fa3"

curl -s "https://derscanner.example.com/app/api/v1/projects/$PROJECT/scans?offset=0&limit=5" \
  -H "Authorization: Bearer $TOKEN"

curl -s "https://derscanner.example.com/app/api/v1/scans/$BASELINE/issues?offset=0&limit=100" \
  -H "Authorization: Bearer $TOKEN"
Baseline security overview — 6 critical, 24 medium, 1 low, and a score of 16 out of 100.

Step 5

Review what the security review actually found

Connect rule IDs to concrete code patterns Claude Opus produced.

Open the detailed results for the baseline scan. Fourteen JS_INJECTION_SQL hits dominate the list — every query in the login path, the shipment search, the status counters, the report date range, and the carrier lookup is assembled by string concatenation, and the update helper builds its SET clause by looping over request-body keys.

JS_CRYPTO_BAD_HASH covers MD5 password hashing and SHA-1 request signing. JS_CRYPTO_BAD_RANDOM points at a session token derived from Math.random. JS_CRYPTO_KEY_HARDCODED and two JS_PASSWORD_HARDCODED hits point at the session secret, the admin token, and the carrier API password sitting in source.

JS_HTTP_USAGE and JS_BACKDOOR_NETWORK_ACTIVITY flag carrier tracking calls made over plain HTTP with the API password in a request header. The three cookie rules — JS_COOKIE_NOT_HTTPONLY, JS_COOKIE_NOT_OVER_SSL, JS_COOKIE_BROAD_PATH — all trace to one res.cookie call with no attributes at all.

Three JS_XSS_REFLECTED hits land on the HTML report preview, which interpolates the report title, the date range, and every row of shipment data straight into a template string.

Baseline findings — SQL injection accounts for fourteen of the thirty-one hits.

Step 6

Read the Code Quality half of the same scan

Show what the quality review adds that the security review does not cover.

Switch the Overview and Detailed Results pages to the CQ slice. The URLs are the same paths with /cq appended, so /projects/$PROJECT/summary_data/cq and /projects/$PROJECT/detailed_results/cq both take the same scan query parameter.

The baseline CQ score is 1 out of 100 across 700 findings. Read the rule mix before reacting to the number: 211 hits for incorrect use of single quotes and 120 for quote formatting are string conventions, while 89 uses of var, 8 string literals thrown as errors, 2 eval calls, and 1 unguarded for…in loop are genuine hygiene problems.

That split is the useful part of a quality review on AI-generated code. The convention hits tell you the model ignored a house style it was never given; the hygiene hits overlap with security — the two eval calls are the same dynamic-execution sinks a reviewer would flag by hand, reached through the layout import and a legacy filter helper.

Baseline Code Quality — 431 critical findings and a score of 1, dominated by string conventions and var usage.

Step 7

Trace Code Quality findings to source lines

Give the remediation prompt concrete targets instead of a score.

The CQ detailed results list every finding with its file and line, so you can group by rule before writing the remediation prompt. Grouping matters here: two rules account for 331 of the 431 critical findings, and fixing them is a formatting decision rather than a code change.

The remaining critical hygiene rules are the ones worth prompting about individually — replace var with const and let, throw Error objects instead of string literals, and remove both eval sinks.

Code Quality findings by file and line — the input for a targeted remediation prompt.

Step 8

Remediate with a second Claude Opus prompt

Fix vulnerabilities and hygiene issues without changing the feature set.

Send a second prompt in Cursor that references the DerScanner results and asks for specific fixes. Keep the security list and the quality list separate so the model does not treat a formatting rule as a security fix.

The remediation prompt is saved as PROMPT-REMEDIATION.txt in the sample archive so the before/after provenance is clear. Re-zip the project after Cursor applies the edits, keeping the same top-level folder name — Scans Comparison matches findings by file path, so a changed archive root makes every finding look fixed and re-added.

Three string literals containing double quotes had to be adjusted by hand afterwards, because the formatter prefers single quotes for those and the quality profile does not. Everything else came from the prompt.

Resist the temptation to tune code against individual rules. The goal is the fix batch a team would actually accept from an AI assistant after a scan.

Remediation prompt (excerpt)text
The ShipDesk JavaScript service was scanned with DerScanner (SAST + Code Quality).
Fix every reported security issue and improve code quality without changing the
feature set.

Security:

- Replace string-concatenated SQL with parameterized queries in every module.
- Escape all values interpolated into the HTML report preview.
- Use bcrypt for password hashing instead of MD5; use HMAC-SHA256 for carrier
  request signing instead of SHA-1.
- Generate session tokens with crypto.randomBytes, not Math.random.
- Read SHIPDESK_ADMIN_PASSWORD, SHIPDESK_CARRIER_API_USER, and
  SHIPDESK_CARRIER_API_SECRET from environment variables. No literals in source.
- Call carrier APIs over HTTPS with a request timeout.
- Set session cookies HttpOnly, Secure, SameSite=Lax, and scope them to /api.
- Add CSRF protection for state-changing routes.
- Validate attachment names and confirm resolved paths stay inside the upload
  directory.
- Do not execute user input through a shell; use execFile with an argument array
  and validate the warehouse code and mode.
- Remove eval and new Function; parse layout exports with JSON.parse.
- Stop returning stack traces and process environment from API responses.

Code quality:

- Replace var with const/let and add 'use strict' to every module.
- Throw Error objects instead of string literals.
- Use camelCase for functions; remove snake_case and PascalCase helpers.
- Remove duplicated helper functions and hardcoded absolute paths.
- Use strict equality and replace magic numbers with named constants.

Step 9

Rescan with identical settings

Measure what changed under the same analysis configuration.

Upload the remediated archive to the same project with the same languages, cqLanguages, and triage flags as the baseline scan. Pass uuid instead of name so the scan joins the existing project.

Security findings dropped from 31 to 5 and the score rose from 16 to 65. Lines of code grew from 630 to 822, because bcrypt, HMAC signing, CSRF verification, path validation, and input allowlists all add code — so the score improved despite a larger denominator.

Compare rule families rather than the headline score alone. Weak hashing, insecure randomness, hardcoded credentials, plain-HTTP egress, and all three cookie rules went to zero.

Start the after-remediation scanbash
TOKEN="$DERSCANNER_TOKEN"
PROJECT="543e6449-7c41-47ea-b293-cbbf8fe4b395"

curl -s -X POST "https://derscanner.example.com/app/api/v1/scan/start" \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@shipdesk-javascript-after.zip" \
  -F "uuid=$PROJECT" \
  -F "languages=JAVASCRIPT" \
  -F "cqLanguages=JAVASCRIPT" \
  -F "checkboxNoBuild=true" \
  -F "preprocessing=true" \
  -F "aiTriageCritical=false" \
  -F "aiTriageMedium=false" \
  -F "aiTriageLow=false" \
  -F "aiTriageInfo=false" \
  -F "applyTriage=false"

# {"scanUuid":"ede2a8b0-..."}
After-remediation security overview — 5 findings and a score of 65, up from 16.

Step 10

Confirm which security families cleared

Separate what the prompt fixed from what still needs a person.

Open the detailed results for the rescan. JS_CRYPTO_BAD_HASH, JS_CRYPTO_BAD_RANDOM, JS_CRYPTO_KEY_HARDCODED, JS_PASSWORD_HARDCODED, JS_HTTP_USAGE, JS_BACKDOOR_NETWORK_ACTIVITY, and all three cookie rules are gone. SQL injection fell from fourteen hits to two.

The five remaining findings sit in two places. Three JS_XSS_REFLECTED hits are on the HTML report preview, which now escapes every interpolated value through escape-html and sends a restrictive Content-Security-Policy header. Two JS_INJECTION_SQL hits are on the shipment search, where the sort and filter column names are interpolated after being checked against an allowlist while the values themselves are bound as parameters.

Both need a reviewer to look at the code and sign off, not another automated pass. That is the honest end state of a two-prompt remediation: most families cleared outright, and a short list left that a person closes.

After remediation — crypto, secrets, HTTP, and cookie families cleared; XSS and two allowlisted-column queries remain.

Step 11

Check the Code Quality rescan

Show the quality half of the same rescan.

The CQ score moved from 1 to 92 and critical Code Quality findings went from 431 to zero. Every critical rule cleared: 211 single-quote hits, 120 quote-formatting hits, 89 var usages, 8 thrown string literals, 2 eval calls, and the unguarded for…in loop.

The 315 remaining findings are all medium or low — indentation, block style, spacing, line length, variable grouping, and one constructor-naming rule. They are worth a formatter pass in CI rather than a prompt.

Read this alongside the security rescan rather than on its own. The two eval calls counted once as a critical quality finding and again as the dynamic-execution risk a reviewer cares about, and one remediation removed both.

Code Quality after remediation — zero critical findings and a score of 92, up from 1.

Step 12

Build the baseline hybrid Canvas

Merge security and quality metrics in one view the product does not ship natively.

Pull critical, medium, low, score, and loc together with criticalCq, mediumCq, lowCq, scoreCq, and locCq from the scan DTO, group findings by ruleId, and lay both slices out in one Cursor Canvas panel.

The baseline hybrid view puts the security story and the quality story side by side — 31 findings at score 16 next to 700 quality findings at score 1 — which is the framing a stakeholder needs before seeing the rescan.

Baseline hybrid Canvas — security rule families and Code Quality rule families in one panel.

Step 13

Build the after-remediation hybrid Canvas

Show what cleared and what is left, in one panel.

Reuse the layout with the rescan UUID and split each slice into what remains and what cleared outright. The cleared column is the part worth showing to whoever approved the remediation work.

On this capture the after panel shows 5 security findings at score 65 and zero critical quality findings at score 92, with ten rule families listed as cleared.

After-remediation hybrid Canvas — cleared families listed beside the short list that remains.

Step 14

Compare rule families in one Canvas

Give stakeholders a delta view the native interface does not merge into a single panel.

Add a third Canvas that plots baseline and after counts side by side by rule family — SQL injection, weak crypto and randomness, plain HTTP and egress, cookie flags, hardcoded secrets, and reflected XSS.

Include a short score-context note. Both scans cover the same project with the same rule set, so the scores are comparable, but lines of code grew from 630 to 822 and readers should know why before they read a fourfold score improvement.

Before/after Canvas — rule-family deltas for both slices with score context.

Step 15

Cross-check in DerScanner Scans Comparison

Pair the Canvas narrative with the native product view readers can open themselves.

Open Scans Comparison and select the baseline and after scans. The chart splits findings into remaining, fixed, and new by severity, and the SAST/CQ toggle above the scan pickers switches between the two slices.

The SAST view shows the twenty-four medium findings as fixed with two remaining. The CQ view shows all 431 critical findings fixed, with the low-severity count rising as the formatting rules redistributed across a larger file set.

Use this view alongside the Canvas panels — product interface for drill-down, Canvas for the combined story you export.

Native Scans Comparison, SAST slice — fixed and remaining findings by severity.

Step 16

Read the Code Quality comparison

Confirm the quality delta in the product interface, not only in the export.

Switch the toggle to CQ on the same comparison. The critical column shows 431 findings fixed and none remaining, which is the clearest single view of the quality result.

The rising low-severity column is expected. Formatting rules scale with file count and line count, and the remediated archive is larger.

Scans Comparison, CQ slice — all 431 critical Code Quality findings fixed.

Checking your result

Did the security review of Claude-generated code find real problems?

Yes. Eleven rule families fired on the baseline, including MD5 password hashing, a session token from Math.random, three hardcoded credentials, plain-HTTP carrier calls, and fourteen string-concatenated SQL queries.

How much did one remediation prompt fix?

Security findings fell from 31 to 5 and the score rose from 16 to 65. Weak hashing, insecure randomness, hardcoded secrets, plain HTTP, and all three cookie rules cleared completely.

Did Code Quality improve on the rescan?

Yes. Critical Code Quality findings went from 431 to zero and the CQ score rose from 1 to 92. The remaining 315 findings are medium and low formatting rules.

Can I run security and code quality in one scan for JavaScript?

Yes. Pass languages=JAVASCRIPT and cqLanguages=JAVASCRIPT on the same scan/start call. JavaScript, TypeScript, and Delphi/Pascal are the languages with Code Quality support.

Does DerScanner include a built-in hybrid security and quality report?

No. The two slices are separate in the product, with separate Overview, Detailed Results, and Scans Comparison views. Combine them in Cursor Canvas or your own reporting from the scan API fields.

Limits of this procedure

  • This walkthrough uses a synthetic application with deliberate defects. Metrics describe that sample only and are not a prediction of results on production code.
  • The JavaScript Code Quality profile mixes style rules with hygiene rules, and the style rules are numerous enough to dominate the critical count. Read the rule breakdown before treating a CQ score as a maintainability verdict.
  • Aggregate scores move with lines of code. The remediated archive is 822 lines against a 630-line baseline because hardening adds code, so compare rule families alongside the score.
  • Five security findings remain after remediation and need a human decision rather than another prompt. A guide that reported zero would be describing rule tuning, not a review.
  • Scans Comparison matches findings by file path. Keep the archive root identical between scans or the comparison will report everything as fixed and re-added.

Canonical terms used: DerScanner; JavaScript; Claude Opus; SAST; Code Quality; rescan; AI-generated code.

DerScanner

Run a security review on AI-generated JavaScript

Scan security and code quality in one upload, compare rescans after remediation, and keep source code on infrastructure you control.

DerScanner

Request a walkthrough on your stack

Tell us which models your team codes with and we will map the same baseline/rescan workflow to your environment.

DerSecur Recognition · build 46c14d5 · 2026-08-26 08:22:21Z · system