Antipola: Menggunakan penghitung rakus dalam kebijakan RegularExpressionProtection

Anda sedang melihat dokumentasi Apigee dan Apigee Hybrid.
Lihat dokumentasi Apigee Edge.

Kebijakan RegularExpressionProtection menentukan ekspresi reguler yang dievaluasi saat runtime pada parameter input atau variabel alur. Biasanya, Anda menggunakan kebijakan ini untuk melindungi dari ancaman konten seperti injeksi SQL atau JavaScript, atau untuk memeriksa parameter permintaan yang salah format seperti alamat email atau URL.

Ekspresi reguler dapat ditentukan untuk jalur permintaan, parameter kueri, parameter formulir, header, elemen XML (dalam payload XML yang ditentukan menggunakan XPath), atribut objek JSON (dalam payload JSON yang ditentukan menggunakan JSONPath).

Contoh kebijakan RegularExpressionProtection berikut melindungi backend dari serangan injeksi SQL:

<!-- /antipatterns/examples/greedy-1.xml -->
<RegularExpressionProtection async="false" continueOnError="false" enabled="true"
  name="RegexProtection">
    <DisplayName>RegexProtection</DisplayName>
    <Properties/>
    <Source>request</Source>
    <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
    <QueryParam name="query">
      <Pattern>[\s]*(?i)((delete)|(exec)|(drop\s*table)|
        (insert)|(shutdown)|(update)|(\bor\b))</Pattern>
    </QueryParam>
</RegularExpressionProtection>

Antipola

Kuantifier default (*, +, dan ?) bersifat serakah: mereka mulai mencocokkan dengan urutan terpanjang yang mungkin. Jika tidak ada kecocokan, mereka akan mundur secara bertahap untuk mencoba mencocokkan pola. Jika string yang dihasilkan yang cocok dengan pola sangat pendek, penggunaan pengukur serakah dapat memerlukan waktu lebih lama daripada yang diperlukan. Hal ini terutama berlaku jika payload berukuran besar (dalam puluhan atau ratusan KB).

Ekspresi contoh berikut menggunakan beberapa instance .*, yang merupakan operator serakah:

<Pattern>.*Exception in thread.*</Pattern>

Dalam contoh ini, kebijakan RegularExpressionProtection pertama-tama mencoba mencocokkan urutan terpanjang yang mungkin—seluruh string. Jika tidak ditemukan kecocokan, kebijakan akan mundur secara bertahap. Jika string yang cocok berada di dekat awal atau tengah payload, penggunaan pengukur serakah seperti .* dapat memerlukan lebih banyak waktu dan daya pemrosesan daripada pengukur enggan seperti .*? atau (lebih jarang) pengukur posesif seperti .*+.

Pengukur keengganan (seperti X*?, X+?, X??) dimulai dengan mencoba mencocokkan satu karakter dari awal payload dan secara bertahap menambahkan karakter. Pengukur kepemilikan (seperti X?+, X*+, X++) mencoba mencocokkan seluruh payload hanya sekali.

Mengingat contoh teks berikut untuk pola di atas:

Hello this is a sample text with Exception in thread
with lot of text after the Exception text.

Menggunakan .* yang rakus tidak berperforma dalam kasus ini. Pola .*Exception in thread.* memerlukan 141 langkah untuk dicocokkan. Jika Anda menggunakan pola .*?Exception in thread.* (yang menggunakan pengukur keengganan) sebagai gantinya, hasilnya hanya 55 langkah.

Dampak

Menggunakan pengukur serakah seperti karakter pengganti (*) dengan kebijakan RegularExpressionProtection dapat menyebabkan:

  • Peningkatan latensi keseluruhan untuk permintaan API dengan ukuran payload sedang (hingga 1 MB)
  • Waktu yang lebih lama untuk menyelesaikan eksekusi kebijakan RegularExpressionProtection
  • Permintaan API dengan payload besar (>1 MB) gagal dengan Error Waktu Tunggu Gateway 504 jika periode waktu tunggu yang telah ditentukan sebelumnya berakhir di Router Apigee
  • Penggunaan CPU yang tinggi pada Pemroses Pesan karena pemrosesan dalam jumlah besar yang selanjutnya dapat memengaruhi permintaan API lainnya

Praktik terbaik

  • Hindari penggunaan pengukur serakah seperti .* dalam ekspresi reguler dengan kebijakan RegularExpressionProtection. Sebagai gantinya, gunakan pengukur enggan seperti .*? atau pengukur posesif seperti .*+ (kurang umum) jika memungkinkan.

Bacaan lebih lanjut