ITmedia NEWSにて気になる記事があり、アップロード機能で情報漏洩できてしまうインシデントが取り上げていました。
開発者であれば割とやってしまう可能性が高い事例だったので、これについての対処方法についてまとめていきたいと思います。
ITmedia NEWSでの概要
アップロード機能を付けたときに、どんなファイルでもアップロードできてしまうインシデントについて取り上げています。
phpファイルをアップロードし、そこから情報を取得できてしまい、情報漏洩してしまうことを指摘されています。
これに対しての具体的な例と対処方法についてまとめていきます。
問題であるアップロード機能を作ってみる
inputタグでtypeをfileを指定する
<input type="file">
なんでもアップロードできると問題あり
多くは画像や動画などをアップロードするイメージがありますが、この状態だとなんでもアップロードできてしまいます。
実行ファイルやExcel、PowerPointなど様々です。
アップロードしたphpファイルを実行できてしまう
ITmedia NEWSで取り扱っているのはphpファイルをアップロード後にコマンド実行できてしまうことです。
例えば以下のようなtest.phpを作成し、アップロードします。
そしたらアップロードされた場所をブラウザで開くと、PHPの設定情報が出力されます。
<?= phpinfo() ?>
サーバー内のデータにアクセスでき、情報漏洩や削除ができてしまう
ユーザーが操作することないサーバー内のデータにアクセスできてしまうため、機密情報が取得できてしまったり、最悪削除することもで出来てしまいます。
なんでもアップロードしないようにする対処方法
acceptでアップロードするファイルを絞り込む
inputタグにはacceptを設定することでアップロードするファイルを絞り込むことができます。
ただこれだとすべてのファイルに戻すことでなんでもアップロードできてしまいます。
ファイルを選択したタイミングで絞り込む
inputタグが変わったタイミングで発火するようにし、ファイルがあれば判別していきます。
アップロードできる拡張子を配列extensionsに格納し、増減してもいいようにしております。
今回はpngとjpegのみアップロードできるようにし、アップロードできないかどうかを変数isNotExtensionで判別しています。
const filterAccept = () => {
const extensions = ['png', 'jpeg'];
document.querySelector('input')?.addEventListener('change', (event) => {
const {files} = event.target;
for (const file of files) {
const {name, size, type} = file;
const isNotExtension = !extensions.some((v) => type.includes(v));
if (isNotExtension) {
alert(`${name}はアップロードできません。`);
document.querySelector('input').value = '';
return;
}
}
});
}
あとはaddEventListenerで作成した関数filterAcceptを呼び出すだけでよいです。
window.addEventListener('load', () => {
filterAccept();
});
その他に容量チェックもする必要あり
アップロードする容量を制限した方がよいです。
1GBの画像がアップロードできてしまうとサーバーの容量が圧迫されてしまい、それが複数回やられてしまうと最悪サーバーが止まってしまいます。
先ほどのソースにあったsizeがそのままファイル容量(byte)なのですが、少しわかりづらいのでMBに変換します。
1KB = 1000byte、1MB = 1000KBなので、1000を2回割るとMBで出すことができます。
const {name, size, type} = file;
const mb = size / 1000 / 1000;
そして 10MBを超えた場合は同じようにアラートを出してアップロードできないようにします。
if (mb > 10) {
alert(`${mb}MBで10MB越えているので、アップロードできません。`);
document.querySelector('input').value = '';
return;
}
まとめ
アップロード機能で情報漏洩できてしまうインシデントについて、対処方法についてまとめました。
phpファイルをアップロード後に実行して情報漏洩してまう事例のため、アップロードできるファイルを絞り込む必要があります。
実装する際は必ずアップロードできるものを絞るように心掛けてください。