Skip to content

CVE-2025-0520: Verified Reproduction

CVE-2025-0520: ShowDoc Unauthenticated File Upload RCE via deprecated ThinkPHP syntax

CVE-2025-0520 is verified against showdoc/showdoc · github. Affected versions: ShowDoc versions before 2.8.7 (commonly referenced as <=2.8.6); Vulhub lab uses 2.8.2. Vulnerability class: RCE. This critical reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00132.

REPRO-2026-00132 showdoc/showdoc · github RCE Apr 14, 2026 CVE entry .txt
Severity
CRITICAL
CVSS
9.4
Reproduced in
139m 41s
Tool calls
526
01 · Overview

What Is CVE-2025-0520?

CVE-2025-0520 is a critical unauthenticated file-upload leading to remote code execution in ShowDoc. An attacker can upload a PHP webshell by bypassing the extension check. Pruva reproduced it (reproduction REPRO-2026-00132).

02 · Severity & CVSS

CVE-2025-0520 Severity & CVSS Score

CVE-2025-0520 is rated critical severity, with a CVSS base score of 9.4 out of 10.

CRITICAL threat level
9.4 / 10 CVSS base
Weakness CWE-434 — Unrestricted Upload of File with Dangerous Type

Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.

03 · Affected Versions

Affected showdoc/showdoc Versions

showdoc/showdoc · github versions ShowDoc versions before 2.8.7 (commonly referenced as <=2.8.6); Vulhub lab uses 2.8.2 are affected.

How to Reproduce CVE-2025-0520

$ pruva-verify REPRO-2026-00132
or curl -O https://www.pruva.dev/api/v1/reproductions/REPRO-2026-00132/artifacts/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2025-0520

Remote code execution — reproduced
  • reached the target end-to-end
  • full exploit chain demonstrated
  • on the real production code path
  • high confidence
  • the upstream fix blocks the same trigger
Trigger

multipart filename and PHP payload body

Attack chain
  1. PageController uploadImg invokes ThinkPHP Upload
  2. upload()
How the agent worked 639 events · 526 tool calls · 2h 20m
2h 20mDuration
526Tool calls
102Reasoning steps
639Events
5Dead-ends
Agent activity over 2h 20m
Support
11
Hypothesis
1
Repro
274
Judge
46
Variant
179
Coding
122
0:00139:41

Root Cause and Exploit Chain for CVE-2025-0520

Versions: ShowDoc before 2.8.7 (runtime validated on v2.8.2)
  • Affected versions: ShowDoc before 2.8.7 (runtime validated on v2.8.2)
  • Risk level: Critical
  • Consequences:
    • Unauthenticated attacker can upload executable PHP
    • Uploaded file is reachable from web path (/Public/Uploads/...)
    • Remote code execution in application context

Root Cause

In vulnerable code, uploadImg() configures ThinkPHP upload with:

  • $upload->allowExts = array('jpg','gif','png','jpeg');
  • then $info = $upload->upload();

On ThinkPHP 3.2+, allowExts is deprecated/ignored and the active key is exts. Because of this mismatch, intended extension restrictions are ineffective in the vulnerable path. A crafted filename (test.<>php) bypasses the simple .php substring check and results in a saved .php payload.

Fix commits:

  • fb77dd4db88dc23f5e570fc95919ee882aca520a: replaces allowExts with exts (upload blocked)
  • e1cd02a3f98bb227c0599e7fa6b803ab1097597f: adds early return false in uploadImg() (endpoint disabled)

Reproduction Steps

  1. Run repro/reproduction_steps.sh.
  2. The script:
    • clones ShowDoc and checks out three revisions: vulnerable v2.8.2, fixed fb77dd4, fixed e1cd02a
    • builds Docker runtime images (php:7.4-apache) for each revision
    • initializes each instance via install/non_interactive.php
    • sends real multipart POST to /index.php?s=/home/page/uploadImg with filename test.<>php
    • for vulnerable revision, requests the uploaded PHP and verifies execution marker
    • for fixed revisions, verifies upload rejection/disable behavior and absence of uploaded PHP
  3. Expected evidence:
    • vulnerable upload response contains success JSON + uploaded .php URL
    • vulnerable execution response contains RCE_OK_1e08f13e8e4695e97fef6d9de3665be4
    • fb77 shows 上传文件后缀不允许 and no uploaded PHP
    • e1cd returns empty response body and no uploaded PHP

Evidence

  • Execution logs:
    • logs/reproduction_run8.log
    • logs/reproduction_run9.log
  • Vulnerable artifacts:
    • repro/runtime_artifacts/http/vuln/upload_response.txt
    • repro/runtime_artifacts/http/vuln/uploaded_php_files.txt
    • repro/runtime_artifacts/http/vuln/webshell_exec_response.txt
    • repro/runtime_artifacts/http/vuln/container.log
    • repro/runtime_artifacts/http/vuln/controller_lines.txt
    • repro/runtime_artifacts/http/vuln/controller_upload_flow.txt
  • Fixed artifacts:
    • repro/runtime_artifacts/http/fb77/upload_response.txt
    • repro/runtime_artifacts/http/fb77/uploaded_php_files.txt
    • repro/runtime_artifacts/http/fb77/container.log
    • repro/runtime_artifacts/http/e1cd/upload_response.txt
    • repro/runtime_artifacts/http/e1cd/uploaded_php_files.txt
    • repro/runtime_artifacts/http/e1cd/container.log
  • Revision evidence:
    • repro/runtime_artifacts/http/vuln/revision.txt
    • repro/runtime_artifacts/http/fb77/revision.txt
    • repro/runtime_artifacts/http/e1cd/revision.txt
  • Summary artifact:
    • repro/runtime_artifacts/http/summary.txt

Recommendations / Next Steps

  • Upgrade to a fixed release (>= 2.8.7) or include both fixes (fb77dd4 and e1cd02a).
  • Keep upload endpoint authenticated or disabled if not required.
  • Enforce strict extension/MIME checks with current framework API (exts) and add server-level execution restrictions in upload directories.
  • Add regression tests for tricky filenames like test.<>php and other extension obfuscation inputs.

Additional Notes

  • Idempotency: confirmed. repro/reproduction_steps.sh was run twice consecutively (reproduction_run8.log, reproduction_run9.log) with successful reproduction and consistent vulnerable-vs-fixed behavior.
  • Limitation: requires Docker availability in the execution environment.

CVE-2025-0520 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:0010:14
0:00
session startedgpt-4o · CVE-2025-0520 · 6b0c23ce
0:38
web search
0:42
1:00
1:04
1:15
web search
1:20
1:38
1:41
2:26
extract_facts
no facts extracted
2:28
2:30
2:30
supportrepro
8:33
error

Unknown error

8:35
8:35
8:35
8:38
8:38
8:44
8:46
web search
8:52
8:54
8:58
9:04
$git clone --depth 1 https://github.com/vulhub/vulhub.git /tmp/vulhub 2>&1 | tail -5
6.5s
Cloning into '/tmp/vulhub'...
9:08
9:08
9:09
9:14
9:14
$docker ps 2>&1
0.2s
{"cwd":"/data/pruva/runs/6b0c23ce-21d5-489c-b632-93979a285c2b","duration_ms":185,"exit_code":0,"stderr":"","stdout":"CONTAINER ID   IMAGE                                  COMMAND                  CREATED         STATUS                   PORTS                                         NAMES\na0b5323ed02e   pruva-rs-pruva-worker-sandbox:latest   \"pruva-worker --back…\"   7 minutes ago   Up 7 minutes (healthy)                                                 pruva-rs-pruva-worker-kimi-k2p5-1\n30ca29941dbc   pruva-rs-pruva-worker-sandbox:latest   \"pruva-worker --back…\"   7 minutes ago   Up 7 minutes (healthy)                                                 pruva-rs-pruva-worker-glm-5p1-1\nc646475c0b52   pruva-rs-pruva-worker-sandbox:latest   \"pruva-worker --back…\"   7 minutes ago   Up 7 minutes (healthy)                                                 pruva-rs-pruva-worker-qwen3p6-plus-1\na9530c951be2   pruva-rs-pruva-worker-sandbox:latest   \"pruva-worker --back…\"   7 minutes ago   Up 7 minutes (healthy)                                                 pruva-rs-pruva-worker-minimax-m2p7-1\nd7cacc05a249   pruva-rs-pruva-api                     \"/app/pruva-api --po…\"   21 hours ago … [truncated]
9:53
9:53
#!/bin/bash
set -euo pipefail

# Portable paths - works from any directory
ROOT="${PRUVA_ROOT:-$(cd "$(dirname "$0")/.." && pwd)}"
LOGS="$ROOT/logs"
mkdir -p "$LOGS"
REPRO="$ROOT/repro"
mkdir -p "$REPRO"

cd "$ROOT"

echo "========================================="
echo "CVE-2025-0520 ShowDoc File Upload RCE Reproduction"
echo "========================================="

# Check Docker is available
if ! command -v docker &> /dev/null; then
    echo "ERROR: Docker is not available"
    exit 1
10:09
10:12
$git clone --depth 1 https://github.com/star7th/showdoc.git /tmp/showdoc 2>&1 | tail -3
2.0s
Cloning into '/tmp/showdoc'...
10:13
10:13
10:14
10:14

Artifacts and Evidence for CVE-2025-0520

Scripts, logs, diffs, and output captured during the reproduction.

repro/rca_report.md4.2 KB
repro/reproduction_steps.sh10.0 KB
coding/proposed_fix.diff0.9 KB
bundle/ticket.json1.9 KB
bundle/repro/judge_review.json1.0 KB
bundle/AGENTS.repro.md0.8 KB
bundle/ticket.md1.5 KB
repro/runtime_manifest.json1.1 KB
repro/runtime_artifacts/library_api_output.txt2.3 KB
repro/runtime_artifacts/http/fb77/container_id.txt0.1 KB
repro/runtime_artifacts/http/fb77/controller_lines.txt0.2 KB
repro/runtime_artifacts/http/fb77/healthcheck_http_code.txt0.0 KB
repro/runtime_artifacts/http/fb77/container.log0.8 KB
repro/runtime_artifacts/http/fb77/upload_response.txt1.7 KB
repro/runtime_artifacts/http/fb77/revision.txt0.0 KB
repro/runtime_artifacts/http/fb77/webshell_exec_response.txt0.0 KB
repro/runtime_artifacts/http/fb77/controller_upload_flow.txt1.9 KB
repro/runtime_artifacts/http/fb77/uploaded_php_files.txt0.0 KB
repro/runtime_artifacts/http/fb77/install_output.txt0.0 KB
repro/runtime_artifacts/http/fb77/request_metadata.txt0.1 KB
repro/runtime_artifacts/http/summary.txt0.7 KB
repro/runtime_artifacts/http/vuln/container_id.txt0.1 KB
repro/runtime_artifacts/http/vuln/controller_lines.txt0.2 KB
repro/runtime_artifacts/http/vuln/healthcheck_http_code.txt0.0 KB
repro/runtime_artifacts/http/vuln/container.log0.9 KB
repro/runtime_artifacts/http/vuln/upload_response.txt0.4 KB
repro/runtime_artifacts/http/vuln/revision.txt0.0 KB
repro/runtime_artifacts/http/vuln/webshell_exec_response.txt0.2 KB
repro/runtime_artifacts/http/vuln/controller_upload_flow.txt1.9 KB
repro/runtime_artifacts/http/vuln/uploaded_php_files.txt0.1 KB
repro/runtime_artifacts/http/vuln/install_output.txt0.0 KB
repro/runtime_artifacts/http/vuln/request_metadata.txt0.1 KB
repro/runtime_artifacts/http/e1cd/container_id.txt0.1 KB
repro/runtime_artifacts/http/e1cd/controller_lines.txt0.2 KB
repro/runtime_artifacts/http/e1cd/healthcheck_http_code.txt0.0 KB
repro/runtime_artifacts/http/e1cd/container.log0.8 KB
repro/runtime_artifacts/http/e1cd/upload_response.txt0.3 KB
repro/runtime_artifacts/http/e1cd/revision.txt0.0 KB
repro/runtime_artifacts/http/e1cd/webshell_exec_response.txt0.0 KB
repro/runtime_artifacts/http/e1cd/controller_upload_flow.txt1.9 KB
repro/runtime_artifacts/http/e1cd/uploaded_php_files.txt0.0 KB
repro/runtime_artifacts/http/e1cd/install_output.txt0.0 KB
repro/runtime_artifacts/http/e1cd/request_metadata.txt0.1 KB
repro/runtime_artifacts/library_api_success.txt0.0 KB
repro/validation_verdict.json0.7 KB
logs/clone_showdoc.log0.1 KB
logs/reproduction_run1.log0.3 KB
logs/docker_build_vuln.log0.9 KB
logs/reproduction_run6.log0.3 KB
logs/reproduction_run3.log0.3 KB
logs/docker_build_fb77.log0.9 KB
logs/git_checkout_vuln.log0.6 KB
logs/git_checkout_e1cd.log0.6 KB
logs/reproduction_run4.log0.3 KB
logs/reproduction_run7.log0.3 KB
logs/reproduction_run2.log0.3 KB
logs/git_checkout_fb77.log0.6 KB
logs/reproduction_run5.log0.3 KB
logs/phpserver_vuln.log1.0 KB
logs/fetch_showdoc.log0.0 KB
logs/reproduction_run8.log0.3 KB
logs/reproduction_run9.log0.3 KB
logs/docker_build_e1cd.log0.9 KB
logs/vuln_variant_e1cd_install_probe2.log0.0 KB
logs/vuln_variant_e1cd_login_probe.json0.1 KB
logs/vuln_variant_e1cd_install_probe.log0.0 KB
coding/verify_logs/base/container_id.txt0.1 KB
coding/verify_logs/base/health_http_code.txt0.0 KB
coding/verify_logs/base/seed_item_output.txt0.0 KB
coding/verify_logs/base/uploaded_phtml_files.txt0.1 KB
coding/verify_logs/base/container.log0.9 KB
coding/verify_logs/base/phtml_count.txt0.0 KB
coding/verify_logs/base/upload_response.txt0.4 KB
coding/verify_logs/base/all_uploaded_files.txt0.1 KB
coding/verify_logs/base/install_output.txt0.0 KB
coding/verify_logs/base/login_response.txt0.7 KB
coding/verify_logs/build_patched.log0.9 KB
coding/verify_logs/patch_apply.log0.1 KB
coding/verify_logs/summary.txt0.4 KB
coding/verify_logs/build_base.log0.9 KB
coding/verify_logs/git_checkout_base.log0.6 KB
coding/verify_logs/git_checkout_patched.log0.6 KB
coding/verify_logs/patched/container_id.txt0.1 KB
coding/verify_logs/patched/health_http_code.txt0.0 KB
coding/verify_logs/patched/seed_item_output.txt0.0 KB
coding/verify_logs/patched/uploaded_phtml_files.txt0.0 KB
coding/verify_logs/patched/container.log0.9 KB
coding/verify_logs/patched/phtml_count.txt0.0 KB
coding/verify_logs/patched/upload_response.txt0.5 KB
coding/verify_logs/patched/all_uploaded_files.txt0.0 KB
coding/verify_logs/patched/install_output.txt0.0 KB
coding/verify_logs/patched/login_response.txt0.7 KB
coding/verify_logs/git_clone.log0.1 KB
coding/verify_fix.sh6.0 KB
coding/summary_report.md2.4 KB
08 · How to Fix

How to Fix CVE-2025-0520

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2025-0520 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2025-0520

Is CVE-2025-0520 exploitable without authentication?

Yes. The uploadImg endpoint accepts the crafted file without authentication, so a remote attacker can drop and execute a PHP webshell on the server.

Which versions of ShowDoc are affected by CVE-2025-0520?

ShowDoc versions before 2.8.7 (commonly referenced as <= 2.8.6) are affected; the reproduction uses 2.8.2. Upgrade to 2.8.7 or later.

How can I reproduce CVE-2025-0520?

Download the verified script from this page and run it in an isolated environment against ShowDoc < 2.8.7. It POSTs a file named like test.<>php to /index.php?s=/home/page/uploadImg and shows the stored PHP executing from Public/Uploads.
11 · References

References for CVE-2025-0520

Authoritative sources for CVE-2025-0520 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.