Checklist

  • Write a clear title: bug class, location, and privilege required.
  • Include a minimal, reproducible PoC: raw request, response, and proof of execution.
  • State impact in business terms, not just “RCE”.
  • Give an accurate severity with a CVSS vector.
  • Provide remediation the developer can act on.
  • Add a retest plan.
  • Follow the program’s disclosure rules.

A finding is only as good as its report. A reproducible report with clear impact gets fixed and paid; a vague one gets closed.

Report template

Copy this and fill it in.

# Title
Remote code execution in <component> via <entry point> (<auth level>)

## Summary
One or two sentences. What the bug is, where it is, and what it lets an attacker do.

## Severity
Critical. CVSS 3.1: <score> (<vector>)

## Affected asset
- URL or endpoint:
- Parameter or input:
- Version or build (if known):
- Auth required: none / user / admin

## Steps to reproduce
1. ...
2. ...
3. ...

## Proof of concept
Raw request:
<paste the exact HTTP request>

Response:
<paste the relevant response>

Proof of execution:
<command output, OOB callback log, or screenshot/video reference>

## Impact
What an attacker gains: full server compromise, access to <data>, lateral movement into <network>, persistence. Tie it to the business.

## Remediation
Specific fix for this sink and class. See remediation notes below.

## Retest
How to verify the fix. The exact request that should now fail.

## References
Advisory, OWASP WSTG section, PayloadsAllTheThings page, any vendor docs.

CVSS quick reference

RCE findings are usually Critical, but the vector depends on access and scope. Common patterns:

Scenario Rough score Vector sketch
Unauthenticated RCE, network reachable 9.8 AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
RCE needing a low priv account 8.8 AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
RCE needing admin 7.2 AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
RCE that escapes to the host (scope change) up to 10.0 raise with S:C

Set the vector honestly. Overstating severity hurts your credibility more than it helps.

Severity guidance for RCE

  • Unauthenticated and network reachable is the worst case. Report it first and fastest.
  • Authenticated RCE still matters: credential reuse and low bars to signup make it realistic. Do not downgrade it to low just because auth is required.
  • Note a scope change when code execution crosses a trust boundary, for example container to host, since that raises the score.
  • If exploitation needs an unusual precondition, state it plainly so the triager can judge it.

PoC format

  • Raw HTTP request: the exact bytes, so anyone can replay it. Mask real secrets.
  • Response: only the part that proves the point.
  • Proof of execution: the cleanest is an out of band callback log with a unique token, or command output like id or hostname. A short screen recording helps for multi step chains.
  • Keep it minimal. One request that proves execution beats a long exploit script.
  • Do not run destructive commands. Prove execution with read only commands such as id, whoami, hostname.

Impact statement examples

  • “An unauthenticated attacker can run arbitrary OS commands as the web user, read application secrets and the database configuration, and pivot into the internal network.”
  • “With a free account, an attacker can execute code in the application server, access other tenants’ data, and establish persistence.”
  • “The code execution escapes the container to the host through the mounted Docker socket, giving full control of the node and every workload on it.”

Remediation guidance

Per class, the durable fix:

  • Command injection: do not build shell strings from input. Use argument arrays with shell=false, allowlist values, and avoid shelling out where a library call exists.
  • Code and expression injection: never evaluate untrusted input. Remove eval style sinks; use a safe parser or a fixed allowlist of operations.
  • Deserialization: do not deserialize untrusted data. Use data only formats (JSON without type binding), signed payloads, and allowlists of permitted classes.
  • SSTI: pass user data as template variables, never concatenate it into the template source. Use sandboxed or logicless templates.
  • File upload: validate on the server, store outside the webroot, serve from a path that does not execute, and generate random names with a fixed safe extension.
  • SSRF: allowlist destinations, block link local and internal ranges, and do not follow redirects to internal hosts.
  • LFI: allowlist includable files, never pass user input to include or file read without strict mapping.
  • SQLi: parameterized queries everywhere, least privilege DB accounts, and disable xp_cmdshell and risky file privileges.

Retest plan

  • Re run the exact PoC request and confirm it now fails.
  • Test a few bypass variants of the same class, since a narrow fix (blocking one character) often misses the root cause.
  • Confirm the fix is the right kind (parameterization, allowlist, removing the sink), not just a WAF rule.

Disclosure norms

  • Follow the program’s policy on scope, testing limits, and timelines.
  • Reference the Bugcrowd Vulnerability Rating Taxonomy (VRT) to align severity with the program, and HackerOne disclosure norms for coordinated timing.
  • Do not access more data than needed to prove impact. Stop at proof, document, and report.
  • Keep communication factual and professional.

Takeaway

Reproducible PoC, honest severity, clear impact, and an actionable fix. That is what turns a working exploit into a report that gets resolved. Back to the RCE methodology.