Antipola: Menggunakan kuantitas serakah 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. Anda biasanya menggunakan kebijakan ini untuk memberikan perlindungan dari ancaman konten seperti injeksi SQL atau JavaScript, atau untuk memeriksa parameter permintaan yang salah format seperti alamat email atau URL.

Ekspresi reguler dapat ditetapkan 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 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

Penghitungan default (*, +, dan ?) pada dasarnya serakah: kuantitas ini mulai mencocokkan dengan urutan terpanjang yang memungkinkan. Jika tidak ditemukan kecocokan, sistem akan mundur secara bertahap untuk mencoba mencocokkan pola. Jika string hasil yang cocok dengan pola sangat singkat, penggunaan penentu yang berlebihan dapat memakan waktu lebih lama dari yang diperlukan. Hal ini terutama terjadi jika payload berukuran besar (dalam puluhan atau ratusan KB).

Contoh ekspresi berikut menggunakan beberapa instance .*, yang merupakan operator serakah:

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

Dalam contoh ini, kebijakan RegularExpressionProtection mencoba mencocokkan urutan terpanjang yang mungkin—seluruh string. Jika tidak ada kecocokan yang ditemukan, kebijakan akan kembali secara bertahap. Jika string yang cocok mendekati awal atau tengah payload, penggunaan pengukur rakus seperti .* dapat membutuhkan lebih banyak waktu dan daya pemrosesan daripada penentu yang enggan seperti .*? atau (lebih jarang) pengukur yang memiliki nilai posesif seperti .*+.

Penghitung enggan (seperti X*?, X+?, X??) dimulai dengan mencoba mencocokkan satu karakter dari awal payload dan menambahkan karakter secara bertahap. Penghitung yang ada (seperti X?+, X*+, X++) mencoba mencocokkan seluruh payload hanya sekali.

Dengan 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.

Dalam kasus ini, penggunaan .* yang berlebihan tidak berperforma baik. Pola .*Exception in thread.* mengambil 141 langkah untuk mencocokkan. Jika Anda menggunakan pola .*?Exception in thread.* (yang menggunakan kuantitas enggan), hasilnya hanya akan menjadi 55 langkah.

Dampak

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

  • Peningkatan latensi keseluruhan untuk permintaan API untuk 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 telah berlalu di Router Apigee
  • Pemakaian CPU yang tinggi pada Pemroses Pesan karena banyaknya pemrosesan yang dapat memengaruhi permintaan API lainnya lebih jauh

Praktik terbaik

  • Hindari penggunaan kuantitatif yang serampangan seperti .* dalam ekspresi reguler dengan kebijakan RegularExpressionProtection. Sebagai gantinya, gunakan kuantifikasi enggan seperti .*? atau kuantifikasi kepemilikan seperti .*+ (lebih jarang) jika memungkinkan.

Bacaan lebih lanjut