Untuk setiap regex 'jahat', apakah ada alternatif yang tidak jahat, atau apakah iblis ada dalam tata bahasa?

16

Rupanya, serangan ReDos mengeksploitasi karakteristik dari beberapa ekspresi reguler (yang berguna) ... pada dasarnya menyebabkan ledakan jalur yang mungkin melalui grafik yang ditentukan oleh NFA.

Apakah mungkin untuk menghindari masalah seperti itu dengan menulis regex 'non-evil' yang setara? Jika tidak (dengan demikian, tata bahasa tidak dapat ditangani di ruang / waktu praktis oleh NFA), pendekatan penguraian apa yang lebih baik? Mengapa?

David Bullock
sumber
Jika saya berhasil menggunakan bahasa teknis yang tepat, itu kecelakaan. Tolong bodohkan jawaban Anda untuk yang non-akademik :-)
David Bullock
1
Saya sebenarnya hanya mencoba menemukan cara praktis untuk menghindari ReDos , dan pertanyaan ini muncul.
David Bullock
Untuk mengulangi pertanyaan Anda (?): Apakah setiap bahasa reguler memiliki ekspresi reguler yang panjangnya dibatasi oleh polinomial dalam jumlah status NFA minimalnya?
A.Schulz
1
@ A.Schulz. Saya kira bukan itu pertanyaannya. Bukan itu cara kerja serangan ReDos. Dalam serangan ReDos, regexp hardcoded ke kode sumber program dan disediakan oleh pengembang, yang dianggap tepercaya. Kemudian, musuh dapat memasok string input, yang cocok dengan program terhadap regexp. Jika musuh dapat menemukan string input yang menyebabkan pencocokan berjalan untuk waktu yang sangat lama, musuh menang. Jadi, kami khawatir tentang input permusuhan, bukan ekspresi reguler permusuhan. (lanjutan)
DW
Akibatnya, saya pikir pertanyaannya adalah sebagai gantinya: Apakah setiap bahasa reguler memiliki ekspresi reguler sehingga mencocokkan string -character dengan ekspresi reguler membutuhkan waktu O ( f ( n ) ) waktu, di mana f ( n ) adalah beberapa tidak-terlalu- fungsi n yang tumbuh dengan cepat (katakanlah, jumlahnya banyak, atau sesuatu seperti itu)? [Kebetulan, formulasi ulang ini memperjelas bahwa jawaban akan tergantung pada algoritma yang digunakan untuk mencocokkan ... seperti yang saya sebutkan dalam jawaban saya.] Ukuran ekspresi reguler sebagai fungsi dari ukuran NFA minimal tidak sangat penting di sini. nHAI(f(n))f(n)n
DW

Jawaban:

14

Itu tergantung pada apakah Anda memiliki ekspresi reguler atau regexp: regexps itu jahat, tetapi ekspresi reguler adalah sesuatu yang indah dan tidak akan pernah mengubah kejahatan pada Anda.

Dengan regexp, maksud saya ekspresi reguler modern: yaitu, ekspresi reguler dengan fitur modern tambahan seperti backreferences - misalnya, ekspresi reguler Perl-kompatibel. Ini lebih kuat daripada ekspresi reguler klasik dari buku teks teori bahasa / automata formal, karena ekspresi reguler klasik tidak mengizinkan referensi, melihat ke belakang, melihat ke belakang, dan sebagainya.

Untuk ekspresi reguler klasik, jika Anda memiliki implementasi yang baik untuk pencocokan, maka tidak ada ekspresi reguler yang terlalu jahat. Secara khusus, algoritma standar untuk pencocokan adalah untuk mengubah ekspresi reguler ke NFA dan kemudian mengeksekusi NFA pada string input. Untuk algoritma ini, waktu menjalankan kasus terburuk untuk menguji string -character adalah O ( n ) , ketika ekspresi reguler diperbaiki. Ini berarti waktu berjalan tidak dapat meledak terlalu cepat. Tidak ada string yang akan menyebabkan peningkatan waktu berjalan yang eksponensial. Jadi, jika Anda menggunakan pencocokan yang menggunakan algoritme ini, tidak ada ekspresi reguler klasik yang akan jahat.nHAI(n)

Ini tergantung pada implementasi pencocokan ekspresi reguler. Jika Anda memiliki implementasi korek yang naif atau buruk, maka pencocokan dapat membutuhkan waktu yang eksponensial; pasti ada algoritma dengan properti itu. Tetapi jawaban terbaik untuk itu mungkin tidak mengubah ekspresi reguler; mungkin lebih baik untuk memilih pencocokan yang lebih baik, jika Anda khawatir tentang serangan penolakan layanan.

Sebagai perbandingan, beberapa regexps modern tidak bisa dihindari jahat. Jika Anda memiliki regexp modern, maka pencocokan dapat memerlukan waktu eksponensial. Secara khusus, regexps dengan backreferences dapat mengenali bahasa NP-hard. Akibatnya, di bawah asumsi yang masuk akal, ada kelas regexps jahat di mana pengujian untuk pertandingan membutuhkan waktu yang eksponensial. Dengan demikian, beberapa regexps modern tidak terhindarkan jahat: tidak ada cara yang layak untuk menemukan regexp setara yang tidak akan menyebabkan ledakan eksponensial dalam menjalankan waktu untuk mencocokkan.

(Setara seperti itu mungkin ada dan bahkan mungkin dapat ditemukan dalam teori, tetapi di bawah asumsi yang masuk akal, menemukan regexp yang setara akan memakan waktu eksponensial, yang dalam praktiknya tidak layak. Jika Anda memiliki prosedur sistematis untuk menemukan regexp yang setara dalam waktu polinomial , maka Anda dapat memecahkan masalah NP-hard dalam waktu polinomial, membuktikan bahwa P = NP. Tidak ada gunanya bagi di sana untuk memiliki regexp yang setara jika tidak ada cara yang benar-benar menemukannya dalam masa hidup Anda.)


Latar belakang dan sumber:

DW
sumber
Bukankah lebih mudah untuk menemukan alternatif yang tidak jahat dengan memecah regex menjadi beberapa regex yang lebih kecil dan menggunakannya dalam kombinasi?
inf3rno
1

Jawaban ini akan mengambil pandangan yang lebih menyeluruh tentang situasi lintas sektor yang tidak biasa ini, di mana teori kompleksitas berlaku untuk cybersecurity dan contohnya berisi beberapa nuansa / kehalusan signifikan yang dapat terjadi di area ini. Ini pada dasarnya mirip dengan "serangan injeksi" di mana input tak terduga tertentu menyebabkan perilaku patologis menabrak sistem atau menyebabkannya memakan waktu lama secara tidak normal.

Wikipedia memiliki 15 kategori serangan Denial of Service dan serangan ini termasuk dalam "banjir tingkat aplikasi" dalam daftar itu. Contoh lain yang agak mirip adalah serangan yang mengisi log aplikasi.

Salah satu perbaikan untuk serangan injeksi adalah "membersihkan input". Perancang aplikasi dapat mengevaluasi ulang jika perlu mengkompilasi regexps sewenang-wenang yang disediakan oleh pengguna yang berpotensi jahat. Hanya dengan menghilangkan ekspresi bersarang di regexp atau batasan serupa lainnya mungkin cukup untuk menghindari serangan ini. Walaupun mereka intrinsik bagi banyak perangkat lunak modern, sejumlah besar fungsi dapat disediakan tanpa mengevaluasi ekspresi reguler. Konteksnya penting, beberapa aplikasi tidak memerlukan keamanan seperti itu.

Pendekatan lain untuk meningkatkan toleransi kesalahan / ketahanan yang berlaku di sini adalah batas waktu ditentukan pada berbagai tingkat tumpukan / hierarki perangkat lunak. Idenya adalah untuk menentukan waktu / cpu atau batas instruksi pada evaluasi ekspresi reguler "rata-rata" dan berakhir lebih awal jika terlampaui. Mereka dapat diimplementasikan dengan solusi khusus tetapi tidak terlalu banyak perangkat lunak atau bahasa pemrograman memiliki batas waktu atau kerangka kerja bawaan untuk tujuan ini.

Berikut adalah contoh yang bagus dari penggunaan timeout untuk meningkatkan toleransi kesalahan dan menunjukkan desain / arsitektur / pov tingkat tinggi untuk mengurangi masalah seperti: Toleransi Kesalahan dalam Volume Tinggi, Sistem Terdistribusi / Netflix. Ini tidak ada yang secara khusus terhubung ke ekspresi reguler tetapi itulah intinya di sini: hampir semua logika level aplikasi dapat masuk ke dalam kerangka kerja ini atau sesuatu yang serupa.

Artikel ini menunjukkan bagaimana melacak kembali secara khusus dapat menyebabkan pencocokan regexp lambat. Regexps memiliki banyak fitur berbeda dan seseorang dapat mencoba untuk mengevaluasi mana yang mengarah pada perilaku terburuk.

Berikut ini adalah survei ilmiah yang bagus tentang topik khusus ini dengan solusi analisis statis yang diajukan:

  • Analisis Statis untuk Ekspresi Runtime Eksponensial Reguler melalui Logika Substruktural / Rathnayake, Thielecke

    Pencocokan ekspresi reguler menggunakan backtracking dapat memiliki runtime eksponensial, yang mengarah ke serangan kompleksitas algoritmik yang dikenal sebagai REDoS dalam literatur keamanan sistem. Dalam makalah ini, kami membangun analisis statis yang baru-baru ini diterbitkan yang mendeteksi apakah ekspresi reguler yang diberikan dapat memiliki runtime eksponensial untuk beberapa input. Kami secara sistematis membangun analisis yang lebih akurat dengan membentuk kekuatan dan produk dari hubungan transisi dan dengan demikian mengurangi masalah REDoS hingga dapat dijangkau. Ketepatan analisis terbukti menggunakan kalkulus substruktural pohon pencarian, di mana percabangan pohon yang menyebabkan ledakan eksponensial ditandai sebagai bentuk non-linearitas.

ay
sumber
Jawaban ini tampaknya bingung tentang beberapa aspek ReDos. 1. ReDoS tidak ada hubungannya dengan serangan injeksi. Serangan injeksi (mis., XSS, injeksi SQL, injeksi perintah, dll.) Sangat berbeda. 2. ReDos bukan tentang regexps berbahaya yang dikirimkan oleh musuh. Biasanya regexp dikodekan dalam program (disediakan oleh pengembang), dan string input dipasok oleh pengguna. Masalahnya tidak dapat dipecahkan secara wajar dengan validasi input, karena biasanya tidak ada kebijakan validasi input jelas yang cukup untuk menghilangkan masalah.
DW
pikir jumlah poin Anda untuk teknis / tata rambut berdasarkan pada ReDos ref & merindukan hutan untuk pohon. yang mirip dengan "serangan injeksi dibuat". jawabannya menunjukkan bahwa ada alternatif untuk menggunakan regexps dalam kode. analisis statis dapat menemukan "regexps jahat". semua poin jawaban valid. kalimat seperti "biasanya regexp dikodekan dalam program (disediakan oleh pengembang), dan string input dipasok oleh pengguna" tidak sama persis dengan penulisan ReDos yang lebih samar di beberapa tempat, dan merujuk pada penyerang jahat, dll. .
vzn