セキュリティ

Studio不正アクセスで全顧客の情報流出か|パスワード・APIキー・Webhook URLを今日替える手順

AIの活用によるセキュリティの向上

ノーコードのWeb制作ツール「Studio」を運営するStudio株式会社は2026年10月16日、同社が使うクラウド環境に第三者の不正アクセスがあり、すべての利用者の情報が外部に流出した可能性があると公表しました。対象にはアカウント情報だけでなく、サイトのフォームに送信された内容、API連携に登録した外部サービスのAPIキー、Webhook通知のURLまで含まれます。本記事では、Studioでサイトを作り運営している人が今日替えるものを先に示し、続いて古いキーが本当に使えなくなったかを確かめるPython、署名の無いWebhook通知を受信側ではじく実装、フォーム送信内容の漏えいを誰が報告するかを、公式発表とStudioヘルプの記述をもとに解説します。

まとめ:Studio不正アクセスで公表された事実と利用者が今日替えるもの

確定している事実は次のとおりです。第三者がStudioの一部機能の脆弱性を悪用してクラウド環境に入り、環境内のデータを外部から取得できる状態にしていました。その状態は10月14日まで続き、脆弱性はすでに修正されています。実際に取得された事実は確認できていませんが、同社は取得されたものとみなして対応しています。対象の件数と原因の詳細は、第一報の時点で公表されていません。

項目 公表されている内容
不正アクセスの期間 2026年9月30日〜10月1日(日本時間)
確認と遮断 10月13日に確認・13〜14日に修正と経路の遮断
対象 Studioの全登録利用者(件数は続報)
暗号化していた情報 復号に必要な鍵も読み出され内容を知られた可能性
パスワード ハッシュ化して保存・平文では保存していない

不正アクセスの期間は、現時点で確認できている範囲を示しています。

利用者が替えるものは、使っている機能で決まります。Studioのパスワードとライブプレビューは全員、API連携・カスタムプロキシ・Webhook通知・フォームのスプレッドシート連携・パスワード保護ページは使っている人だけです。Studio側で値を変えるだけでなく、連携先の外部サービス側で古いキーを無効にするところまでが対応です。

Studio利用者が今日替える7項目|Web制作者と運営担当のチェックリスト

メールとパスワードでログインする人の変更とGoogleログインだけの人の扱い

Studioの公式発表(第一報)は、メールアドレスとパスワードでログインしている利用者にパスワードの変更を求めています。同じパスワードを他のサービスで使っているなら、そちらも替えてください。GoogleログインかFacebookログインだけで、Studioのパスワードを設定していない人はこの対応は不要とされています。

ただし不要なのはパスワードの変更だけです。メールアドレス、デザインエディタとCMSの内容、フォームの送信内容は、ログイン方法に関係なく対象に入っています。下の表で、自分が使っている機能の行をすべて確かめてください。

使っている機能 替えるもの どこで替えるか
メールとパスワードのログイン Studioのパスワード Studioのアカウント設定
ライブプレビュー 発行済みURL Studioで削除して再発行
API連携 APIキー・トークン 連携先サービスで新規発行と旧キー削除
カスタムプロキシ プロキシキー Studioで再発行しプロキシ側の値を差し替え
Webhook通知 通知先URL 受信側で新URLを作りStudioに登録
フォームのスプレッドシート連携 連携の認証情報 Studioで解除しGoogleアカウント側も確認
パスワード保護ページ 保護ページのパスワード Studioのページ設定

スプレッドシート連携は、Studio側で解除したあと、Googleアカウントの他のデベロッパーのアプリとのリンクを管理する画面でStudioへのアクセス権が残っていないかも見ておくと確実です。

ライブプレビューURLの削除と再発行で公開前ページの共有をやり直す

ライブプレビューは、公開前のページを関係者に見せるためのURLです。公式発表は、発行済みのURLが直接特定されたことは確認していないとしつつ、安全のため削除を求めています。削除したURLは無効になり、アクセスできなくなります。

制作会社がクライアントに確認用URLを送っている場合は、削除の前に「旧URLが開けなくなる」ことを先方に伝えてください。新しいURLはメールやチャットに貼り直すことになるので、送付先の一覧を手元で作ってから作業すると漏れません。未発表の新サービスやキャンペーンのページをプレビューで共有していた事業者は、このURLの削除を最初に済ませてください。

個別メールが届く5機能とStudioを装う偽メールを見分ける公式の言い切り

API連携、パスワード保護ページ、フォーム、カスタムプロキシ、Webhook通知の5機能を使うプロジェクトのオーナーには、Studioから個別のメールで案内が送られています。オーナー以外のメンバーには届かないことがあるため、制作を受託している側はオーナーであるクライアントに受信を確かめてください。

見分けの基準は、公式発表に書かれた2つの言い切りです。Studioがパスワードや認証情報をメールや電話で尋ねることはなく、本件のメールにパスワードや認証情報の入力を求めるリンクが含まれることもありません。入力を求めるメールは、公式の案内とは異なる偽物です。問い合わせは、ログインできる人は画面のヘルプアイコンから「不正アクセスに関するお問い合わせ」を選び、ログインできない人は公式発表の窓口フォームから送ります。回答は平日10時〜18時に順次行われます。

公式発表の時系列|9月30日の不正アクセスから10月16日の第一報まで

取得できる状態が10月14日まで続いた経緯と取得が未確認という意味

日付 出来事
9月30日〜10月1日 第三者による不正アクセス(確認できている期間)
10月13日 社内の調査で不正アクセスを確認
10月13日〜14日 脆弱性を修正し経路を遮断・取得できる状態を解消
10月16日 第一報を公開

不正アクセスの期間は2日間ですが、データを外部から取得できる状態はその後も10月14日まで続いていました。確認まで約2週間かかったことになります。「取得された事実は確認できていない」という文言は、取得されなかったという意味ではありません。同社自身が取得されたものとみなして動いているので、利用者も同じ前提で対応してください。

暗号化していた認証情報も復号鍵ごと読まれた可能性がある情報の範囲

公式発表によると、フォームの送信内容、外部サービスのAPIキーとトークン、スプレッドシート連携の認証情報、プロキシキー、reCAPTCHA v3の設定情報、Webhook通知のURLは、暗号化して保存していたものも、復号に必要な鍵が同じ不正アクセスで読み出されました。暗号化していたから安全とは言えない状態です。

一方、Studioのパスワードとパスワード保護ページのパスワードはハッシュ化して保存されていました。元の文字列を割り出すのは困難としながらも、可能性を否定できないため変更を求めています。替える優先度は、平文に戻せる可能性のあるAPIキーやトークンの方が、ハッシュ化されたパスワードより高いと考えてください。決済やログインに使う同社自身の認証情報は、すでに新しいものに切り替えたとされています。

Studioに預けたシークレットの棚卸し|API連携キーとプロキシキーの切り替え

Data Connect APIの外部キーがStudio側に保存される理由

StudioヘルプのData Connect API(API連携)によると、microCMSやNotionなどの外部サービスの認証情報はHTTPヘッダーとして登録し、Studio側のProxyから送信されます。公開サイトのソースコードに表示されない代わりに、キーそのものはStudioに保存されます。今回流出した可能性があるのはこの値です。例として挙げられているのはNotion、microCMS、Airtableで、ヘッダー名はX-MICROCMS-API-KEYやAuthorizationです。

切り替えは、連携先のサービスで新しいキーを発行し、Studioに登録し直し、最後に古いキーを連携先で削除する順で進めます。microCMSのAPIキーのドキュメントは、書き込み系の権限を持つキーが漏れるとコンテンツを書き換えられるおそれがあるとして、公開に使うキーはGETだけに絞る設定を勧めています。新しいキーを作るときに、Studioが使うのは取得だけなのでGET以外の権限を外してください。Data Connect APIはGETとPOSTのどちらでも取得しかできない仕様です。

古いキーが失効したかを外部APIで確かめるPythonスクリプトと実行結果

Studio側で値を替えても、連携先で古いキーを消し忘れると、流出したキーは使えるままです。次のスクリプトは、切り替え前の値を環境変数から読み、各サービスの「自分は誰か」を返すAPIに送って、まだ通るかを判定します。Notionはusers/me、Airtableはmeta/whoamiを使う構成です。Python 3の標準ライブラリだけで動き、check_old_secrets.pyとして保存します。

import json, os, sys, urllib.request, urllib.error

# 切り替え前の古い認証情報が、まだ外部サービスで通るかを確かめる
def call(method, url, headers, body=None):
    req = urllib.request.Request(url, data=body, method=method, headers=headers)
    try:
        with urllib.request.urlopen(req, timeout=15) as r:
            return r.status, r.read(200).decode("utf-8", "replace")
    except urllib.error.HTTPError as e:
        return e.code, e.read(200).decode("utf-8", "replace")

env = os.environ.get
checks = []
if env("OLD_NOTION_TOKEN"):
    checks.append(("Notion", "GET", "https://api.notion.com/v1/users/me",
        {"Authorization": "Bearer " + env("OLD_NOTION_TOKEN"), "Notion-Version": "2022-06-28"}, None, (401,)))
if env("OLD_AIRTABLE_TOKEN"):
    checks.append(("Airtable", "GET", "https://api.airtable.com/v0/meta/whoami",
        {"Authorization": "Bearer " + env("OLD_AIRTABLE_TOKEN")}, None, (401,)))
if env("OLD_MICROCMS_KEY") and env("MICROCMS_SERVICE") and env("MICROCMS_ENDPOINT"):
    checks.append(("microCMS", "GET", "https://" + env("MICROCMS_SERVICE") + ".microcms.io/api/v1/"
        + env("MICROCMS_ENDPOINT") + "?limit=1", {"X-MICROCMS-API-KEY": env("OLD_MICROCMS_KEY")}, None, (401,)))
if env("OLD_SLACK_WEBHOOK"):
    # textを入れずに送る:有効なURLなら400 no_textで投稿されず、無効なら403か404が返る
    checks.append(("Slack", "POST", env("OLD_SLACK_WEBHOOK"),
        {"Content-Type": "application/json"}, json.dumps({}).encode(), (403, 404)))

alive = unknown = 0
for name, method, url, headers, body, revoked in checks:
    status, text = call(method, url, headers, body)
    if status in revoked:
        verdict = "失効済み"
    elif 200 <= status < 300 or (name == "Slack" and status == 400):
        verdict = "要対応:古い値がまだ通る"
        alive += 1
    else:
        verdict = "判定不能:URLや名前を確認"
        unknown += 1
    print(f"{name:9} HTTP {status}  {verdict}  {text[:50]!r}")
print("確認", len(checks), "件 / 要対応", alive, "件 / 判定不能", unknown, "件")
sys.exit(1 if alive else (2 if unknown else 0))

2026年10月16日に、どのサービスにも存在しないダミーの値を入れて、実際の各APIへ送った結果です。microCMSは存在しないサービス名を指定したため404になり、判定不能として残りました。

$ python check_old_secrets.py
Notion    HTTP 401  失効済み  '{"object":"error","status":401,"code":"unauthorize'
Airtable  HTTP 401  失効済み  '{"error":{"type":"UNAUTHORIZED","message":"Invalid'
microCMS  HTTP 404  判定不能:URLや名前を確認  ''
Slack     HTTP 404  失効済み  'no_team'
確認 4 件 / 要対応 0 件 / 判定不能 1 件

終了コードは、まだ通る値があれば1、判定できない値があれば2、すべて失効なら0です。自社のサービス名で実行し、microCMSが401になれば失効と判断できます。実在サービスで古いキーを送ったときの応答は本記事では確かめていないため、初回は新しいキーで200が返ることも同時に確かめてください。値は環境変数で渡し、シェルの履歴やファイルに残さないようにします。同じキーをGitリポジトリに置いた覚えがあるなら、gitleaksによるシークレット検出で履歴も洗ってください。

カスタムプロキシのx-studio-proxy-keyとパスワード保護ページの切り替え

カスタムプロキシの設定手順では、自社のプロキシがStudioサブドメイン(xxxx.studio.site)へ要求を転送するときに、x-studio-proxy-keyヘッダーにStudioが発行したキーを付けます。プロキシ側で認証やIP制限を掛けている構成では、キーを知る第三者がプロキシを通さずにStudio側へ要求を送れる余地が残ると読めます。新しいキーを発行したら、プロキシの設定値を差し替え、公開ページが表示されることをすぐ確かめてください。

パスワード保護ページは、会員向け資料や社内向けページに使われがちです。パスワードを替えたら、新しい値を共有先に届け直す手順も同時に決めておきます。

署名の無いStudioのWebhook通知を受信側で検査する実装とSlackの再発行

Studio-Webhookの通知に署名が無く通知先URLそのものが鍵になる理由

StudioヘルプのWebhook通知によると、サイトの公開・更新・非公開などのたびに、登録したURLへPOSTで通知が送られます。付くヘッダーはContent-Type: application/jsonとUser-Agent: Studio-Webhookで、本文はproject_id、event、publish_url、timestampなどのJSONです。送信者を確かめる署名のヘッダーはヘルプに書かれていません。

つまり受信側から見ると、通知先URLを知っている者なら誰でも本物と同じ形の通知を送れます。公開の通知を合図にキャッシュの削除や再ビルドを走らせている構成では、偽の通知で処理を何度も起こされます。署名で送信元を確かめる一般的な作りはWebhookの作り方と受信側の署名検証で解説しましたが、Studioの通知ではそれが使えません。URLを新しくすることが、切り替えの中身になります。

通知先URLの文字列と時刻で受理を判定するPythonの受信側チェック

次の関数は、通知先URLの末尾に混ぜた推測できない文字列、User-Agent、project_id、timestampの4点で受理を判定します。User-Agentとproject_idは偽装できるため、実際に鍵として働くのはURLの文字列だけです。新しいURLを登録したら、古い文字列で届いた要求は拒否され、ログに残ります。

import hmac, json, os, time

TOKEN = os.environ.get("STUDIO_HOOK_TOKEN", "")        # 新しい通知先URLに混ぜた文字列
PROJECT_ID = os.environ.get("STUDIO_PROJECT_ID", "")

def accept(path_token, user_agent, raw_body, now=None):
    if not TOKEN or not hmac.compare_digest(path_token, TOKEN):
        return False, "token不一致"
    if user_agent != "Studio-Webhook":
        return False, "User-Agent不一致"
    try:
        body = json.loads(raw_body)
    except ValueError:
        return False, "JSONでない"
    if body.get("project_id") != PROJECT_ID:
        return False, "project_id不一致"
    now = time.time() if now is None else now
    if abs(now - int(body.get("timestamp", 0))) > 300:
        return False, "5分以上前の通知"
    return True, "受理"

2026年10月16日にPython 3.14で、新しい文字列の通知、古い文字列の通知、1時間前のtimestampを持つ通知の3つを与えた結果です。

新URL・正しい通知 (True, '受理')
旧URLへの通知 (False, 'token不一致')
新URL・1時間前の通知 (False, '5分以上前の通知')

切り替え後に「token不一致」が記録され続けるなら、古いURLを誰かが使っている兆候です。送信元IPと時刻を控え、続報で公表される二次被害の情報と照らし合わせてください。

Slackのincoming webhook URL漏えい時の再発行と旧URLの失効確認

Studioのヘルプは、通知先にSlackのincoming webhook URLを登録する使い方を案内しています。Slackのincoming webhooksのドキュメントは、このURLには秘密の値が含まれると明記しており、URL自体が秘密情報です。漏れたURLを使うと、第三者がそのチャンネルへ任意の文面を投稿できます。社内チャンネルに「公開しました」の体裁で偽のリンクを流されると、フィッシングの入口になります。

Slackのアプリ設定で新しいWebhookを作ってStudioに登録し、古いWebhookは削除します。削除後に先のスクリプトで古いURLを確かめ、403か404が返れば、古いURLは失効済みと判断できる状態です。同じドキュメントは、無効や削除済みのWebhookにno_service、無効なトークンにinvalid_tokenを返すと説明しています。

フォーム送信内容の漏えいは誰が報告するか|サイト運営者側の判断材料

クラウド利用でも報告義務は利用する事業者にあるとするQ&A 6-22

Studioのフォームに届く問い合わせには、送信者の氏名やメールアドレスが入っています。これを集めているのはサイトを運営する事業者です。個人情報保護委員会のガイドラインQ&AのA6-22は、クラウドサービス提供事業者が個人データを取り扱わないこととなっている場合、漏えいの報告義務はクラウドサービスを利用する事業者が負うとしています。報告をクラウド事業者に代行させることはできますが、義務の主体は利用する側です。

Studioが個人データを取り扱う委託先に当たるか、取り扱わないクラウドに当たるかは、利用規約と契約の内容で決まります。どちらの整理でも、運営者が「Studioが報告したから自社は何もしなくてよい」と決めつけるのは危険です。不正アクセスによる漏えいのおそれは件数にかかわらず報告の対象になりうるため、速報の期限を意識して早めに判断してください。速報と確報の段取りは個人情報保護委員会への報告義務で整理しています。

復号鍵まで読まれたため高度な暗号化の報告免除に当たりにくい根拠

報告が不要になる例外に、高度な暗号化で秘匿されている場合があります。ただしQ&AのA6-19は、その条件として、暗号化した情報と復号鍵を分離し、復号鍵自体の漏えいを防ぐ措置などが必要だとする説明です。今回の公式発表は、フォームの送信内容について復号に必要な鍵が同じ不正アクセスで読み出されたとしているため、この例外には当たりにくいと考えられます。

公式発表は、フォームから情報を送った人には送信先のサイトの運営者から案内がある場合があると書いています。本人への通知の文面は、Studioの続報で対象範囲が確定するのを待ちつつ、送信フォームの項目と保存期間を手元で整理しておくと早く出せます。

預けた認証情報の点検を急ぐ事業者とStudioの案内待ちで足りる事業者

フォームとAPI連携で問い合わせや会員情報を集めている事業者

Studioのフォームで問い合わせや資料請求を受け付け、API連携でmicroCMSやNotionのデータを表示し、Webhookで社内の仕組みとつないでいるなら、今週中に次の3点を終えてください。連携先すべてで古いキーを削除し、スクリプトで失効を確かめること。Webhookの受信側で古いURLへの要求を拒否し、記録すること。フォームの送信者に対する報告と通知の要否を、社内の個人情報の担当者と決めることです。

キーを手作業で管理していると、次に同じことが起きたときも棚卸しから始まります。外部サービスの鍵をAWS Secrets Managerのような保管先で一元管理し、ローテーションの手順を決めておけば、切り替えは、あらかじめ決めた手順を実行する作業です。連携の範囲が広く、どこに鍵があるか社内で洗い出しきれないときは、脆弱性診断・セキュリティ診断で、Webhookの受信側や外部APIとの接続を含めて点検できます。

フォームも外部連携も使わない名刺代わりのサイトで過剰になる対応

会社案内だけを載せ、フォームも外部連携も使っていないサイトでは、本記事のスクリプトや受信側の実装は過剰です。Studioのパスワード変更とライブプレビューの削除を済ませ、偽メールに注意すれば足ります。Studioからの乗り換えを急ぐ必要もありません。続報で原因と再発防止策が示されるまで、今回の対応を確実に終える方が先です。

よくある質問

Studioの不正アクセスについて、利用者とサイトの運営担当者から出やすい質問をまとめました。

Googleログインだけで使っている場合は何もしなくてよいですか?

パスワードの変更は不要ですが、ほかの対応は残ります。公式発表は、GoogleログインかFacebookログインだけでStudioのパスワードを設定していない人について、パスワード変更を不要としているだけです。メールアドレス、CMSの内容、フォームの送信内容、API連携のキーはログイン方法に関係なく対象です。ライブプレビューの削除と、使っている機能ごとの切り替えは同じように行ってください。

Studioで作られたサイトのフォームに問い合わせを送った側は何をすればよいですか?

送った内容が流出した可能性はありますが、送信者がStudioに対して手続きをする必要はありません。公式発表は、送信先のサイトの運営者から案内がある場合があるとしています。運営者を名乗る連絡が来たら、メールのリンクではなく、自分でそのサイトを開いて連絡先を確かめてください。不明な点はStudioの問い合わせ窓口でも受け付けています。

個別メールが届いていなければAPI連携の切り替えは不要ですか?

不要とは言えません。個別メールはプロジェクトのオーナー宛てに送られるため、制作会社や運用担当がメンバーとして参加しているだけだと届きません。Studioの設定画面でAPI連携やWebhookの登録があるかを自分で確かめ、登録があればオーナーと連携して切り替えてください。届いていない場合の問い合わせ先は、公式発表の窓口です。

対象になった件数や原因の詳細はいつ分かりますか?

2026年10月16日の第一報の時点では、対象の範囲と件数、二次被害の有無、原因と再発防止策は公表されていません。同社はこの3点を、確認が取れ次第、同じお知らせのページに続報として載せるとしています。件数が分かるまで待たずに、本記事のチェックリストの切り替えを先に済ませてください。

WordPressなど別の仕組みに移せば同じことは起きませんか?

起きないとは言えません。WordPressでも、プラグインの脆弱性やサーバーの設定不備から同じ種類の情報が漏れます。違いは、更新や監視を誰が担うかです。移行を検討するなら、フォームの送信内容をどこに何日保存するか、外部サービスの鍵を誰がどこで管理するかを先に決めてください。それが決まらないまま移しても、同じ棚卸しの課題が残ります。

関連記事

お気に入りに入れた記事の一覧

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.10.16 テックブログ バーガーキング不正アクセスで約1,118万件の情報漏洩|対象確認・案内メールの真偽と運営側のログ点検
  2. 2026.10.15 テックブログ 銀のさら不正アクセス:最大650万件の対象確認と窓口、パスワード変更の手順
  3. 2026.10.16 テックブログ ソースネクスト不正アクセスで最大2,252万件流出|ログインできない理由・パスワード再設定と会員APIの点検
  4. 2026.10.15 テックブログ リゾートトラスト不正アクセス:会員2.6万件・カハラ横浜3.6万件の対象確認と窓口
  5. 2025.12.02 テックブログ クーパン問題とは?3,755万人流出と過去最大6,246億ウォンの課徴金

RELATED POSTS 関連記事

目次