Có cách nào để đưa mã độc vào một biểu thức thông thường không?


138

Tôi muốn thêm khả năng tìm kiếm biểu thức chính quy vào trang web công cộng của mình. Khác với mã hóa HTML đầu ra, tôi có cần phải làm gì để chống lại đầu vào của người dùng độc hại không?

Các tìm kiếm của Google bị ngập trong những người giải quyết vấn đề ngược - sử dụng các biểu thức thông thường để phát hiện đầu vào độc hại - điều mà tôi không quan tâm. Trong kịch bản của tôi, đầu vào của người dùng một biểu thức chính quy.

Tôi sẽ sử dụng thư viện Regex trong .NET (C #).


4
Điều này có thể phụ thuộc vào ngôn ngữ và / hoặc thư viện regex bạn sử dụng.
aschepler

Một số tài liệu đọc thêm: ReDoS trên OWASP , ReDoS trên Wikipedia
joeytwiddle

Câu trả lời:


216

Từ chối ‐ của Conc Mối quan tâm dịch vụ

Mối quan tâm phổ biến nhất với regexes là sự từ chối ‐ của attack dịch vụ tấn công thông qua các mô hình bệnh lý đi theo cấp số nhân - hoặc thậm chí siêu cấp số mũ! - và vì vậy xuất hiện để mất mãi mãi để giải quyết. Chúng chỉ có thể hiển thị trên dữ liệu đầu vào cụ thể, nhưng người ta thường có thể tạo một dữ liệu trong đó điều này không quan trọng.

Những cái này sẽ phụ thuộc phần nào vào mức độ thông minh của trình biên dịch regex mà bạn đang sử dụng, bởi vì một số trong số này có thể được phát hiện trong thời gian biên dịch. Trình biên dịch Regex thực hiện đệ quy thường có bộ đếm đệ quy ‐ trong bộ đếm độ sâu để kiểm tra sự không tiến triển.

Bài viết xuất sắc năm 2007 của Russ Cox về Kết hợp biểu thức chính quy có thể đơn giản và nhanh chóng (nhưng chậm trong Java, Perl, PHP, Python, Ruby, ...) nói về những cách mà hầu hết các NFA hiện đại, mà tất cả dường như bắt nguồn từ mã của Henry Spencer , bị suy giảm hiệu suất nghiêm trọng, nhưng trong đó một NFA kiểu Thompson không có vấn đề như vậy.

Nếu bạn chỉ thừa nhận các mẫu có thể được giải quyết bằng các DFA, bạn có thể biên dịch chúng theo cách đó và chúng sẽ chạy nhanh hơn, có thể nhanh hơn nhiều. Tuy nhiên, cần có thời gian để làm điều này. Bài viết của Cox đề cập đến phương pháp này và các vấn đề liên quan. Tất cả bắt nguồn từ một giao dịch không gian thời gian cổ điển.

Với DFA, bạn dành nhiều thời gian hơn để xây dựng nó (và phân bổ nhiều trạng thái hơn), trong khi với NFA, bạn dành nhiều thời gian hơn để thực hiện nó, vì nó có thể là nhiều trạng thái cùng một lúc và quay lui có thể ăn bữa trưa của bạn - và CPU của bạn.

Từ chối ‐ của Giải pháp dịch vụ

Có lẽ cách hợp lý nhất để giải quyết những mô hình đang ở cuối cuộc đua với sức nóng cái chết của vũ trụ là bọc chúng bằng một bộ đếm thời gian có hiệu quả đặt thời gian tối đa cho phép thực hiện. Thông thường, điều này sẽ nhiều, ít hơn nhiều so với thời gian chờ mặc định mà hầu hết các máy chủ HTTP cung cấp.

Có nhiều cách khác nhau để thực hiện những điều này, từ đơn giản alarm(N)ở cấp độ C, đến một số try {}loại ngoại lệ loại báo động bắt, tất cả các cách để tạo ra một luồng mới được tạo đặc biệt với một ràng buộc thời gian được tích hợp ngay trong nó.

Mã chú thích

Trong các ngôn ngữ regex thừa nhận các chú thích mã, một số cơ chế cho phép hoặc không cho phép các chuỗi này khỏi chuỗi bạn sẽ biên dịch sẽ được cung cấp. Ngay cả khi các chú thích mã chỉ để mã bằng ngôn ngữ bạn đang sử dụng, bạn nên hạn chế chúng; họ không cần phải gọi mã bên ngoài, mặc dù nếu có thể, bạn đã gặp vấn đề lớn hơn nhiều.

Ví dụ, trong Perl, người ta không thể có các chú thích mã trong các biểu thức được tạo từ phép nội suy chuỗi (vì chúng sẽ được biên dịch trong thời gian chạy) trừ khi pragma có phạm vi từ vựng đặc biệt use re "eval";hoạt động trong phạm vi hiện tại.

Bằng cách đó, không ai có thể lẻn vào một chú thích mã để chạy các chương trình hệ thống như rm -rf *, chẳng hạn. Vì các chú thích mã rất nhạy cảm về bảo mật, Perl sẽ vô hiệu hóa chúng theo mặc định trên tất cả các chuỗi được nội suy và bạn phải tránh ra để kích hoạt lại chúng.

Người dùng Xác định \ P {roperties}

Vẫn còn thêm một vấn đề an ninh nhạy cảm liên quan đến bất động sản Unicode kiểu - như \pM, \p{Pd}, \p{Pattern_Syntax}, hoặc \p{Script=Greek}- đó có thể tồn tại trong một số trình biên dịch regex rằng sự ủng hộ mà ký hiệu.

Vấn đề là trong một số trong số này, tập hợp các thuộc tính có thể là khả năng mở rộng của người dùng. Điều đó có nghĩa là bạn có thể có các thuộc tính tùy chỉnh là các chú thích mã thực tế cho các hàm được đặt tên trong một số tên cụ thể, như \p{GoodChars}hoặc \p{Class::Good_Characters}. Làm thế nào ngôn ngữ của bạn xử lý những người có thể đáng xem.

Hộp cát

Trong Perl, một ngăn hộp cát thông qua Safemô-đun sẽ kiểm soát khả năng hiển thị không gian tên. Các ngôn ngữ khác cung cấp các công nghệ hộp cát tương tự. Nếu các thiết bị như vậy có sẵn, bạn có thể muốn xem xét chúng, bởi vì chúng được thiết kế đặc biệt để thực thi giới hạn mã không tin cậy.


4
Chuyển đổi NFA-> DFA có thể tạo ra vụ nổ trạng thái theo cấp số nhân, biến DoS thời gian thành DoS không gian, cũng như chi phí thời gian để tạo ra số lượng trạng thái theo cấp số nhân.
Barry Kelly

nhưng có lẽ anh ta sẽ không cần toàn bộ khả năng biểu thức chính quy, bạn nghĩ sao về việc hạn chế sức mạnh của các biểu thức thông thường như google đã làm: google.com/intl/en/help/faq_codesearch.html#regapi
systemfault

1
@Bỏ khá đúng. Tôi đã nghĩ về chiến lược của Russ Cox được mô tả trong một trong những bài viết của ông về việc biên soạn dần các phần của NFA thành một DFA tương đương nhưng ném nó đi nếu nó quá lớn. Nhưng không có viên đạn bạc nào trong DFA, ngay cả khi Thompson đã chứng minh nó tương đương với NFA, bởi vì bạn phải trả cho người cầm súng vào lúc này hay lúc khác. Thời gian dành cho hệ điều hành để có thêm không gian và chi phí thiết lập bảng trang tiếp viên, đôi khi có thể làm giảm quy mô cân bằng theo cách khác và làm cho việc chuyển đổi từ thời gian sang không gian trở nên kém hấp dẫn hơn.
tchrist

20

Thêm vào câu trả lời tuyệt vời của tchrist: cùng một người Nga Cox, người đã viết trang "Biểu thức chính quy" cũng đã phát hành mã! re2 là một thư viện C ++ đảm bảo thời gian chạy O (length_of_regex) và giới hạn sử dụng bộ nhớ có thể định cấu hình. Nó được sử dụng trong Google để bạn có thể nhập regex vào tìm kiếm mã google - có nghĩa là nó đã được thử nghiệm trong trận chiến.


2
Quả thực là như vậy. Bạn có thể trao đổi re2 vào công cụ regex của Perl bằng một mô-đun và nó sẽ sử dụng re2 nếu có thể và Perl nếu không. Hoạt động khá tốt.
tchrist


6

Bạn sẽ muốn đọc bài viết này:

Chuyển đổi bối cảnh không an toàn: Cấy các biểu thức chính quy cho khả năng sống sót Bài báo nói thêm về những gì có thể xảy ra với các công cụ biểu thức chính quy (ví dụ PCRE), nhưng nó có thể giúp bạn hiểu bạn đang chống lại điều gì.


1
Đây là một lời khuyên bảo mật về mã regc (3) GNU libc: securityreason.com/achievement_securityalert/93 kịp thời! Ít nhất là trong linux, lỗ hổng rất dễ chứng minh: grep -E ". * {10,} {10,} {10,} {10,} {10,}"
Bruce Ediger

5

Bạn không chỉ lo lắng về sự phù hợp mà còn cả cách bạn thực hiện việc khớp. Ví dụ: nếu đầu vào của bạn trải qua một số loại pha thay thế hoặc lệnh thay thế trên đường đến công cụ biểu thức chính quy, có thể có mã được thực thi bên trong mẫu. Hoặc, nếu cú ​​pháp biểu thức chính quy của bạn cho phép các lệnh nhúng, bạn cũng phải cảnh giác với điều đó. Vì bạn không chỉ định ngôn ngữ trong câu hỏi của mình, thật khó để nói chắc chắn tất cả ý nghĩa bảo mật là gì.


1

Một cách tốt để kiểm tra RegEx của bạn về các vấn đề bảo mật (ít nhất là đối với Windows) là công cụ làm mờ SDL RegEx do Microsoft phát hành gần đây. Điều này có thể giúp tránh xây dựng RegEx xấu về mặt bệnh lý.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.