九月十九號下午,我花了十一分鐘,在一個用 AI 寫出來的會員訂單查詢頁上,看到五十個陌生人的收件地址和手機號碼。我沒有破解密碼,也沒有裝任何工具。我只是把網址最後面的 10001 改成 10002,然後一路改到 10050。

那是一家做寵物保健食品的電商,一年營業額三千多萬。老闆的姪子剛畢業,暑假用 AI 幫公司寫了幾個小東西,其中一個是讓會員自己查訂單進度,省掉客服每天回二十幾通「我的貨到哪了」。頁面做得不錯,手機上看也順。上線三週,沒出事。

老闆找我本來是談別的事。我們在會議室聊到一半,我隨口說那個查詢頁給我看一下。

看完之後我們兩個都沒說話。

所以回到那個問題:Codex 或任何 AI 寫程式的工具,會不會寫出有資安漏洞的程式?會。但這句話講完等於沒講,因為人寫的程式也會。

真正值得花時間想的是另一件事。AI 產出的洞,跟人寫出來的洞,性質不一樣。

人寫錯,多半是知道該做但忘了做,或者做得不夠嚴。AI 產出的洞,多半是因為沒有人要求它做。你跟它說「幫我做一個頁面,讓會員輸入訂單編號就能查進度」,它就做了一個頁面,讓任何人輸入任何訂單編號都能查進度。它完全照做,一個字都沒錯。

這是我覺得最要命的地方。它不會跟你說「你好像少講了一件事」。

我看過最常重複的三種

第一種就是上面那個,權限檢查整個不存在。程式知道怎麼把資料撈出來,但沒有人告訴它要先確認「問的這個人有沒有資格問」。

第二種,金鑰放在看得到的地方。API key 直接寫在前端的 JS 裡,或者 .env 檔跟著 commit 進 git 推上公開的 repo。我遇過一家做線上課程的,金流的測試金鑰在公開 repo 裡躺了四個月才被發現。沒出事,運氣好而已。

第三種,使用者打的字直接送進資料庫查詢或系統指令。這個現在比以前少,因為主流框架大多預設擋掉了,但手寫拼字串的小工具還是常中。

我自己陪跑過的案子裡,用 AI 寫的內部小工具,十個大概六個有第一種問題。不是 AI 笨,是需求裡從來沒人提。

風險多大,看兩個條件就好

我不希望你看完這篇就全面緊張,那沒必要,也沒幫助。判斷其實只要問兩個問題:

這東西有沒有公開網址,外面的人連得到嗎?

它碰不碰得到別人的個資、帳務、或是可以被改動的資料?

兩個都是,嚴肅處理,排到本週。只有一個,排進待辦。兩個都不是,比如只在你自己電腦上跑、把三十個 Excel 併成一張表的腳本,放輕鬆,你擔心的程度超過實際風險很多。

中小企業用 AI 寫的東西,大部分落在最後這類:報表整理、檔名批次處理、把 PDF 轉成表格。這些寫壞了頂多檔案亂掉,還原備份就好。真正要盯的是那一小撮掛在公開網址上、而且碰得到客戶資料的。那家寵物電商的查詢頁,正好兩個條件都中。

把攻擊者請進 prompt 裡

我現在固定讓學員做兩件事。

第一件,寫需求的時候就把限制講出來,不要等東西做完再補。需求結尾加這段:這個頁面會公開在網路上,每一個查詢都要先確認登入者身分、只能查自己的資料,所有使用者輸入都要驗證,不要把任何金鑰寫在前端。

第二件,東西做完,開一個全新的對話,把程式碼貼進去,換一個身分問它:你現在是一個想偷資料的人,這段程式碼公開在網路上,列出你會嘗試的五種攻擊方式,每一種說明你會怎麼做、會拿到什麼,不要修程式碼,只要攻擊清單。

為什麼要開新對話?因為在同一個對話裡,它剛寫完這段程式,語境上會傾向幫自己說話。換個乾淨的對話、換個身分,答案的銳利程度差很多。這是我試過幾十次之後的體感,講不出什麼原理,但差異很明顯。

還有一個更土的方法,不懂程式也能做:瀏覽器按 F12,切到 Network,點一次查詢,看它呼叫哪個網址。把網址裡的編號改成別的數字,重新整理。還看得到東西,就是中了。那天我做的就是這件事,十一分鐘。

既濟卦講的其實是這個

這件事讓我想到既濟。六十四卦排到第六十三,水在上火在下,看起來什麼都到位了,是「完成」的卦。但卦辭寫的是:初吉終亂。

我以前覺得這卦很掃興,事情都成了還潑一盆冷水。做企業諮詢之後才慢慢懂,既濟講的不是「完成之後會變壞」,而是「完成的那一刻,你的注意力會離開」。程式跑起來了、頁面上線了、客服電話從二十幾通掉到五六通,所有訊號都在告訴你這件事結束了。

風險就是從那裡開始長的。

繫辭裡那句「安而不忘危」,講的是同一件事,只是口氣比較溫和。

所以我給的建議很單純:東西上線那天,不要只慶祝,順手做一次攻擊者視角的檢查。那是一次性的十分鐘,不是一個要長期維護的工程。

那天離開前,姪子當場把頁面關掉,加了一段驗證,確認登入的會員編號跟查詢的編號是同一個,不同就擋。兩行多一點。

他改完問我:「這樣就夠了嗎?」

我說不一定夠。但你現在會問這個問題了,這比那兩行重要。