簡體   English   中英

如何將 Web 客戶端限制到某個域?

[英]How to restrict the web client to a certain domain?

我有一個問題,人們正在克隆我的網站前端並模仿從他們自己的域對我的 API 的調用來濫用我的服務。 我想出的解決方案是讓 Angular 客戶端檢查其工作的 URL,對其進行加密並將其作為標頭添加到 API 調用。 混淆 JS 代碼以防止逆向工程。 這樣 API 將收到一個加密的標頭並確保該域是正確的。

所以在客戶端

headers.append(`CustomHeader`, this.encryptDomain());

在服務器端

var domainEncrypted = Request.Content?.Headers?.GetValues("CustomHeader").FirstOrDefault();
var domainPlain = Decrypt(domainEncrypted);
if (domainPlain != myDomain)
{
  return BadRequest();
}

你能幫我提供代碼示例來匹配 JS 和 C# 加密和解密算法嗎? 因此encryptDomain在 JS 端工作,而Decrypt在 C# 端工作。 我知道這不是一個完美的解決方案,但我想嘗試。 如果有人有更好的想法,歡迎您。

編輯:顯然我想要做的是類似於 JScrambler 域鎖定功能

TLDR

在不能/不應該使用 IP 地址白名單的情況下,不可能通過不同的(克隆的)客戶端保證方式阻止與您的 API 通信。

為什么

這樣想吧。 您有一個具有一些識別規則的服務器 - 客戶端應該具有一些將其標記為受信任的標識符。 在您的問題中,它是一個域。

域是可以在 HTTP 標頭或請求正文中傳遞的公共信息,這很容易,但客戶端也很容易替換此信息。

而且,如果您使用任何類型的密碼學來提供更安全的識別機制 - 您只會更難破解它並再次假裝為受信任的客戶端,因為您在客戶端使用的每個機制都可能被黑客逆向工程。 看看這個問題

一種可以用來保證訪問限制的方法是在服務器端使用 IP 地址白名單,因為 IP 地址是 TCP/IP 傳輸級協議的一部分,並且它具有“握手”過程來識別相互通信的點,而且很難替換。 檢查此問題以獲取詳細信息。

所以,你可以做什么?

CORS

設置 CORS 策略是創建受信任的客戶端-服務器通信的第一步。 大多數瀏覽器都支持 CORS 策略,但當然客戶端可能不是瀏覽器。 問題不在於瀏覽器與服務器之間的通信,但我應該提一下,因為瀏覽器也是客戶端。

客戶端加密

您可以使用加密,但我認為沒有任何理由這樣做,因為任何對服務器的請求都可以通過您的合法客戶端(網站)讀取。 因此,即使您對其進行了加密 - 任何人都擁有密鑰和加密算法來假裝為受信任的客戶。 但如果你想...

您需要為每個請求創建唯一的密鑰,以使偽裝者的生活變得更加困難。 要做到這一點,你需要一些成分:

  • 客戶端生成密鑰的公鑰(加密)
  • 混淆密鑰生成JS代碼
  • 用於解密服務器端生成的密鑰的私鑰

JS 端 RSA 加密庫可以很容易地用谷歌搜索( 例如

也可以使用 google 找到混淆庫(像這樣

如果您使用 C# 后端,則可以使用System.Security.Cryptography命名空間來完成服務器端解密。

基本上,您制作的密鑰生成算法越復雜,您制作的代碼就越模糊 - 黑客更難將自己偽裝成受信任的客戶。 但正如我所說,沒有保證完全識別受信任客戶的方法。

您無法阻止人們復制您網站的 FE 資產……它們應該是公開的。 您可以嘗試通過將構建的應用程序拆分為更多塊(使用 Angular 的延遲加載或通過操縱 webpack 的配置)來使其更難。 盡管如此,瀏覽器仍然需要純文本代碼,因此盡管這會使其變得更難一些,但它並不能阻止復制。

當我們為生產構建 Angular 時,它已經通過優化(縮小、搖樹等)進行了代碼混淆。

為了減輕人們濫用您的服務器資源的問題,您需要在后端請求授權和一些誤用檢測方面實施可靠的實踐。

配置CORS將不起作用,因為您報告攻擊者正在使用 BE 代理。

確保您的請求的身份驗證是可靠的。 市場標准方法是使用嵌入在每個請求的Authorization標頭中的JWT有效負載。 它簡單、可靠且資源低廉。

我還建議實施request throttling 但這是一個單獨的問題。

如果您的身份驗證已經可靠,則您需要檢測您的真實用戶何時濫用您的系統。 有許多工具可以監控流量(如azure 的),但沒有“異常流量”的總括定義。 檢測“異常流量”是您需要為系統的具體情況定制的。 一旦你有了一個可以幫助你開始的網絡流量工具。

為您提供幾個解決方案。 首先,您可以通過在服務器上應用CORS策略來阻止。 如果您仍然想從代碼中進行操作,那么您可以像這樣在 c# 中基於主機名進行阻止。

var hostname = requestContext.HttpContext.Request.Url.Host;
if (hostname != myDomain)
{
  return BadRequest();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM