beacon 接收端要接住匿名訪客,就必須設成公開可存取,這帶來一組要理解清楚的安全含義。核心觀念是:這個端點的威脅模型不是「資料外洩」,而是「別人拿這個公開端點能做什麼」。先釐清兩個部署設定各自的安全角色,再界定實際的風險範圍。

execute as 與 who has access 的分工

部署 web app 時的兩個設定,一個決定「用誰的權限跑」、一個決定「誰能呼叫」,安全含義不同。

execute as(執行身分)決定程式用誰的權限執行。 選「我」時,任何打進來的請求都以你的身分執行程式——這是必要的,因為匿名訪客沒有你試算表的寫入權,只有用你的身分才寫得進去。它的含義是:這支程式能碰的資料範圍等於你授權給它的範圍(那一張試算表),而不是呼叫者的權限。所以程式裡只該做你願意讓匿名請求觸發的事——doPost 寫一列 log 是安全的,但如果程式裡寫了「刪除整張表」的邏輯,那也會用你的權限被匿名觸發。

who has access(誰可以存取)決定誰能呼叫這個網址。 接匿名 beacon 必須選「所有人」(完全不需登入),這也表示網址一旦洩漏(而它必然公開,見下一段),任何人都能呼叫。這兩個設定合起來的效果是:一個任何人都能觸發、但只會執行你寫的那幾行、且以你的身分操作你授權的那張表的端點。

這個網址必然公開

beacon 端點的網址會被寫進每一頁的 client-side JavaScript,任何人檢視原始碼都看得到。它藏不住,這是 client beacon 架構的本質、不是設定失誤——GA、Cloudflare Web Analytics 那些的收集端點同樣是公開的。所以安全策略不能建立在「保密網址」上,而要建立在「限制這個公開端點能造成的破壞」上。

這也界定了什麼不是風險:別人拿到網址讀不到你的 Sheet,因為 doPost 只做 appendRow 然後回一個固定的 {ok:true},不回傳任何試算表內容;他也碰不到你其他 Google 資料,因為授權範圍只綁那張表。端點是「只能寫、寫入內容固定、回應不洩漏」的,這個形狀本身就把資料外洩排除了。

實際的風險範圍

公開端點的真實風險是騷擾型的,有兩種。髒資料:有人直接對網址 POST 任意內容,往你的 log 塞垃圾列、污染統計。配額消耗:有人狂打這個端點,吃掉你的執行配額,嚴重時排擠正常 beacon(配額的細節見配額、濫用與隱私)。

這兩種風險的共通點是它們不會洩漏或破壞你的資料,只會污染統計或耗資源。對沒沒無聞的個人 blog,攻擊者缺乏動機花力氣灌一個小站的瀏覽計數,實際發生機率低。所以務實的姿態是:先讓公開端點跑著、把「限制破壞範圍」的保護當成「遇到再加」的選項,而不是上線前就必備。具體的防護手段在下一篇。

更新部署不換網址(安全角度)

日常維護會反覆改 doPost,改完要讓 /exec 反映新版本、而網址不變——用「管理部署作業 → 編輯 → 版本選新版本」,不要用「新增部署作業」(那會產生新網址)。這個操作除了避免假故障(見web app 部署模型),也有安全意義:換網址意味著舊網址可能還殘留在快取的頁面裡繼續被打,管理起來多一個要追蹤的公開端點。用同一個部署更新,公開端點就始終只有一個、行為可控。

下一步

存取權限的安全框架清楚後,配額實際會怎麼碰撞、怎麼擋濫用、隱私怎麼守、以及量大到該遷移的訊號,見配額、濫用與隱私