OpenDolphin は『真正性』すら満たしていないかもしれない

以前にもサーバの API を通して偽造カルテをデータベースに入れ込む、みたいなことをやったのだが、

今度はもうちょっと巧妙なカルテの改竄(対策)を考えてみる。

OpenDolphin では、hibernate というORMを使って、「カルテを修正したときは、元のバージョンは消去せず、必ず新しいバージョンを作る」ということで改竄を防止している。
なのだが、これは「データベースにアクセスするときは hibernate を使う」というのが大前提になっている。
実際のカルテ実体のデータは、データベースの blob 領域というところに保存されている。当たり前だが blob オブジェクトには hibernate を使わずともアクセスできる

最も単純な例を考えてみよう。
id=11 のレコードに blob で test と書き込む。

ところが、このときの oid(lob への一種のポインタみたいなものです)は、データベースに直接問い合わせることで知ることができる。

このときは 47410。

この値を使って、blob を書き換えることは可能だ。
‘test’ は16進数表記だと 0x74657374 になるのだが、これを 0x74747474 に変更する。
hibernate を使って id=11 のレコードを再度復元すると該当する blob は ‘tttt’ (0x74747474)となっている。

実際は、blob を書き換えた時に oid も変更されてしまうので(47410 → 47412 に変化している)、よくできた管理者であれば、この異常に気がつくと思うが、そうでない人ならば、改竄されたところで気がつきもしないだろう。

OpenDolphin はソースコードが公開された時点では「データ構造が複雑なので、真正性は担保されている」みたいなことが言われていたが、データ構造が複雑だからといって、それは解読不能ということでも、想定していた方法以外での操作が不可能ということでもない。

思うのだが、データベースなどの何らかのストレージに医療記録を平文で「普通」に記録する方式はもうそろそろ限界なのかもしれない。

かといって、ブロックチェーンみたいな話をいきなりされてもなあ。。。という感じで、ここら辺は難しいところですね。


ところで先ほど openEHR というオープンソースの EHR のサイトを覗いてきたが、ここら辺は配慮がされているようで、記録は persistence layer という一種の抽象化されたレイヤーを通して行うようだ。
要するに永続化の手段まで具体的に決めてしまうと、そのセキュリティホールを突いて記録を改竄する輩が出てくるため、特定のストレージに限定しないということなのだろう。

ところで、openEHR はけっこう間違った情報が流れているみたいですね。よく PHP で書かれて、みたいな紹介のされ方しているが、普通に Java コードも確認できたけど?

 

猪股弘明

 

Java hibernate を利用した PotsgreSQL LOB の取り扱い

以前に OpenDolphin-2.7m という電子カルテのプロジェクトをやっていたとき、ユーザー(大半は医師の方々)の理解がアヤしいと感じた箇所は LOB のあたり。

一般的に『データベース=巨大なエクセル』みたいな説明がなされているので、「電子カルテの実体は LOB 領域に永続化されています」と言って即座に理解できる医師はそう多くなかった。

OpenDolphin 自体のデータ構造がかなりわかりにくく、コーディングもかなり「正統派」スタイルだったため、敷居が高かったせいもあるのかもしれない。

PostgreSQL の LOB に関しては、sql ・jdbc などのドライバ・ORM (Java であれば hibernate)などを介して操作できる。

プログラミング言語を介して LOB を操作するのであれば、やはり ORM を使うのが一番楽だと思う。

最もシンプルな書き方は以下の通り。


@Entity
public class Lobs implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String content;
    
    @Lob
    private byte[] binarylob;
        
    @Lob
    private String charlob;

    (以下、セッター・ゲッターなどを定義)

適当な名前の String と byte[] を用意して @Lob アノテーションを付ければ、hibernate はこれを LOB (それぞれ clob, blob になる)として取り扱ってくれる。

プロジェクトが適切に構成されていれば、アプリ起動時に hibernate は class Lobs に対応したテーブル lobs を自動で作成してくれる。

実際に得られたテーブルは以下の通り。

この書き方だと

・blob, clob とも oid 型になる

・String は character varying(255) となる

のが「へえ」という感じだ。

 

次回は、lob の書き込み/読み込みの具体的な方法あたり。

 

猪股弘明

 

保護中: tomcat FAQ

このコンテンツはパスワードで保護されています。閲覧するには以下にパスワードを入力してください。