ヤマダデンキは2026年11月13日、リフォーム管理システムが第三者からの不正アクセスを受け、氏名・住所・電話番号とリフォーム実施履歴・見積データ等の営業記録が最大350万件影響を受けた可能性があると公表しました。外部への流出は調査中です。この記事では、公表で確定した事実と未公表の範囲を分け、同じ時期に公表された別の2件との違いを整理します。そのうえで示すのは、住所と工事の履歴が一緒に出たときに想定される点検商法やなりすまし連絡への備えです。後半は顧客管理・営業管理システムを持つ開発者向けに、店舗単位のアクセス権、監査ログからの大量閲覧の検知、見積だけで終わった顧客の消去バッチを、実行できるPythonのコード付きで解説します。
まとめ:ヤマダデンキのリフォーム管理システム不正アクセスの事実と、営業記録を持つ側の作業
確定しているのは、11月12日に不正アクセスを確認して外部からのアクセスを遮断したこと、影響を受けた可能性のある情報が最大350万件であること、マイナンバーとクレジットカード情報は含まれないことの3点です。外部へ流出したかどうか、原因、侵入経路は公表されていません。
リフォームを依頼したり見積を取ったりした人は、ヤマダデンキを名乗る訪問・電話・SMSに注意します。住所と工事の履歴がそろうと、「前回の工事の点検」をうたう連絡がもっともらしく聞こえるからです。
顧客の住所と履歴を持つシステムの開発者が自社で確かめる作業は、優先度の高い順に次の4つです。
- 担当者が自分の店舗・自分の案件以外の顧客を読めない状態になっているかを確かめる
- 1つのアカウントが平常時の何倍もの顧客を開いたり出力したりしたら気付ける監査ログを持つ
- 見積だけで終わった顧客の住所と電話番号を、期限を決めて消す
- 漏えい時の報告の期限と、顧客への注意喚起の文面を先に用意する
件数を小さくする手段は1つ目と3つ目です。
11月13日の公表で確定した最大350万件の項目と、流出の有無など未公表の範囲
11月12日の不正アクセス確認から外部アクセスの遮断・詳細調査までの経緯
ヤマダデンキの11月13日の公表によると、同社は11月12日にリフォーム管理システムへの不正アクセスを確認し、ただちに外部からのアクセスを遮断して詳細調査を始めました。公表文に書かれた経緯はこの1行だけです。
侵入された経路、システムを自社で運用していたのか委託先が運用していたのか、不正アクセスが始まった時期は書かれていません。お客様情報の外部への流出についても「現在も調査中」としています。影響範囲と原因の調査を続け、新たに公表すべき情報が確認されたら知らせる方針です。
氏名・住所・電話番号とリフォーム実施履歴・見積データの最大350万件
影響を受けた可能性があるのは、リフォーム管理システムに登録のある顧客の個人情報です。項目は次のとおりです。
| 区分 | 公表文の記載 |
|---|---|
| 対象の項目 | 氏名・住所・電話番号 |
| 対象の営業記録 | リフォーム実施履歴・見積データ等 |
| 件数 | 最大350万件 |
| 含まれない情報 | マイナンバー・クレジットカード情報 |
| 対象外の情報 | 店頭やECサイトでの家電購入情報等 |
「最大」と「可能性」は、読まれた範囲をまだ絞り込めていない段階の書き方です。350万件はシステムに登録された顧客の上限と読むのが自然で、調査が進めば小さくなる余地があります。メールアドレスは項目に挙がっていません。一方で「等の営業記録」とあるため、見積の金額や工事の内容、訪問の記録がどこまで含まれるかは、続報を待つ必要があります。
10月23日のサービス停止と委託先経由のメール流出6,046件は別の事案
ヤマダデンキはこの1か月で、ほかに2件の不正アクセスを公表しています。検索結果で混ざりやすいので分けておきます。
| 公表日 | 対象 | 公表された内容 |
|---|---|---|
| 10月23日 | ヤマダビデオ・スマホゴールド会員 | 各種手続き画面を停止 |
| 11月5日・11日 | 委託先のメール配信会社 | メールアドレス6,046件 |
| 11月13日 | リフォーム管理システム | 最大350万件・流出は調査中 |
10月23日の公表では、10月22日午後4時13分頃から2つのサービスの手続き画面を止めたとし、個人情報への影響は調査中としています。11月11日の第2報は、メール配信会社アララへの不正アクセスで「ヤマダファミリーサポートFCクラブ」の利用者のメールアドレスが流出したもので、件数は第1報の最大7,640件から確定値の6,046件になりました。委託先側の事案の全体像はアララの不正アクセスと契約企業の対応で整理しています。3件の関係について、同社は公表文で触れていません。
住所と工事履歴がそろう営業記録の漏えいで想定する、点検商法となりすまし連絡
実施履歴と見積があると「前回工事の点検です」が本物らしく聞こえる理由
氏名と電話番号だけの漏えいなら、届くのは一般的な迷惑電話です。今回の項目には住所とリフォームの実施履歴、見積データが入っています。いつ、どの部分を工事したか、どの工事を検討して見送ったかが分かれば、「前回の浴室工事から3年たったので点検に伺います」「見積をお出しした外壁の件で」と、本人しか知らないはずの話から切り出せます。
国民生活センターの「訪問販売によるリフォーム工事・点検商法」(2026年7月31日更新)によると、点検商法の相談は2023年度12,550件、2024年度19,249件、2025年度19,696件と増えています。事例には、給湯器の点検と電話で告げられ、高額なメンテナンス契約を結んだがメーカー保証期間内だったという相談も挙がっています。今回の情報が悪用されたかどうかは公表されていません。ただ、営業記録は点検商法の台本にそのまま使える形をしています。
利用者が今やる、ヤマダデンキを名乗る訪問・電話・SMSへの確かめ方
公表文は、同社を装ったメール・SMS・電話等に注意するよう呼びかけ、同社がメールや電話でパスワードや暗証番号等を尋ねることはないとしています。利用者がやることは3つに絞れます。
- 点検や追加工事の連絡が来たら、その場で日程を決めず、自分で調べた番号からヤマダデンキに確かめる(お客様御相談窓口 0120-335-537、10時〜18時)
- 訪問してきた業者を家に入れる前に、名刺の会社名と連絡先を控え、同社の窓口で実在を確かめる
- 工事の契約を急がされたら、家族や別の業者の見積と比べてから決める
高齢の家族がリフォームを依頼していた場合は、家族の側から先に伝えておくのが確実です。住所が出ているので、電話を断っても訪問が来る前提で備えます。
営業記録を誰がどこまで読めるかを決める、店舗単位のアクセス権の設計
個人情報保護委員会ガイドラインのアクセス制御と、全件を読める画面の問題
リフォームのように店舗や担当者ごとに案件を持つ業務では、1人の担当者が日常で見る顧客は全体のごく一部です。それでも、検索画面や一覧画面から全店舗の顧客を引けるつくりは珍しくありません。1つのアカウントが乗っ取られたとき、読まれる範囲は全件になります。
個人情報保護委員会のガイドライン(通則編)の別添10-6は、技術的安全管理措置の1つ目に「アクセス制御」を置き、担当者と取り扱う個人情報データベース等の範囲を限定するよう求めています。手法の例には、ユーザーIDに付与するアクセス権で使える従業者を限定することが挙がっています。画面のメニューを隠すだけでは足りません。APIやDBの問い合わせの段階で、読める行を絞る必要があります。APIの段階での認可の組み方はAPI不正アクセス対策の実装手順で解説しています。
PostgreSQL 18の行レベルセキュリティで担当店舗の顧客だけを返す仕組み
アプリの問い合わせに毎回「自店舗の条件」を書く方式は、書き忘れた1か所から全件が漏れます。DBの側で絞るための手段の1つが、PostgreSQLの行レベルセキュリティです。PostgreSQL 18.7のドキュメントによると、テーブルで行レベルセキュリティを有効にすると、行の参照や変更はポリシーで許可されたものだけになり、ポリシーが1つも無ければ何も見えない(default-deny)動きになります。
設計で外せない注意点は2つです。
- スーパーユーザーとBYPASSRLS属性を持つロールは常にポリシーを通らない。アプリの接続ユーザーにこれらを持たせない
- テーブルの所有者も通常はポリシーを通らない。所有者で接続するなら FORCE ROW LEVEL SECURITY を指定する
アプリが所有者のロールでDBにつないでいると、ポリシーを書いても効きません。導入時は、アプリの接続ユーザーで他店舗の顧客を引き、0件になることを必ず試します。全店舗を横断して見る必要がある本部の分析は、氏名や住所を除いた集計用のテーブルかビューに分けて渡します。
1つのアカウントの大量閲覧と時間外の出力を、監査ログから拾う検知の実装
担当者ごとの平常値と比べて閲覧件数の急増を抽出するPythonとSQL
権限を絞っても、正規のアカウントが乗っ取られれば、その範囲は読まれます。ガイドラインの10-3で手法の例に挙げられているのは、ログイン実績やアクセスログなどの記録を整備し、取扱いを検証できるようにすることです。記録を取るだけでなく、毎時の集計で異常を拾える形にしておきます。
次のコードは、顧客の閲覧と出力を記録した監査ログをsqlite3に入れ、担当者ごとに1時間あたりの閲覧件数を集計して、平常時の中央値の5倍以上(最低50件)の時間帯と、営業時間外の出力を抽出します。
# 監査ログから、1アカウントが平常時より多くの顧客記録を開いた時間帯を抽出する(Python 3.9以上・標準ライブラリのみ)
import sqlite3
from statistics import median
db = sqlite3.connect(":memory:")
db.execute("CREATE TABLE audit_log (ts TEXT, staff_id TEXT, store_id TEXT, customer_id INTEGER, action TEXT)")
rows = []
# 平常時のダミーログ:各担当者が営業時間中に1時間あたり6〜8件の顧客を開く(7日分)
for day in range(1, 8):
for hour in (10, 14, 16):
for staff, store, n in (("s01", "T01", 6), ("s02", "T02", 8)):
for i in range(n):
rows.append((f"2026-11-{day:02d} {hour:02d}:{i * 5:02d}:00", staff, store, day * 100 + i, "view"))
# 11月8日の深夜2時台:s02のアカウントで400件の顧客を開き、うち100件を出力している
for i in range(400):
rows.append((f"2026-11-08 02:{i % 60:02d}:00", "s02", "T02", 5000 + i, "export" if i % 4 == 0 else "view"))
db.executemany("INSERT INTO audit_log VALUES (?, ?, ?, ?, ?)", rows)
hourly = db.execute("""
SELECT staff_id,
substr(ts, 1, 13) AS hour,
COUNT(DISTINCT customer_id) AS customers,
SUM(action = 'export') AS exports,
CAST(substr(ts, 12, 2) AS INTEGER) AS h
FROM audit_log
GROUP BY staff_id, hour
ORDER BY staff_id, hour
""").fetchall()
by_staff = {}
for staff, hour, customers, exports, h in hourly:
by_staff.setdefault(staff, []).append(customers)
for staff, hour, customers, exports, h in hourly:
base = median(by_staff[staff]) # 担当者ごとの平常値(1時間あたり閲覧件数の中央値)
reasons = []
if customers >= max(base * 5, 50):
reasons.append(f"閲覧{customers}件(平常の中央値{base:g}件)")
if exports and not 8 <= h < 20:
reasons.append(f"営業時間外の出力{exports}件")
if reasons:
print(staff, hour + "時台", "/".join(reasons))
Python 3.14.10(Windows)で2026年11月14日に実行した結果です。値は説明用に作ったもので、ヤマダデンキのシステムやデータを再現したものではありません。
s02 2026-11-08 02時台 閲覧400件(平常の中央値8件)/営業時間外の出力100件
閾値の決め方と、検知した後にアカウントと出力経路を止める順序
平常時に1時間8件を開く担当者の、深夜2時台の400件だけが残りました。s01は抽出されていません。5倍と50件、営業時間の8時〜20時は説明用の値です。本番では、繁忙期を含む2〜4週間の分布を担当者ごとに集計してから決めます。月末の一括処理のように正当な大量閲覧がある業務は、専用のアカウントに分けておくと誤検知が減ります。
検知した後は、次の順で止めます。
- 該当アカウントのセッションを失効させ、パスワードを再設定する
- CSV出力など一括で持ち出せる機能を、全アカウントでいったん止める
- 監査ログから、そのアカウントが開いた顧客IDの一覧を確定する
3つ目の一覧が、後で影響範囲を「最大」ではなく実数で示す根拠になります。監査ログ自体をアプリと同じ権限で消せるつくりでは、侵入者による証拠ごとの消去が可能です。ログは書き込みしかできない別の保存先に送っておきます。
見積だけで終わった顧客の住所を残し続けない、保存期間の設計と消去バッチ
個人情報保護法第22条の消去の努力義務と、成約・未成約で期間を分ける理由
営業記録は、成約しなかった見積も含めてたまり続ける性質の情報です。ガイドライン(通則編)の3-4-1は、法第22条にもとづき、利用する必要がなくなった個人データは遅滞なく消去するよう努めなければならないとしています。法令で保存期間が定められている場合は除かれます。
成約した顧客には、保証やアフターサービスで連絡する理由が残ります。見積だけで終わった顧客は、再提案の見込みが薄れた時点で住所を持つ理由が弱くなります。保存期間を状態ごとに分けるのはこのためです。期間は自社の規程と、契約や法令で求められる保存義務から決めます。消すのは氏名・住所・電話番号に絞り、工事の種別や金額は残せば、見積の傾向の分析は続けられます。
sqlite3で動かす消去バッチと、バックアップに残った住所の扱い
次のコードは、状態ごとの保存期間を過ぎた顧客の氏名・住所・電話番号を消し、工事の種別と金額は残します。
# 見積だけで終わった顧客の氏名・住所・電話番号を、保存期間を過ぎたら消す消去バッチ(Python 3.9以上・標準ライブラリのみ)
import sqlite3
from datetime import date
RETENTION_YEARS = {"estimate_only": 3, "contracted": 10} # 説明用の値。自社の規程と契約・法令上の保存義務から決める
TODAY = date(2026, 11, 14)
db = sqlite3.connect(":memory:")
db.execute("""CREATE TABLE customers (
customer_id INTEGER PRIMARY KEY, name TEXT, address TEXT, phone TEXT,
work_type TEXT, amount INTEGER, status TEXT, last_activity TEXT, erased_at TEXT)""")
db.executemany("INSERT INTO customers VALUES (?, ?, ?, ?, ?, ?, ?, ?, NULL)", [
(1, "顧客A", "群馬県(ダミー)", "000-0000-0001", "浴室", 980000, "estimate_only", "2021-06-01"),
(2, "顧客B", "東京都(ダミー)", "000-0000-0002", "外壁", 1500000, "estimate_only", "2025-02-10"),
(3, "顧客C", "埼玉県(ダミー)", "000-0000-0003", "キッチン", 1200000, "contracted", "2018-09-30"),
(4, "顧客D", "千葉県(ダミー)", "000-0000-0004", "屋根", 2100000, "contracted", "2014-04-01"),
])
def cutoff(years):
return TODAY.replace(year=TODAY.year - years).isoformat()
for status, years in RETENTION_YEARS.items():
cur = db.execute("""UPDATE customers
SET name = NULL, address = NULL, phone = NULL, erased_at = ?
WHERE status = ? AND last_activity < ? AND erased_at IS NULL""",
(TODAY.isoformat(), status, cutoff(years)))
print(f"{status}: 保存{years}年・基準日{cutoff(years)}より前 → {cur.rowcount}件を消去")
db.commit()
# 工事種別と金額は残るので、集計や見積の傾向分析は続けられる
for row in db.execute("SELECT customer_id, name, address, work_type, amount, status FROM customers"):
print(row)
同じ環境で実行した結果です。
estimate_only: 保存3年・基準日2023-11-14より前 → 1件を消去
contracted: 保存10年・基準日2016-11-14より前 → 1件を消去
(1, None, None, '浴室', 980000, 'estimate_only')
(2, '顧客B', '東京都(ダミー)', '外壁', 1500000, 'estimate_only')
(3, '顧客C', '埼玉県(ダミー)', 'キッチン', 1200000, 'contracted')
(4, None, None, '屋根', 2100000, 'contracted')
5年前の見積だけの顧客Aと、12年前に成約した顧客Dの連絡先が消え、工事の種別と金額は残りました。本番で流すときは、消す前に対象の件数を出し、担当部署の確認を経てから実行します。
見落としやすいのはバックアップです。本番のテーブルから消しても、日次のバックアップや分析用の複製に住所が残っていれば、漏えい時の件数には数えられます。バックアップの保持期間を保存期間より短くするか、復元時に消去バッチを流し直す手順を決めておきます。リフォームの写真や本人確認書類の画像が残る問題は、Joshinの不正アクセスと写真投稿先の棚卸しで扱いました。
判断:全件の棚卸しから始める条件と、個人情報保護委員会への報告の期限
店舗で絞れず監査ログも無いなら、権限より先に保有件数を減らすという線引き
自社の顧客管理システムで手を付ける順番は、今の状態で決まります。全店舗の顧客をどの担当者も読めて、閲覧の監査ログも残していないなら、権限の作り直しより先に消去バッチを流します。権限の分離は設計と試験に時間がかかりますが、保存期間を過ぎた住所を消す作業は数日で済み、漏えい時の件数を直接減らせるからです。
逆に、店舗単位の権限がすでに効いていて監査ログもあるなら、消去は定期実行に任せ、検知の閾値の調整に時間を使います。部分的な対策で十分と言えるのは、この2つがそろっている場合だけです。
不正アクセスで1,000人を超える漏えいの速報3〜5日と確報60日
個人情報保護委員会は、報告が必要な事態として4つの類型を示しています。不正の目的によるおそれがある漏えい、財産的被害のおそれがある漏えい、本人の数が1,000人を超える漏えい、要配慮個人情報の漏えいです。外部からの不正アクセスで1,000人を超える顧客の情報に影響が出たおそれがある場合は、不正の目的によるおそれと1,000人超の2つに当たります。
速報は発覚から3〜5日以内が目安です。確報は30日以内、不正の目的によるおそれがある場合は60日以内とされています。報告の流れは個人情報保護委員会への報告義務の実務で解説しました。自社の顧客管理・営業管理システムの権限やログの設計を第三者の目で確かめたい場合は、脆弱性診断・セキュリティ診断で相談できます。
よくある質問
ヤマダデンキのリフォーム管理システムへの不正アクセスについて、利用者と開発者から出やすい質問をまとめました。2026年11月14日時点の公表内容にもとづきます。
ヤマダデンキの不正アクセスで影響を受けた可能性があるのはどんな情報ですか?
リフォーム管理システムに登録のある顧客の氏名、住所、電話番号と、リフォーム実施履歴や見積データ等の営業記録で、件数は最大350万件です。マイナンバーとクレジットカード情報は含まれず、店頭やECサイトでの家電購入情報等は対象外とされています。外部への流出の有無は調査中です。
ヤマダデンキで家電を買っただけでも対象になりますか?
公表文は、リフォーム以外の情報(店頭やECサイトでの家電購入情報等)は対象外としています。対象はリフォーム管理システムに登録のある顧客です。リフォームを依頼した人に加え、見積だけを取った人も、見積データが登録されていれば含まれる可能性があります。
ヤマダデンキを名乗る電話や訪問が来たらどうすればよいですか?
その場で日程や契約を決めず、自分で調べた番号からヤマダデンキのお客様御相談窓口(0120-335-537、10時〜18時、元日を除く)に確かめます。同社の説明では、メールや電話でパスワードや暗証番号等を尋ねることはないとのことです。点検を口実にした訪問には、名刺の会社名を控えて家に入れる前に確認します。
10月のヤマダビデオの件やメールアドレスの流出とは同じ事案ですか?
公表は別々です。10月23日はヤマダビデオとスマホゴールド会員の手続き画面の停止、11月5日と11日はメール配信会社アララへの不正アクセスによるメールアドレス6,046件の流出、11月13日がリフォーム管理システムの件です。3件の関係について、同社は公表文で触れていません。
顧客管理システムで店舗ごとに見える顧客を絞るにはどうすればよいですか?
画面のメニューを隠すだけでなく、APIやDBの問い合わせの段階で読める行を絞ります。PostgreSQLで担当店舗の行だけを返すポリシーを書くための仕組みが、行レベルセキュリティです。アプリの接続ユーザーがテーブルの所有者やBYPASSRLS属性を持つと効かないため、導入時に他店舗の顧客を引いて0件になることを試します。
関連記事
- Joshin(ジョーシン)不正アクセス:最大600万件の対象とサブスク初期パスワード、メンテナンス中のサービス:家電量販店のリフォーム写真アップロードシステムも対象になった事案
- アララの不正アクセス:メール約8,100万件の持ち出しと公表した契約企業、APIキー再設定・代替送信・連名報告:ヤマダデンキの委託先メール流出の元になった事案
- API不正アクセス対策の実装手順:JPCERT注意喚起に沿うレート制限・認可・トークン失効とアプリ解析・SSRF対策:APIの段階での認可とトークン失効
- 個人情報保護委員会への報告義務|対象4類型・速報3〜5日と確報30日の実務:不正アクセスで漏えいしたときの報告の流れ