繁體中文

開發者工具 · URL 編碼器和解碼器

在查詢參數中編碼重定向 URL,而不破壞它

· 工作原理

url 編碼 查询参數 安全 oauth

編碼為單一查詢參數值的完整 URL,透過百分比編碼保留結構
原始 ToolAcre 向量圖

將一個 URL 嵌套在另一個 URL 中是百分比編碼最常見的錯誤地方。這篇文章展示了為什麼必須對內部 URL 的 ?、& 和 = 進行編碼、如何編碼以及如何檢查結果。

刪除了一半參數的回傳連結 — 內部 URL 並被外部查詢字串吞沒

刪除一半參數的返回連結是每個開發人員都會遇到的調試模式。使用者登入後,應用程式嘗試重定向到 ?next=https://example.com/page?id=1&user=alice, 並且最終到達 example.com/page?id=1. 內部 URL 中的 & 符號被解析為外部查詢參數之間的分隔符號。兩個具有不同分隔符號的 URL 意味著必須對內部 URL 進行編碼。

當將一個 URL 作為查詢參數嵌套在另一個 URL 中時,該內部位址對於外層來說將成為不透明資料。問號、與號和等號不得被讀取為結構分隔符號。百分比編碼將它們轉換: ?變成 %3F,& 變成 %26,= 變成 %3D。然後,外部解析器將編碼後的字串視為一個參數值。

兩個 URL,兩組分隔符號 — 為什麼內部 URL 只是外部 URL 的一個值

對完整的內部 URL 使用 encodeURIComponent 可提供完整保護:encodeURIComponent("https://example.com/a?b=1&c=2") 會傳回 "https%3A%2F%2Fexample.com%2Fa%3Fb%3D1%26c%3D2"。每個結構字元都會變成 %XX 表示法,因此外部剖析器不會誤解巢狀分隔符號。encodeURI 等替代方法會保留斜線與問號,當結果成為查詢值時會再次產生歧義。

伺服器僅解碼一次。提取下一個參數後,單一decodeURIComponent 呼叫會將內部URL 恢復為其原始形式。將結果解析為新的查詢字串,然後看到正確的參數結構。當同一個值經過多層時,雙重解碼是一種風險; %26 在一次解碼後變為 &,並在第二次解碼後保持 &。

對整個內部 URL 進行encodeURIComponent — 編碼什麼內容,包括:、/ 和?

基本規則很簡單:任何在 URL 語法中有意義的字符,包括 : / ? = & #,出現在查詢參數值中時必須採用百分比編碼。這可確保外部解析器僅看到您想要的參數結構,而不會看到您傳遞的值中隱藏的任何意外分隔符號。使用encodeURIComponent來完整可靠地處理這種編碼。

在 URL 編碼器和解碼器中測試此編碼:貼上內部 URL,以值模式對其進行編碼,觀察 %XX 輸出。使用解碼器模式驗證往返是否完全匹配。該工具演示了端到端編碼,因此您可以放心地將結果直接複製到您的應用程式程式碼中。

工作範例:正確建構 ?next=https://example.com/a?b=1&c=2 — 編碼字串和伺服器端解碼

關鍵的安全邊界與編碼並存。伺服器必須驗證解碼後的目標實際上可以安全地重定向到。百分比編碼使 URL 結構明確;它不會使任意 URL 變得安全。當應用程式盲目遵循使用者提供的 URL 時,就會出現開放重定向漏洞。驗證需要明確的許可名單、網域驗證或使用者確認。

編碼修復了解析問題;驗證修復了安全性問題。這些是不同層面的單獨關注點。 URL 編碼器和解碼器示範了正確的編碼。伺服器必須新增驗證:對照清單進行檢查、驗證網域或要求確認。如果沒有驗證,正確編碼的重定向到任何網域仍然可以被利用。

開放重定向風險 - 為什麼伺服器必須驗證解碼的目標,而不僅僅是解碼它

常見錯誤累積於此。開發人員有時只對查詢部分進行編碼,而不修改斜杠,這會破壞結構。其他人對整個構造參數進行編碼,包括 ?next=,從而創建雙重編碼。有些透過解析而不解碼來檢查有效性,誤讀編碼結構。使用encodeURIComponent 進行建置可確保每種情況下的一致性和正確性。

另一個常見錯誤是相信瀏覽器會自動修復格式錯誤的參數。 URL 是資料,必須嚴格遵守資料。 encodeURIComponent 是這項工作的標準工具。 URL 編碼器和解碼器將此過程保留在本機,以便您可以在交付生產之前驗證確切的位元組。

常見錯誤 - 僅對查詢部分進行編碼,或相信瀏覽器可以修復它

OAuth redirect_uri 參數完全遵循相同的模式。授權伺服器將控制權傳遞給已知位址的用戶端,通常是帶有多個參數的完整 URL。將其編碼為單一值可確保參數在傳輸中保存下來,並用戶端在使用前解碼一次。 OAuth 流中的編碼處理不當會導致令牌和回呼參數在傳輸過程中消失。

OAuth 中的狀態參數使用編碼與加密簽章結合來實現 CSRF 保護。片段標識符保留在客戶端,永遠不會傳輸到伺服器。無論編碼為何,承載權杖都絕對不能放置在重新導向 URL 中,因為 URL 出現在日誌、瀏覽器歷史記錄和參考標頭中。

這不包括什麼 - OAuth 狀態參數和 CSRF 保護設計

測試策略:使用真實參數建構內部 URL,將其編碼為外部值,並在接收代碼中解碼。驗證解碼結果與原始結果逐字節相同。在生產部署之前使用 URL 編碼器和解碼器。檢查網路流量和日誌以確認正確到達並編碼資料沒有被截斷或損壞。

像 %2e 而不是 %2E 這樣的拼字錯誤可能會正確解碼,但在期望一致性的輔助系統中無法進行往返檢查。不同平台上的庫之間的編碼不匹配很少見,但也是可能的;測試完整的往返行程可以在它們引起生產問題和客戶投訴之前發現它們。

重點:將內部 URL 視為資料 — URL 編碼器和解碼器的單值模式如何對其進行完整編碼及其解碼器如何確認往返

編碼邊界很清晰:encodeURIComponent 將您的輸入視為不透明資料,並轉義除未保留的標點符號之外的每個字符,從而可以安全地嵌套在任何 URL 層中。驗證邊界是分開的:解碼後,驗證目的地是使用者打算去的地方。使用 URL 編碼器和解碼器查看端到端的編碼演示。

從一開始就將內部 URL 視為資料。將其編碼為單一查詢值,在收到時解碼一次,然後在重定向之前套用驗證。 URL 編碼器和解碼器將任何完整 URL 的百分比編碼顯示為單一查詢值,並在本機上驗證往返。編碼和驗證都是必不可少的;該工具可以正確處理編碼。