Masalah Penolakan Layanan
Perhatian yang paling umum dengan regex adalah serangan penolakan layanan melalui pola patologis yang bersifat eksponensial - atau bahkan super eksponensial! - dan tampaknya butuh waktu lama untuk dipecahkan. Ini hanya dapat muncul pada input data tertentu, tetapi umumnya dapat membuat satu di mana ini tidak masalah.
Yang mana ini akan tergantung pada seberapa pintar kompiler regex yang Anda gunakan kebetulan, karena beberapa di antaranya dapat dideteksi selama waktu kompilasi. Kompiler regex yang menerapkan rekursi biasanya memiliki penghitung kedalaman rekursi built-in untuk memeriksa non-progresi.
Makalah Russ Cox 2007 yang luar biasa tentang Pencocokan Ekspresi Reguler Dapat Sederhana dan Cepat (tetapi lambat di Jawa, Perl, PHP, Python, Ruby, ...) berbicara tentang cara NFA paling modern, yang semuanya tampaknya berasal dari kode Henry Spencer , mengalami penurunan kinerja yang parah, tetapi di mana NFA gaya Thompson tidak memiliki masalah seperti itu.
Jika Anda hanya mengakui pola yang dapat dipecahkan oleh DFA, Anda dapat mengkompilasinya seperti itu, dan mereka akan berjalan lebih cepat, mungkin jauh lebih cepat. Namun, perlu waktu untuk melakukan ini. Makalah Cox menyebutkan pendekatan ini dan masalah yang menyertainya. Semuanya bermuara pada pertukaran ruang-waktu klasik.
Dengan DFA, Anda menghabiskan lebih banyak waktu untuk membangunnya (dan mengalokasikan lebih banyak status), sedangkan dengan NFA Anda menghabiskan lebih banyak waktu untuk mengeksekusinya, karena itu dapat berupa beberapa negara sekaligus, dan melakukan backtracking dapat memakan makan siang Anda - dan CPU Anda.
Solusi Penolakan Layanan
Mungkin cara yang paling masuk akal untuk mengatasi pola-pola ini yang berada di ujung yang kalah dari perlombaan dengan kematian-panas alam semesta adalah dengan membungkusnya dengan sebuah pengatur waktu yang secara efektif menempatkan jumlah waktu maksimum yang diizinkan untuk dieksekusi. Biasanya ini akan jauh, jauh lebih sedikit daripada batas waktu default yang disediakan oleh sebagian besar server HTTP.
Ada berbagai cara untuk mengimplementasikannya, mulai dari yang sederhana alarm(N)
di level C, hingga semacam try {}
memblokir pengecualian tipe alarm tangkapan, semua cara untuk memunculkan thread baru yang secara khusus dibuat dengan batasan waktu yang dibangun tepat di dalamnya.
Panggilan Kode
Dalam bahasa regex yang menerima panggilan kode, beberapa mekanisme untuk membolehkan atau melarang ini dari string yang akan Anda kompilasi harus disediakan. Meskipun panggilan kode hanya untuk kode dalam bahasa yang Anda gunakan, Anda harus membatasi mereka; mereka tidak harus dapat memanggil kode eksternal, meskipun jika mereka bisa, Anda punya masalah yang jauh lebih besar.
Sebagai contoh, di Perl seseorang tidak dapat memiliki kode panggilan dalam regex yang dibuat dari interpolasi string (seperti yang akan terjadi, seperti yang dikompilasi selama waktu run-time) kecuali pragma use re "eval";
dengan cakupan leksikal khusus aktif dalam lingkup saat ini.
Dengan begitu, tidak ada yang bisa menyelinap masuk dalam kode panggilan untuk menjalankan program sistem seperti rm -rf *
, misalnya. Karena pemanggilan kode sangat peka terhadap keamanan, Perl menonaktifkannya secara default pada semua string yang diinterpolasi, dan Anda harus keluar dari cara Anda untuk mengaktifkannya kembali.
User-Defined \ P {roperties}
Masih ada satu masalah keamanan yang sensitif yang berkaitan dengan sifat Unicode-gaya - seperti \pM
, \p{Pd}
, \p{Pattern_Syntax}
, atau \p{Script=Greek}
- yang mungkin ada di beberapa kompiler regex bahwa dukungan yang notasi.
Masalahnya adalah bahwa dalam beberapa di antaranya, sekumpulan properti yang mungkin dapat dikembangkan pengguna. Itu berarti Anda dapat memiliki properti khusus yang merupakan panggilan kode aktual ke fungsi-fungsi yang disebutkan dalam beberapa ruang nama tertentu, seperti \p{GoodChars}
atau \p{Class::Good_Characters}
. Bagaimana bahasa Anda menangani hal-hal itu mungkin layak dilihat.
Kotak pasir
Di Perl, kompartemen kotak pasir melalui Safe
modul akan memberikan kontrol atas visibilitas namespace. Bahasa lain menawarkan teknologi kotak pasir serupa. Jika perangkat tersebut tersedia, Anda mungkin ingin melihatnya, karena mereka dirancang khusus untuk eksekusi terbatas kode yang tidak dipercaya.