Google Apps Script をセキュアに実行

Google Apps Script ( GAS ) は、デプロイ時の設定によっては、URL を知っていれば誰でもリクエストを送信することが可能です。このままでは、いたずらや間違ったリクエストでも GAS が実行されてしまうため、どうにかして制限を掛けたいと思います。

正しい送信者であることをどうやって GAS に判断させるか

通常、GAS を実行できるユーザを制限したい場合は、デプロイ時にアクセスできるユーザを指定します。 
「自分のみ」、「Google Workspace の組織内の全員」、 「Google アカウントを持つ全員」にすると、Google アカウントの認証と access_token を使ったリクエストが必要になり、連携するアプリケーションの開発が難しくなってしまいます。

「全員」にすると外部のシステムから呼び出すことができます。ですが、この設定では URL を知っていれば誰でも GAS を実行することができてしまいます。URL はブラウザやさまざまなセキュリティーツールのログとして残ってしまうので、アプリケーション開発者以外の人に知られてしまうリスクが残ります。

まず思いつくのはGASとアプリケーション開発者だけが知っている秘密のパスワードを決め、GAS側ではその秘密のパスワードが含まれているか確認する方法です。

しかし秘密なはずなのに、通信内容に含んでしまうと結局は通信ログなどに残ってしまい、秘密の意味がありません。

GAS のコード上で可能なセキュリティ対策の処理として、「パスワード付きハッシュ」や「メッセージ認証コード」と呼ばれる手法があります。

本ブログでは、GAS をセキュアに実行する方法として、簡単に導入できる「パスワード付きハッシュ」手法をご紹介します。 

処理の概要

FileMaker Pro
・GAS と共通のパスワードを外部から見えない場所に保存
・GAS に送信したいデータと共通のパスワードを組み合わせたテキストを MD5 に変換
・生成した MD5 値と GAS に送信したいデータを GAS に送信

GAS
・FileMaker Pro と共通のパスワードを外部から見えない場所に保存
・共通のパスワード と FileMaker Pro から取得したデータを、FileMaker Pro と同じように組み合わせ、 MD5 に変換
・GAS が生成した MD5 値と FileMaker Pro から取得した MD5 値とを評価し、一致するのかを判定
・一致した場合は、GASの処理を進める
・不一致の場合は、GASの処理を中断し FileMaker Pro にエラーのレスポンスを返す

FileMaker Pro から GAS にリクエストを送信

GAS へは今回 GET リクエストを送信します。
そのため、データを GetAsURLEncoded 関数で URL エンコードする必要があります。
処理は以下の通りです。

GET リクエストについては Google Apps Script への GET リクエストによるスプレッドシートデータの取得から….

MD5 値は
「 GAS と FileMaker Pro の共通のパスワード(以降、共通パスワード) : GAS で処理するデータ」
以上のような構成のテキストを GetContainerAttribute 関数により変換した値になります。

例えば、共通パスワード「 kotobukishokai 」、GAS で処理するデータ: 「 1111 」
これらの値で MD5 に変換した値は「2A28F248636608D1F9A482E6E921A4E0」となります。

こうして生成した MD5 の値と GAS で処理するデータで JSON を作成し、URL パラメータとして付与し、GAS へ GET リクエストを送信します。

GAS の処理

FileMaker Pro から受け取った JSON データの “data” と、共通パスワードからFileMaker Pro と同様に MD5 値を生成し、FileMaker Pro で生成した MD5 値 (JSON データの “data”)との一致を見ます。

一致した場合は、そのまま GAS での処理を実行します。
一致しない場合は、処理を中断し、一致しなかったことを FileMaker Pro に返します。

MD5 値を生成するカスタム関数 “MD5”

まとめ

今回は、 Google Apps Script をセキュアに実行する方法をご紹介いたしました。
共通のパスワードを用いた MD5 でやり取りを行うことで、簡易ではありますがセキュアに GAS を実行することが可能です。
この手法も突破されたくない場合は、データにランダムな値を値を入れたり、タイムスタンプを埋め込んだり、またパスワード部分を十分長くしたりなどすることで、よりセキュアにすることができます。