Tiếng Việt

Công cụ dành cho nhà phát triển · Bộ mã hóa và giải mã URL

Mã hóa URL chưa được khử trùng: các tham số đã giải mã vẫn cần thoát

· Tại sao nó quan trọng

url-encoding bảo vệ xss

Tải trọng được mã hóa theo phần trăm được giải mã trở lại dạng ban đầu sẵn sàng để thoát đầu ra
Hình minh họa vector ToolAcre gốc

Mã hóa phần trăm bảo vệ cấu trúc URL chứ không phải HTML, SQL hoặc shell của bạn. Bài đăng này giải thích lý do tại sao một giá trị được mã hóa chính xác lại trở nên nguy hiểm ngay khi nó được giải mã và lối thoát nào thuộc về đâu.

Tại sao chỉ mã hóa URL không thể ngăn chặn các cuộc tấn công XSS

Tham số "an toàn" có thể chạy tập lệnh nếu được mã hóa để truyền nhưng được giải mã trước khi hiển thị. Hãy xem xét tải trọng XSS như thẻ img với trình xử lý lỗi được mã hóa phần trăm dưới dạng %3Cimg%20src%3Dx%20onerror%3Dalert%281%29%3E. Nếu điều này di chuyển trong URL và được giải mã bằng mã ứng dụng trước khi chèn vào HTML, trình duyệt sẽ thấy đánh dấu ban đầu và thực thi trình xử lý. Mã hóa phần trăm là lớp biểu diễn; không thay đổi mối đe dọa cơ bản.

Tải trọng chỉ an toàn trong quá trình truyền khi nó được mã hóa chuỗi không có ý nghĩa đặc biệt đối với trình phân tích cú pháp HTTP hoặc URL. Khi nó được giải mã, nó lại trở nên nguy hiểm vì trở lại dạng ban đầu. Mỗi bối cảnh xuôi dòng phải áp dụng các quy tắc thoát riêng phù hợp với cách sử dụng dữ liệu. Mã hóa URL không thay thế cho việc thoát HTML, tham số hóa SQL hoặc xử lý đối số shell.

Mã hóa phần trăm dùng để làm gì - giữ cho các dấu phân cách rõ ràng trên dây, không có gì hơn thế

Việc mã hóa phần trăm thực hiện là bảo vệ chính xác cấu trúc URL. Ampersand vẫn là một phần của cú pháp chuỗi truy vấn, không được diễn giải lại dưới dạng dấu phân cách. Dấu gạch chéo không trở thành dấu phân cách đường dẫn. Dấu hỏi không bắt đầu đoạn. Bằng cách mã hóa các ký tự dành riêng dưới dạng %XX, trình phân tích cú pháp xử lý chúng dưới dạng dữ liệu chứ không phải cú pháp. Điều này hiệu quả với một công việc: giữ cấu trúc URL rõ ràng trên dây.

Giải mã đảo ngược chính xác đường một chiều đó. Các byte được khôi phục chính xác là những gì đã được mã hóa, không hơn không kém. HTML-chuỗi nguy hiểm vẫn nguy hiểm, vectơ tiêm SQL vẫn nguy hiểm và lệnh shell vẫn nguy hiểm. Mã hóa phần trăm không phải là xác thực đầu vào, không phải là vệ sinh và không phải là ranh giới bảo mật. Nó chỉ là định dạng đại diện.

Giải mã khôi phục các byte gốc - vì vậy mọi bối cảnh xuôi dòng sẽ thấy lại giá trị thô

Thoát theo ngữ cảnh cụ thể là nơi bảo vệ thực sự hoạt động thực sự. HTML ngữ cảnh cần các thực thể: nhỏ hơn trở thành <, lớn hơn trở thành >, dấu ngoặc kép trở thành ", ký hiệu và trở thành &amp;. Ngữ cảnh SQL cần các truy vấn được tham số hóa để tách cấu trúc khỏi dữ liệu, ngăn chặn kẻ tấn công đột nhập. Ngữ cảnh Shell cần các mảng đối số để tránh phân tách từ và tạo toàn cầu hoàn toàn.

Mỗi bối cảnh có các nhân vật nguy hiểm khác nhau và các quy tắc thoát hiểm khác nhau một cách chính xác. Thực thể HTML vô hại trong truy vấn SQL nhưng vô dụng trong việc bảo vệ ở đó. Dấu gạch chéo ngược ngăn cản việc chèn SQL vào một số cơ sở dữ liệu nhưng không ngăn được các cơ sở dữ liệu khác. Thoát Shell phụ thuộc vào phong cách trích dẫn. Nhà phát triển phải hiểu đích đến trước khi chọn cách xử lý dữ liệu.

Thoát theo ngữ cảnh cụ thể — HTML thực thể để đánh dấu, truy vấn được tham số hóa cho SQL, mảng đối số cho shell

Ví dụ đã hoạt động: tải trọng sau đây từ liên kết đến nhật ký đến trang cho biết nơi phải xảy ra mã hóa và thoát. Liên kết chứa tải trọng XSS được mã hóa dưới dạng tham số truy vấn. Máy chủ nhận được nó vẫn được mã hóa trong nội dung yêu cầu HTTP. Ứng dụng giải mã tham số truy vấn để hiển thị nó trong trang. Nếu không thoát đầu ra, trình duyệt sẽ hiển thị tải trọng dưới dạng HTML và thực thi nó.

Nếu cùng một tham số được ghi vào tệp, mục nhập nhật ký sẽ chứa tải trọng được giải mã rõ ràng. Ứng dụng thứ hai đọc nhật ký, giải mã lại, chèn vào trang HTML mà không thoát. Payload thực hiện lần thứ hai. Ở mỗi bước, bối cảnh sẽ xác định điều gì là an toàn. Quá trình giải mã URL đã an toàn. Lưu trữ tệp đã được an toàn. Nhưng kết quả đầu ra HTML mà không thoát ra sẽ gây tử vong.

Ví dụ hoạt động: theo dõi một tải trọng từ liên kết đến nhật ký đến trang - nơi nó được mã hóa, nơi nó được giải mã, nơi nó phải được thoát

Mã hóa dưới dạng công cụ tránh bộ lọc cho thấy lý do tại sao kẻ tấn công mã hóa kép và trộn chữ hoa chữ thập một cách đáng kể. Nếu tường lửa tìm thẻ img, kẻ tấn công sẽ gửi %3Cimg và hy vọng ứng dụng sẽ giải mã một lần nhưng tường lửa thì không. Nếu xác thực từ chối %3Cimg nhưng cho phép trường hợp khác nhau, các byte giống nhau sẽ giải mã thành cùng một tải trọng. Bảo mật tùy thuộc vào đầu vào được mã hóa khớp mẫu rất dễ vỡ.

Việc giải mã phải chính xác và có thể dự đoán được một cách tuyệt đối. Dạng chuẩn (hex chữ thường, mã hóa đã biết) cho phép chính sách nhất quán nhưng không giải quyết được vấn đề cơ bản. Cách tiếp cận đáng tin cậy duy nhất là cho phép giải mã khi cần thiết và áp dụng lối thoát đầu ra theo ngữ cảnh cụ thể ngay trước khi sử dụng. Giải mã không bao giờ an toàn; chỉ cần thiết cho việc truyền tải.

Mã hóa như một công cụ tránh bộ lọc - tại sao kẻ tấn công mã hóa kép và trộn chữ hoa chữ thường và tại sao việc giải mã phải chính xác

Bảo vệ XSS đầy đủ yêu cầu hiểu rõ các luồng dữ liệu, bối cảnh mà nó đi qua ở mỗi bước, những gì thoát ra khỏi mỗi bối cảnh cần có. Mã hóa URL là một phần nhỏ: chỉ bảo tồn cấu trúc trong quá trình truyền. Nhưng một quân cờ không bao giờ tự nó có khả năng phòng thủ. Nhiều nhà phát triển kết hợp mã hóa với dọn dẹp vì cả hai đều liên quan đến việc thay thế các ký tự nhưng phục vụ các công việc quan trọng hoàn toàn khác nhau.

Tường lửa ứng dụng Web có thể phát hiện các mẫu trong tải trọng yêu cầu, nhưng việc mã hóa dễ dàng tránh được các kỹ thuật khớp mẫu đơn giản. Việc điều chỉnh WAF rất phức tạp và vượt quá khả năng mã hóa URL. Biện pháp bảo vệ đáng tin cậy là việc thoát đầu ra trong mã ứng dụng, kết hợp với xác thực đầu vào sao cho phù hợp với bối cảnh và yêu cầu cụ thể của bạn.

Nội dung này không bao gồm — hướng dẫn phòng thủ XSS đầy đủ hoặc điều chỉnh tường lửa ứng dụng web

Bảo vệ XSS đầy đủ yêu cầu hiểu rõ các luồng dữ liệu, bối cảnh mà nó đi qua ở mỗi bước, những gì thoát khỏi từng bối cảnh cần trong suốt ứng dụng. Mã hóa URL là một phần nhỏ: chỉ bảo tồn cấu trúc trong quá trình truyền. Nhưng một quân cờ không bao giờ tự nó có khả năng phòng thủ. Nhiều nhà phát triển kết hợp mã hóa với dọn dẹp vì cả hai đều liên quan đến việc thay thế các ký tự nhưng phục vụ các công việc quan trọng hoàn toàn khác nhau trong suốt quá trình phát triển.

Kiểm tra tải trọng từ đầu đến cuối để xem vị trí mã hóa và thoát thực sự quan trọng trong toàn bộ quá trình. Dán %3Cimg%20src%3Dx%20onerror%3Dalert%281%29%3E vào bộ giải mã URL và xem nó trở thành chuỗi trông giống như đánh dấu. Sau đó dán kết quả vào bộ thoát thực thể HTML để xem cách trở thành văn bản an toàn. Hai công cụ hiển thị các lớp rõ ràng.

Bài học rút ra: mã hóa cho URL, thoát cho đầu ra — cách bộ mã hóa & giải mã URL và bộ thoát thực thể HTML ngồi cạnh nhau trong một sản phẩm cho hai công việc khác nhau

Điều đáng rút ra là mã hóa và thoát là những mối quan tâm riêng biệt ở các lớp khác nhau hoàn toàn xuyên suốt. Mã hóa URL chỉ bảo vệ cấu trúc được truyền đi. Thoát đầu ra bảo vệ nội dung được hiển thị. Giá trị được mã hóa chính xác vẫn cần thoát đầu ra khi đạt HTML. Chuỗi thoát chính xác không bao giờ cần mã hóa URL nếu không được đưa vào URL.

Áp dụng phòng thủ bên phải ở lớp bên phải một cách chân thực. Không dựa vào mã hóa URL để ngăn chặn các cuộc tấn công XSS. Đừng dựa vào lối thoát HTML để duy trì cấu trúc URL. Hiểu luồng dữ liệu của bạn và áp dụng chuyển đổi thích hợp ở mỗi bước. Bộ mã hóa URL giúp bạn biết chức năng mã hóa; sau đó sử dụng bộ thoát thực thể HTML cho bước đầu ra.