カー用品のソフト99コーポレーションが、2026年11月10日に公式オンラインショップへの不正アクセスを公表しました。お問合せフォームの画像添付機能からプログラムファイルを置かれ、そこから外部の命令でサーバー内を調べられたという内容です。漏えいの可能性があるのは最大136,968人で、氏名や住所に加えてクレジットカードの下4桁・有効期限・名義人も含まれます。前半は公表文で分かる経緯と項目、窓口、届いた連絡の見分け方です。後半は、画像添付を受け取る側でファイルを確かめるPythonの例と、アップロード先でプログラムを動かさないNginxの設定を載せます。
まとめ:ソフト99の不正アクセスで分かっていることと、利用者・EC運営者が今やること
ソフト99の公表文によると、11月5日に委託先から「不審な動きがある」と連絡があり、調べた結果、画像添付機能を足がかりにした侵入が分かりました。オンラインショップは止めてあり、アクセス経路も遮断済みです。
| 項目 | 公表文の記載(11月10日時点) |
|---|---|
| 発覚 | 2026年11月5日・委託先からの連絡 |
| 侵入の入口 | お問合せフォームの画像添付機能 |
| 件数 | 最大136,968人(対象と件数は確認中) |
| 対象 | 11月5日までに会員登録・購入した人 |
| カード情報 | 下4桁・有効期限・名義人など |
| 報告 | 11月9日に個人情報保護委員会へ |
利用者がやることは2つです。ソフト99を名乗るメール・SMS・電話には応じず、添付やリンクも開かない。カードの利用明細を、次の請求から数か月は見続ける。自社のECサイトに問い合わせフォームの添付機能があるなら、受け取ったファイルの置き場所と、そこでプログラムが動かない設定かを今週中に確かめてください。
公表文で分かる範囲:11月5日の委託先の連絡から11月10日の公表までの経緯
委託先の連絡で発覚した不審な動きと、ショップの一時停止・経路の遮断
発覚のきっかけは、ショップの運用を担う委託先からの連絡でした。11月5日に不審な動きを伝えられ、委託先が調べたところ、外部の第三者がお問合せフォームの画像添付機能からプログラムファイルをアップロードしていたと分かりました。
ソフト99はショップを一時停止し、アクセス経路を遮断しています。アクセス制限も強めました。外部のセキュリティ専門家への調査依頼は「予定」の段階で、原因と影響範囲は委託先と調べている最中です。二次被害は確認されていないとしています。
ショップのシステム名、委託先の社名、置かれたファイルの種類は書かれていません。この記事でも推測では埋めません。
最大136,968人という件数と、11月5日までの会員登録・購入という範囲
対象は、11月5日までに会員登録をした人と、買い物をした人です。会員登録をせずに購入した人も、文面上は対象に入ると読めます。
136,968人は「最大」の数字です。公表文は、対象となる会員と件数の詳細をまだ確認中としています。続報で減ることも、内訳が分かれることもありえます。公表文の範囲では、11月5日より後に初めて登録・購入した人は対象に含まれていません。
漏えいのおそれがある項目:カード下4桁・有効期限と、利用者が確かめること
氏名・住所・購買情報・お届け先と、カード情報3項目の扱いの違い
公表文が挙げる項目は次のとおりです。最後が「等」で終わっているので、これで全部とは限りません。
- 氏名、住所、メールアドレス、電話番号、生年月日、性別
- 購買情報、お届け先情報
- クレジットカード情報のうち、カード番号の下4桁、有効期限、カード名義人
カード番号の全桁とセキュリティコードは、項目に挙がっていません。下4桁と有効期限だけで決済はできないので、カードの再発行を急ぐ段階ではありません。注意したいのは別の使われ方です。「末尾1234のカードで不審な決済がありました」のように本物の数字を添えた偽の連絡は、受け取った側が信じやすくなります。購買情報やお届け先が組み合わされば、なおさらです。
窓口0120-342-199と、ソフト99を名乗るメール・SMS・電話の見分け方
問い合わせ窓口は0120-342-199(通話料無料)で、受付は平日9:00〜17:30です。土日祝日と年末年始・夏季休業は除かれます。非通知で発信すると折り返しができないため、公表文は番号の前に186を付けるよう求めています。メールは[email protected]です。
公表文は、心当たりのないメール・SMS・電話に応じないこと、添付を開かずリンクを押さず返信もしないこと、ソフト99を装う偽サイトやSNSアカウントにID・パスワード・カード情報を入れないことを呼びかけています。判断の基準は単純です。受け取った連絡に書かれた番号やURLは使わない。上の窓口や、カード裏面の番号へ自分からかけ直してください。偽の連絡の典型と見分け方はフィッシングの手口と見分け方にまとめています。
侵入の経路:お問合せフォームの画像添付からプログラムファイルが置かれた仕組み
CWE-434「危険な種類のファイルの無制限アップロード」に当たる弱点
画像を受け付けるはずの入口にプログラムを置ける状態は、脆弱性の分類でCWE-434(Unrestricted Upload of File with Dangerous Type)と呼ばれます。よくある原因は次の4つです。
- 拡張子を禁止リストで弾いており、
.phtmlや二重拡張子をすり抜けられる - ブラウザが送るContent-Typeを信じて「画像」と判定している
- 利用者が付けたファイル名のまま、公開ディレクトリに保存している
- 保存先のディレクトリで、サーバーがプログラムとして実行できてしまう
OWASPのFile Upload Cheat Sheetは、Content-Typeは利用者が送る値で偽装がたやすく、信頼できないと書いています。拡張子は許可リストで絞り、保存名はUUIDなどで作り直し、置き場所は別サーバーか公開領域の外にする、というのが同書の基本線です。ソフト99のフォームがどの条件に当たったかは公表されていません。
置かれたファイルが命令を受け付け、設定ファイルの読み取りへ進む流れ
公表文は、置かれたファイルを使って外部から命令を送り込み、サイトのプログラムの権限でサーバー内を調べ、設定ファイルを読んだと説明しています。外から命令を受けて動くこの種のファイルは、一般にWebシェルと呼ばれます。仕組みと検知・除去のコマンドはWebシェルの仕組みと検知・除去の手順で扱いました。
設定ファイルが読まれたという点は軽く見られません。ECサイトの設定ファイルには、データベースの接続先・ユーザー名・パスワードが書かれていることが多いからです。それが読めれば、会員テーブルまでは一歩で届いてしまいます。問い合わせフォームという会員機能と無関係に見える入口から、会員全体の情報に届いたのが本件の構造です。
画像添付を受け取る側の実装:拡張子・先頭バイト・再エンコードを重ねるPythonの例
許可リスト・先頭バイト・Pillowの形式確認とUUIDの保存名への置き換え
OWASPの推奨を、問い合わせフォームの画像添付に当てはめたのが次のコードです。Pillowで画像として開けるかを確かめ、通ったものだけ描き直して保存します。Image.verify()は検証の後に開き直す必要があると公式に書かれているので、2回開いています。
# 問い合わせフォームの画像添付を受け取る側の検証(Python 3.10以上・Pillow 10以上)
import sys
import uuid
from pathlib import Path
from PIL import Image
ALLOWED = {"jpg": "JPEG", "jpeg": "JPEG", "png": "PNG"} # 拡張子と実際の形式の許可リスト
MAX_BYTES = 5 * 1024 * 1024 # 5MB
MAX_PIXELS = 4000 * 4000 # 展開後の画素数の上限
SIGNATURES = {"JPEG": b"\xff\xd8\xff", "PNG": b"\x89PNG\r\n\x1a\n"}
def accept_image(src: Path, store_dir: Path) -> Path:
"""検査に通った画像だけを、再エンコードして公開領域の外へ保存する。"""
name = src.name
if name.count(".") != 1 or ":" in name:
raise ValueError("二重拡張子・コロンを含む名前は拒否")
ext = name.rsplit(".", 1)[1].lower()
if ext not in ALLOWED:
raise ValueError(f"許可していない拡張子: {ext}")
if src.stat().st_size > MAX_BYTES:
raise ValueError("サイズ超過")
head = src.read_bytes()[:8]
expected = ALLOWED[ext]
if not head.startswith(SIGNATURES[expected]):
raise ValueError("先頭のシグネチャが拡張子と合わない")
with Image.open(src) as im:
im.verify() # 壊れたファイルを弾く(verify後は再オープンが必要)
with Image.open(src) as im:
if im.format != expected:
raise ValueError(f"中身の形式が {im.format}")
if im.width * im.height > MAX_PIXELS: # 展開前に寸法で弾く
raise ValueError("画素数の上限超過")
clean = im.convert("RGB") if expected == "JPEG" else im.copy()
store_dir.mkdir(parents=True, exist_ok=True)
dest = store_dir / f"{uuid.uuid4().hex}.{ext}" # 利用者のファイル名は使わない
clean.save(dest, format=expected) # 再エンコードで末尾の付加データを落とす
dest.chmod(0o640) # 実行権限を付けない
return dest
if __name__ == "__main__":
store = Path(sys.argv[1])
for p in sys.argv[2:]:
try:
print("OK ", Path(p).name, "->", accept_image(Path(p), store).name)
except Exception as e:
print("NG ", Path(p).name, ":", e)
画素数の上限は、PillowのMAX_IMAGE_PIXELS任せにせず自前で判定しています。Pillowはこの値を超えても2倍までは警告を出すだけで、例外にならないためです。store_dirには、Webサーバーが配信しないディレクトリを渡します。
模擬ファイル8件で確かめた判定と、末尾の付加データが消えることの確認
Python 3.14.10・Pillow 13.0.0で、Pillowで作った無害な模擬ファイル8件に対して2026年11月11日に実行した結果です(保存名のUUIDは省略)。
$ python upload_check.py store in/photo.jpg in/screen.png in/fake.jpg in/note.php \
in/photo.php.jpg in/anim.png in/huge.png in/tail.jpg
OK photo.jpg -> 0683cdda....jpg
OK screen.png -> 7478319....png
NG fake.jpg : 先頭のシグネチャが拡張子と合わない
NG note.php : 許可していない拡張子: php
NG photo.php.jpg : 二重拡張子・コロンを含む名前は拒否
NG anim.png : 先頭のシグネチャが拡張子と合わない
NG huge.png : 画素数の上限超過
OK tail.jpg -> aeda06f4....jpg
fake.jpgはテキストに拡張子jpgを付けたもの、anim.pngはGIFに拡張子pngを付けたもの、huge.pngは5000×4000画素のPNGです。tail.jpgは正常なJPEGの末尾に文字列を足したもので、検査は通ります。ただし保存後のファイルを調べると、足した文字列は残っていませんでした(5,451バイトから5,429バイト)。描き直して保存する工程が、画像の外側に隠したデータを落としたことになります。
OWASPは、描き直しても悪性の中身が全て消える保証はないとも書いています。このコードは入口の一枚目であり、次の設定と組み合わせて使います。
Nginxでアップロード先のスクリプト実行を止める設定と、公開領域の外への配置
既存のサイトで、添付ファイルを公開ディレクトリに置く作りをすぐには変えられない場合の応急策です。Nginxのlocationは、前方一致に^~を付けると、一致したときに正規表現のlocationを確かめません。これを使い、PHPへ渡す設定がアップロード先に効かないようにします。
# /uploads/ 配下ではスクリプトとして扱わず、拡張子がPHP系なら403を返す
location ^~ /uploads/ {
location ~* \.(php|phtml|phar|pht)$ {
return 403;
}
add_header X-Content-Type-Options nosniff;
}
この設定は公式ドキュメントの仕様に沿って書いたもので、手元のNginxで起動確認はしていません。入れる前にnginx -tで構文を確かめ、検証環境で/uploads/配下のPHPファイルに403が返ることを見てください。根本の対策は、添付ファイルを公開ディレクトリに置かないことです。ApacheやIISでも、アップロード先でスクリプトを動かさない設定を同じ考え方で入れられます。
個人情報保護委員会への報告:11月9日の報告と、不正の目的による漏えいのおそれ
件数を問わず報告対象となる類型と、確報を60日以内に出す期限
ソフト99は、公表の前日にあたる11月9日に個人情報保護委員会へ報告しています。個人情報保護法のガイドライン(通則編)では、不正アクセスのように不正の目的で行われた漏えいは、「おそれ」の段階でも件数を問わず報告の対象です。速報は把握から3〜5日以内が目安で、この類型の確報は60日以内に出します。
発覚が11月5日、報告が11月9日なので、速報の目安の範囲に収まっている日程です。確報では原因や再発防止策の記載が求められるため、侵入の詳しい経路は確報の前後で公表文に追記される可能性があります。報告の流れと様式は個人情報保護委員会への報告義務の実務で、委員会の資料は漏えい等の対応のページで確かめられます。
判断:委託先に任せたECサイトで自社が確かめる範囲と、診断に出す条件
委託契約で確かめるアップロード機能・ログの保存・連絡の取り決め
本件では、異常に気付いたのは委託先でした。ECサイトの運用を外に任せている企業は、少なくとも次の点を委託先に聞いて答えをもらってください。重い順に並べています。
- 問い合わせフォームや会員画面で、ファイルを受け付ける機能がどこにあるか。受け取ったファイルの保存先と、そこでプログラムが動かない設定になっているか
- アップロードの記録とWebサーバーのアクセスログを何日残しているか。侵入が分かったとき、いつから置かれていたかを追える長さか
- 不審な動きを見つけたとき、何時間以内に誰へ連絡するか
- 設定ファイルにデータベースのパスワードを平文で書いていないか
1と2に答えられない委託先なら、その時点で点検を頼む理由になります。管理画面や共通基盤から他社のサイトへ被害が広がった例はスカラコミュニケーションズの事案、アップロード機能から決済画面が改ざんされた例はPhotoGoodsの事案で整理しています。
問い合わせフォームに添付機能を残さない場面と、第三者診断に出す範囲
添付ファイルを受け付けなくても問い合わせの用が足りるなら、機能ごと外すのが一番安く確実です。商品の不具合を写真で受けたいといった理由がない限り、会員データと同じサーバーで、匿名の誰でも使えるフォームにファイル添付を付ける構成は採らないと決めてしまってかまいません。
残す場合は、受け付けた画像を別のストレージへ逃がし、Webサーバーとデータベースの権限から切り離します。そのうえで、ファイルアップロード・設定ファイルの置き場所・データベース接続の権限をまとめて第三者に見てもらうのが近道です。ログイン画面やAPIの入口の固め方はAPI不正アクセス対策の実装手順を参照してください。委託先任せのサイトを外から確かめたい場合は、一創の脆弱性診断・セキュリティ診断でアップロード機能を含めた診断を受け付けています。これから作り直す場合は、ECサイトの要件定義の非機能要件に、添付ファイルの扱いを最初から書き込んでおくと後戻りが減ります。
よくある質問
ソフト99の不正アクセスについて、利用者と開発者から出やすい質問に、11月10日の公表文の範囲で答えます。
ソフト99のオンラインショップを使ったことがあります。自分は対象ですか?
2026年11月5日までに公式オンラインショップで会員登録をしたか、買い物をした人が対象です。最大136,968人とされていますが、対象となる会員と件数の詳細はまだ確認中です。個別の該当を知りたい場合は、窓口の0120-342-199(平日9:00〜17:30)か、[email protected]へ問い合わせてください。非通知の電話は折り返しができないため、186を付けて発信します。
クレジットカードは止めたほうがよいですか?
公表文が挙げるカード情報は、番号の下4桁・有効期限・名義人です。全桁の番号とセキュリティコードは項目に入っていないため、これだけで決済に使われる可能性は低いといえます。再発行を急ぐより、利用明細を数か月見続け、身に覚えのない請求があればカード会社へ連絡してください。下4桁を添えた偽の連絡には注意が必要です。
ソフト99からメールや電話が来ました。本物か確かめる方法は?
連絡に書かれた番号やURLは使わず、公表文に載っている窓口へ自分からかけ直して確かめます。公表文は、心当たりのないメール・SMS・電話に応じないこと、添付を開かずリンクを押さないこと、ソフト99を装う偽サイトやSNSアカウントにID・パスワード・カード情報を入れないことを呼びかけています。
画像添付だけの問い合わせフォームで、なぜサーバー全体が危なくなるのですか?
画像のふりをしたプログラムを置けて、それがサーバー上で動く設定だと、外から命令を送って動かせるようになるためです。プログラムはサイトと同じ権限で動くので、設定ファイルに書かれたデータベースの接続情報も読めます。本件でも、サーバー内の調査と設定ファイルの読み取りが行われたとされています。
自社のECサイトに同じ弱点がないか、まず何を見ればよいですか?
ファイルを受け付ける画面を洗い出し、受け取ったファイルの保存先を確かめます。保存先がブラウザから直接開ける場所で、しかもそこでPHPなどが動くなら、本件と同じ形です。拡張子を禁止リストで弾いているだけの場合や、利用者が付けたファイル名で保存している場合も、OWASPの推奨から外れています。自社で判断できなければ、診断を依頼する対象にしてください。
関連記事
- Webシェルとは?仕組み・代表例と検知・除去の手順をTomcat・PHP・IISのコマンド例で解説:置かれたファイルを見つけて取り除く手順
- PhotoGoodsの不正アクセスとカード情報漏えい|決済画面の改ざんとアップロード機能の締め方:アップロード機能から決済画面まで届いたEC事案
- API不正アクセス対策の実装手順:JPCERT注意喚起に沿うレート制限・認可・トークン失効とアプリ解析・SSRF対策:顧客向けシステムの入口を固める実装
- 個人情報保護委員会への報告義務|対象4類型・速報3〜5日と確報30日の実務:漏えいのおそれがあるときの報告の流れ
- フィッシングとは?手口の種類・見分け方と企業が取るべき組織的対策を解説:事件の後に届く偽の連絡の見分け方