2009-12-24 49 views
40

Tôi có một trang web xử lý "/" và "% 2F" trong phần đường dẫn (không chuỗi truy vấn) của một URL khác nhau. Đây có phải là một điều xấu để làm theo RFC hoặc thế giới thực?Dấu gạch chéo ("/") tương đương với dấu gạch chéo được mã hóa ("% 2F") trong phần đường dẫn của URL HTTP

Tôi hỏi vì tôi tiếp tục gặp phải một chút bất ngờ với khung web tôi đang sử dụng (Ruby on Rails) cũng như các lớp bên dưới (Hành khách, Apache, vd, tôi phải bật "ALLOW_ENCODED_SLASHES" cho Apache) . Bây giờ tôi đang nghiêng về việc loại bỏ các dấu gạch chéo mã hóa hoàn toàn, nhưng tôi tự hỏi liệu tôi có nên nộp báo cáo lỗi mà tôi thấy hành vi kỳ lạ liên quan đến các dấu gạch chéo được mã hóa hay không.

Là tại sao tôi có dấu gạch chéo được mã hóa ở nơi đầu tiên, về cơ bản tôi có các tuyến đường như thế này:

:controller/:foo/:bar 

nơi: foo là một cái gì đó giống như một con đường có thể chứa dấu gạch chéo. Tôi nghĩ rằng điều đơn giản nhất để làm là chỉ cần thoát URL foo để các dấu gạch chéo bị bỏ qua bởi cơ chế định tuyến. Bây giờ tôi đang có nghi ngờ, và nó khá rõ ràng rằng các khuôn khổ không thực sự hỗ trợ này, nhưng theo RFC là nó sai để làm điều đó theo cách này?

Dưới đây là một số thông tin tôi đã thu thập được:

RFC 1738 (URL):

thường một URL có sự giải thích tương tự khi một octet được đại diện bởi một nhân vật và khi nó được mã hóa. Tuy nhiên, điều này không đúng đối với các ký tự dành riêng: mã hóa một ký tự dành riêng cho một lược đồ cụ thể có thể thay đổi ngữ nghĩa của một URL.

RFC 2396 (URI):

Những nhân vật được gọi là "dành riêng", vì việc sử dụng của họ trong phần URI được giới hạn mục đích dự trữ của họ. Nếu dữ liệu cho thành phần URI sẽ xung đột với mục đích được bảo lưu, thì dữ liệu mâu thuẫn phải được thoát trước khi tạo URI.

(không thoát ở đây có nghĩa là một cái gì đó khác hơn là mã hóa các nhân vật reserved?)

RFC 2616 (HTTP/1.1):

nhân vật khác hơn là những người trong "dành riêng" và "không an toàn "bộ (xem RFC 2396 [42]) tương đương với mã hóa" "%" HEX HEX "của chúng.

Ngoài ra còn có this bug report cho Rails, nơi họ dường như mong đợi các dấu gạch chéo được mã hóa để hành xử khác nhau:

Đúng vậy, tôi mong đợi kết quả khác nhau vì họ đang chỉ vào các nguồn lực khác nhau.

Tìm kiếm tệp 'foo/bar' trong thư mục gốc. Phiên bản không thoát được tìm kiếm thanh tập tin trong thư mục foo.

Rõ ràng từ RFC mà nguyên so với được mã hóa tương đương với các ký tự không được đặt trước, nhưng câu chuyện dành cho ký tự dành riêng là gì?

+0

Liên quan: http://stackoverflow.com/q/14631200/1591669 – unor

+0

Người dùng PHP sử dụng bộ điều khiển phía trước: $ _GET & $ _REQUEST đã được mã hóa. Điều này có thể gây ra sự cố với dấu gạch chéo vì bạn sẽ không thể biết dấu gạch chéo là gì và% 2F là gì. Nếu bạn hoàn toàn cần xem yêu cầu khi nó được gửi, hãy xem trong $ _SERVER ['REQUEST_URI']. Xem thêm [urldecode() @ php.net] (http://php.net/manual/en/function.urldecode.php) –

Trả lời

18

Từ dữ liệu bạn thu thập được, tôi có xu hướng nói rằng mã hóa "/" trong uri có nghĩa là được xem là "/" một lần nữa ở cấp ứng dụng/cgi.

Điều đó có nghĩa là nếu bạn đang sử dụng apache với mod_rewrite chẳng hạn, nó sẽ không khớp với mẫu mong đợi bị gạch chéo với URI với các dấu gạch chéo được mã hóa trong đó. Tuy nhiên, khi mô-đun/cgi/... thích hợp được gọi để xử lý yêu cầu, thì tùy thuộc vào nó để giải mã và lấy một tham số bao gồm các dấu gạch chéo làm thành phần đầu tiên của URI.

Nếu ứng dụng của bạn sau đó sử dụng dữ liệu này để truy xuất tệp (tên tệp có dấu gạch chéo), đó có thể là một điều xấu.

Tóm lại, tôi thấy nó hoàn toàn bình thường khi thấy sự khác biệt về hành vi trong "/" hoặc "% 2F" khi diễn giải của chúng sẽ được thực hiện ở các cấp độ khác nhau.

+0

Đây là khá nhiều những gì tôi đã suy nghĩ quá. Thật không may có vẻ như không có nhiều hỗ trợ để thực hiện nó theo cách này trong thế giới thực. Tôi sẽ tiếp tục làm việc ngay bây giờ nhưng nếu tôi bắt đầu lại, tôi sẽ thử một cơ chế thoát khác. – user85509

6

Tôi cũng có một trang web có nhiều url với các ký tự được mã hóa url. Tôi thấy rằng nhiều API web (bao gồm các công cụ quản trị trang web của Google và một số mô-đun Drupal) chuyến đi qua các ký tự được mã hóa url. Nhiều API tự động giải mã url tại một số điểm trong quá trình của chúng và sau đó sử dụng kết quả dưới dạng URL hoặc HTML. Khi tôi tìm thấy một trong những vấn đề này, tôi thường tăng gấp đôi mã hóa kết quả (biến% 2f thành% 252f) cho API đó. Tuy nhiên, điều này sẽ phá vỡ các API khác mà không mong đợi mã hóa kép, vì vậy đây không phải là một giải pháp phổ quát.

Cá nhân tôi đang loại bỏ càng nhiều ký tự đặc biệt trong URL của mình càng tốt.

Ngoài ra, tôi đang sử dụng số id trong URL của tôi mà không phụ thuộc vào urldecoding:

example.com/blog/my-amazing-blog%2fstory/yesterday

trở thành:

example.com/blog/12354/my-amazing-blog%2fstory/yesterday

trong trường hợp này, mã của tôi chỉ sử dụng 12354 để tìm bài viết và phần còn lại của URL bị hệ thống của tôi bỏ qua (nhưng là vẫn được sử dụng cho SEO.) Ngoài ra, số này sẽ xuất hiện TRƯỚC KHI URL không được sử dụng mponents. theo cách đó, url sẽ vẫn hoạt động, ngay cả khi% 2f được giải mã không chính xác.

Ngoài ra, hãy đảm bảo sử dụng các thẻ chuẩn để đảm bảo rằng các lỗi url không dịch thành nội dung trùng lặp.

+0

Phương pháp này có vẻ hoạt động khá tốt với reddit.com. – StockB

0

Điều gì sẽ xảy ra nếu :foo ở dạng tự nhiên của nó có dấu gạch chéo? Bạn sẽ không muốn nó không phải là rằng sự khác biệt mà đề xuất đang cố gắng bảo tồn? It specifically notes,

Tương tự như unix và các quy tắc tên tệp hệ điều hành khác nên được coi là hoàn toàn trùng hợp và không được dùng để chỉ ra rằng URI phải được hiểu là tên tệp.

Nếu ai bị xây dựng một giao diện trực tuyến cho một chương trình sao lưu, và muốn bày tỏ những con đường như một phần của đường dẫn URL, nó sẽ làm cho tinh thần để mã hóa các dấu gạch chéo trong đường dẫn tập tin, vì đó là không thực sự là một phần của cấu trúc phân cấp của tài nguyên - và quan trọng hơn là tuyến đường . /backups/2016-07-28content//home/dan/ mất gốc của hệ thống tập tin trong dấu gạch chéo kép. Thoát dấu gạch chéo là cách thích hợp để phân biệt, khi tôi đọc nó.

Các vấn đề liên quan