我的部落格這半年來不知為何被印尼的廣告留言廠商盯上,三不五時會跑來留一些印尼文垃圾留言(大多是吃角子老虎、線上賭場... 之類博弈類廣告,但有次是升學求職家教,跨度挺大),頻率一週一兩次,每次會隨機挑五六篇留言,每則間隔一兩分鐘,印尼文居多,但也看過一兩次英文版。

推測對方有花了點心思,破解掉我防君子不防小人的陽春版加減計算 CAPTCHA,想說既然投資了就要定期採收。我推測是機器人的理由是 - 對方只管貼,根本沒注意到我加了審核關卡,貼了沒人看得到是在貼心酸?

想了一些防堵手法。

用 ChatGPT 判斷?酷歸酷,但有成本考量。

依據來源 IP 的留言時間隔判斷?有誤判可能,讀者馬上留言補充還挺常見,我自己就常這樣。

評估使用機器學習演算法(隨機森林、支援向量機、貝式分類)及自定義啟發式演算法(N-Grams),蒐集網路垃圾留言進行訓練,建立 AI 阻擋機制... (別鬧了)

最後,決定別把簡單的事複雜化搞死自己,回歸傳統把 reCAPTCHA 裝起來吧。動手前,向兩位有重度 CAPTCHA 使用經驗的前輩請益,小熊子推薦我一個新選項 - hCaptcha

看了一下,hCaptcha 使用方式宇宙無敵簡單,用 Github 或 Google 帳號註冊,新增站台取得 Site Key (免費方案一個月一百萬次,不用鎖定網域名稱),在個人設定可查到 Secret。

前端只要加兩行:

<script src="https://js.hcaptcha.com/1/api.js" async defer></script>

<form>
    <div class="h-captcha" data-sitekey="your_site_key"></div>
</form>

POST 表單回 ASP.NET Core 時,會自動加送一個 h-captcha-response 參數,用 Request.Form 讀取以 application/x-www-form-urlencoded 格式送出 Secret 及 Token,由回傳 JSON 的 success 屬性 true/false 判斷即可,比 reCaptcha 簡單許多。用 ASP.NET Core 寫的話,大約會像這樣:
(讓我想到 Angular 跟 Vue 的風格差異,Angular 架構完整考慮嚴謹,堪稱教科書等級,但有時我沒有要蓋 101,只想搭間小屋快點有地方遮蔭 😄)

var hcatpchaToken = Request.Form["h-captcha-response"];
try
{
   if (string.IsNullOrEmpty(hcaptchaToken)) 
        throw new ApplicationException("Please fill hCaptcha ");
   var form = new Dictionary<string, string>
   {
       { "secret", _your_hcaptcha_secret_ },
       { "response", hcatpchaToken }
   };
   var res = await httpClientSinglton.PostAsync("https://hcaptcha.com/siteverify",
       new FormUrlEncodedContent(form));
   res.EnsureSuccessStatusCode();
   var json = await res.Content.ReadFromJsonAsync<Dictionary<string, object>>();
   if (!((System.Text.Json.JsonElement)json["success"]).GetBoolean()) 
        throw new ApplicationException("Failed to pass hCaptcha");
}
catch (Exception ex)
{
   throw new ApplicationException("hCaptcha error: " + ex.Message);
}

總之,大會報告:部落格留言的防機器人檢查我換成 hCaptcha 了(原本想同時保留加減運算的,雙重 CAPTCHA 效果加倍,但怕造成新同學混淆作罷),大家如果有遇到什麼困難請再回報。

Due to spam comments, I decide to replace my blog captcha to hCaptcha


Comments

# by Trrry

想詢問有考慮cloud flare 機器人驗證嗎?

# by 小熊子

謝謝黑大~ (阿母~我的名字上了資訊科技第一名的網站~)

# by Jeffrey

to Trrry, 指 Cloudflare Turnstiles? https://www.cloudflare.com/zh-tw/products/turnstile/ FB 貼文也有讀者推薦,已列入口袋名單。

# by longer

to Trrry, Cloudflare Turnstiles,Server Side驗證,token="" and secret="",還是"StatusCode":200, 要如何判斷驗證是否正確?

# by longer

var token = "";// Request["cf-turnstile-response"]; var ip = Request.UserHostAddress; string secretKey = ""; var formData = new MultipartFormDataContent(); formData.Add(new StringContent(secretKey), "secret"); formData.Add(new StringContent(token), "response"); formData.Add(new StringContent(ip), "remoteip"); var url = "https://challenges.cloudflare.com/turnstile/v0/siteverify"; var client = new HttpClient(); //formData要用PostAsJsonAsync var response = await client.PostAsJsonAsync(url, formData); if (!response.IsSuccessStatusCode) { debug += "非機器人驗證失敗!";// JsonConvert.SerializeObject(response); } 上面的判斷,總是不會出現失敗!

# by longer

參考黑大的寫法,已解決! Cloudflare Turnstiles的優點可以不用每次強迫點圖形驗證,hCaptcha要付費才行。 同樣的缺點,Turnstiles依官方文件設定appearance,卻不會強迫要點圖形後才能驗證。

# by AK47Twn

hCAPTCHA不能綁定域名~ Hacker直接拿你的SiteKey分分鐘就可以把額度耗盡byPass.

# by Jeffrey

to AK47Twn, 有相關資料可參考嗎?我還以為額度是依後端上傳 secret 及 response 呼叫 API 次數計算。

# by Terry

如果還是被破解 那就只能考慮看看google v2的9宮格驗證了?

# by AK47Twn

https://docs.hcaptcha.com/ 其端要Passkey打到API就會收費. 所以如果SiteKey/API不能綁URI,直接拿SiteKey打到爆就可以~ 帶是你是要做公開網頁的SiteKey一定是公開的~ 不管Google reCAPTCHA Enterprise, hCAPTCHA都是有現成破解方案. 由付費破解的收費reCAPTCHA ENTERPRISE > hCAPTCHA > reCATPTCHA community就可以知道保護力 只是hCAPTCH更簡單可以針對低費率打到爆或是讓你企業成本案成報暴增~ Google reCAPTCHA可以直上Enterprise因為都是一百萬個不用錢.支援也更多. reCAPTCHA Community沒有真正的Mobile SDK (Android有一個安全SDK有內建但是要停止了)而且超過 1M直接棄守~ Cloudflare的問題也是沒有Mobile SDK. reCAPTCHA Ent只提供評分,不會有放行阻擋動作,要後端自行處理.如果有過高過低分要打API去訓練模型(也要算額度). 某h作為安全性工具反而沒有安全功能是有點神奇,不要問我為什麼知道. 暗黑版:reCAPTCHA的1M是用Billing Account分,同一個Project/SiteKey可以隨時切換Billing Account完全不會影響運作... DDDD (懂的都懂) 真的不要問我怎麼知道的

Post a comment