1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【セキュリティ】Hospital Management System の Stored XSS を解説

1
Last updated at Posted at 2025-12-16

はじめに

— なぜ “動いているコード” は危険なのか

Hospital Management System は、数年前に公開された PHP ベースの Web アプリケーションです。
機能的には問題なく動作しますが、セキュリティ更新が一切行われていないという、ある意味とても“教育的”な状態にあります。

その結果、Stored XSS(永続型 XSS) が発見され、
CVE-2021-38757 として登録されました。

しかもこの脆弱性、
いまだに未修正です。


CVE-2021-38757 とは?

  • 種類: Stored Cross-Site Scripting
  • 影響範囲: Receptionist(管理者)アカウント
  • 難易度: 極めて低い
  • 再現性: 100%

なぜ危険か?

  • 攻撃者は ログイン不要
  • Contact フォームに payload を送るだけ
  • 管理者がログインした瞬間に JS 実行

つまりこれは:

「患者の問い合わせが、管理者をハッキングする」脆弱性

です。


脆弱な機能:Contact フォーム

攻撃は非常にシンプルです。

  1. Contact ページを開く
  2. 適当に情報を入力
  3. Message 欄に以下を入力:
<script>alert(document.cookie)</script>
  1. 送信
  2. 管理者(Receptionist)がログイン
  3. XSS 発動

問題の核心:contact.php

脆弱性の根本原因は、以下のコードです。

<?php 
$con=mysqli_connect("localhost","root","","myhmsdb");
if(isset($_POST['btnSubmit']))
{
    $name = $_POST['txtName'];
    $email = $_POST['txtEmail'];
    $contact = $_POST['txtPhone'];
    $message = $_POST['txtMsg'];

    $query="insert into contact(name,email,contact,message) 
            values('$name','$email','$contact','$message');";
}

何が問題か?

1. ユーザー入力を そのまま DB に保存
  • HTML / JavaScript を一切無加工で保存
  • XSS payload が永続化される
2. SQL を文字列連結で生成
  • SQL Injection も同時に成立
  • つまり 二重で危険

なぜ「入力チェック」だけではダメなのか?

よくある誤解:

<script> を弾けばいいのでは?」

答え:ダメです

理由:

  • <img onerror=...>
  • <svg onload=...>
  • <details ontoggle=...>

HTML は逃げ道だらけ。
入力時フィルタリングは補助輪でしかない


正しい修正方針

原則はこの2つだけ

対策 目的
Prepared Statement SQL Injection 防止
Output Escaping Stored XSS 防止

修正①:Prepared Statement(SQLi対策)

<?php
$con = new mysqli("localhost", "root", "", "myhmsdb");
$con->set_charset("utf8mb4");

if (isset($_POST['btnSubmit'])) {
    $name    = $_POST['txtName'];
    $email   = $_POST['txtEmail'];
    $contact = $_POST['txtPhone'];
    $message = $_POST['txtMsg'];

    $stmt = $con->prepare(
        "INSERT INTO contact (name, email, contact, message) VALUES (?, ?, ?, ?)"
    );
    $stmt->bind_param("ssss", $name, $email, $contact, $message);
    $stmt->execute();
}

これで SQL Injection は終了


修正②:出力時エスケープ(XSS対策)

管理画面側で必ずエスケープします。

<?php
function e($s) {
    return htmlspecialchars($s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}

echo e($row['message']);

これだけで:

<script>alert(1)</script>

&lt;script&gt;alert(1)&lt;/script&gt;

になり、ただの文字列になります。


Stored XSS が特に危険な理由

種類 特徴
Reflected XSS 被害は一時的
Stored XSS 永続・自動・管理者直撃

Stored XSS は:

  • 攻撃者が離脱しても
  • 管理者が後から踏む
  • 最悪、全権限乗っ取り

という「時限爆弾型」です。



まとめ

  • CVE-2021-38757 は 典型的だが致命的な Stored XSS
  • 原因は:
    • 入力の無検証保存
    • 出力時エスケープ不在
  • 修正は難しくない
  • 難しくないからこそ、放置は罪

https://www.cve.org/CVERecord?id=CVE-2021-38757
https://github.com/kishan0725/Hospital-Management-System
https://packetstorm.news/files/id/163869

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?