Apps Script予約画面の悪用対策と確認できた範囲

こんにちは!アントロンのNaokoです。
ネット予約を始めたいけど、いたずらの予約や大量の申し込みが来たらどうしよう。そう思って止まっていませんか?
私が制作を担当している宿では、ホームページに埋め込む素泊まりの予約画面を自作しました。Google Apps Script(Googleのサービスを動かすプログラム)とGoogleカレンダーを使う仕組みです。
Claude Code(AIに作業を頼めるアプリ)にコードの調査を頼むと、予約回数や入力された文字の長さ・内容に制限がないことが分かりました。そこで、受付件数の上限と入力内容の確認を入れ、受付を止めたときは公式LINEと電話を案内する作りにしました。
この記事では、Apps Scriptに実装した対策と、確認できた範囲を紹介します。Apps Scriptで予約を拒否できるかは試していません。
10月6日:自作の予約画面に当てはまる攻撃を調べた
2026年10月6日、Claude Codeに予約画面のコードを読んでもらい、攻撃や悪用の方法を調べました。調査記録では24種類について、この仕組みに当てはまるかを整理しています。本番へ攻撃を試す送信はしていません。
主に当てはまったのは、次の内容でした。
- 偽の予約で部屋を埋める。 調査時点のコードには、予約回数の制限がありませんでした。参考にしたのは、OWASPの自動化された攻撃に関する資料です。
- 確認メールを他人のアドレスに送らせる。 入力されたアドレスを宛先にする仕組みでした。フォームの自動返信の悪用については、ロリポップ!の注意喚起も参考にしました。
- 入力欄に文やURLを差し込む。 お名前・ご住所・ご要望に、長さや内容の制限がありませんでした。予約サイトの利用者を狙ったフィッシングについては、観光庁の注意喚起を参考にしました。
一方、ログインも決済もない作りなので、パスワードの総当たりやカードの試し打ちは当てはまりませんでした。
受付件数は、メールアドレスと電話番号で数える
調査では、Apps Scriptのウェブアプリが受け取る情報の一覧に、送り主のIPアドレス(通信元を示す番号)がないことを確認しました。Apps Scriptの公式資料に記載された項目をもとにした判断です。
そこで、入力されたメールアドレスと電話番号をそれぞれ数え、どちらかが上限に達したら受け付けないコードにしました。同じ人かどうかを確認する仕組みではないため、両方の連絡先を変えた申し込みは、別の連絡先として数えられます。
上限は、ネット予約全体と、同じメールアドレス・同じ電話番号から受ける件数に置きました。数えるのは、宿泊日ではなく、予約を受けた日(日本時間)です。
上限の数は私が決め、設定を1か所にまとめました。数と、受け付けない文字の細かい条件は、この記事では伏せています。
件数は、Apps Scriptのスクリプト プロパティ(スクリプトごとに値を保存できる場所)に、日ごとに保存します。件数を数えるための保存では、連絡先をそのまま残さず、ハッシュ(元の文字列から計算した値)に変えます。前の日の分は、次に数えるときに消します。
上限に達した場合は、予約を登録せず、公式LINE・電話の連絡先を案内する作りです。全体の上限に達すると、その日のネット予約受付を止めるため、通常のお客さんの申し込みもネットでは受け付けなくなります。
この件数制限は、予約の登録と、それに伴うメール送信を抑えるためのものです。調査では、偽の予約によってメール送信サービスの上限を使い切られる問題も挙げられました。
ただし、月の空き・料金への大量アクセスは、この件数制限では止められません。Apps Scriptの割り当て(利用できる処理の上限)を使い切られる問題が残ると整理しています。参照したのは、Apps Scriptの割り当てに関する公式資料です。
入力された文字への対策
件数制限に加えて、次の対策を入れました。
- 文字数とURL。 お名前・ご住所・ご要望に文字数の上限を置き、この3つの欄にURLがあれば受け付けない作りにしました。全角のURLも、半角にそろえてから確認します。
- 縦線。 この仕組みは、宿がカレンダーに書いた予定を読んで受付を止めます。コードの調査では、お名前に縦線と受付停止を示す文字を入れると、予約の予定を受付停止の予定として読み違える問題が見つかりました。お名前・ご住所・ご要望の縦線を受け付けない処理と、予約の予定を受付停止と読まない処理を入れました。
- 式の書き込み。 予約の控えをスプレッドシートへ書くとき、式として読まれる文字で始まる入力には、先頭にアポストロフィを付けて文字として扱う処理を入れました。先頭が
=の値を式として扱う仕様は、Apps Scriptの公式資料で確認しています。 - 改行とタブ。 空白へ置き換えます。ご要望の欄だけは改行を残します。
- メールの件名。 宿への通知メールの件名からお名前を外しました。外部からの入力をメールのヘッダーに使わない対策は、IPAの資料を参考にしました。
- アクセス記録。 画面を開く・空きを見る・料金を出す・予約を送る操作について、結果とかかった時間をスプレッドシートの別シートに1行ずつ残す作りにしました。このアクセス記録には個人情報を入れません。
文字数の上限は、予約画面の入力欄にも設定しました。画面を通さず直接送られる場合に備え、Apps Script側でも入力を確認する処理を入れています。
reCAPTCHAなどのロボット確認は入れていません。調査記録では、ホームページの埋め込み内で動くかを、公式資料では確かめられなかったとしています。動かないと確認したわけではありません。
本番で確認したのは、空き・料金表示とアクセス記録
2026年10月6日、私がコードを本番のApps Scriptに貼り、デプロイ(公開すること)して、予約画面を公開しました。
そのあとClaude Codeが本番で確認したのは、次の2点です。
- カレンダーの予定から、空きと料金が表示されること
- アクセス記録が残ること
本番で予約を送る確認はしていません。これらの確認は、件数の上限や入力内容の制限によって予約を拒否できたことを示すものではありません。
10月12日:予約を別の仕組みに切り替えた
2026年10月12日、宿の予約はCloudflare Workers+D1(プログラムの実行とデータ保存のサービス)で作り直した仕組みに切り替えました。新しい仕組みの要件にも、申込日ごとの受付件数の上限を入れました。
10月14日:作り直した仕組みで断る画面を確認した
2026年10月14日、作り直した予約の仕組みを、Claude Codeにローカル環境(手元のパソコン)で動かしてもらいました。以下の画像と結果は、この仕組みのもので、Apps Scriptの動作確認ではありません。
宿の名前と連絡先は、テスト用の架空のものです。本番やリモートのテスト環境には送っていません。確認メールも送らない設定です。
まず、ご要望の欄にURLを入れて次へ進もうとしました。入力欄の下に「ご要望にURLは入れられません」と出て、先へ進めませんでした。

URLを消して送ると、予約は受け付けられ、予約番号が出ました。この入力で予約が通ることを確認しました。
次に、その日の上限の数まで、別のメールアドレス・電話番号・宿泊日で予約を入れました。そのあと画面からもう1件送ると、予約は登録されませんでした。画面には、受付の終了と、公式LINE・電話への案内が出ました。

画面の公式LINEと電話番号は、テスト用の架空のものです。同じメールアドレス・電話番号ごとの上限は、この確認では試していません。
受付を止めたときの連絡先を確認してみてください
ネット予約やフォームを使っている方は、受付を止めたときの画面に、別の連絡先の案内があるか確認してみてください。
自作の予約画面やフォームの対策を相談したいときは、お問い合わせフォームからどうぞ。
最後まで読んでくださりありがとうございました!




コメント