Antipola: Menggunakan kuantitas serakah dalam kebijakan RegularExpressionProtection

Anda sedang melihat dokumentasi Apigee Edge.
Buka Dokumentasi Apigee X.
info

Kebijakan RegularExpressionProtection menentukan ekspresi reguler yang dievaluasi di runtime pada parameter input atau variabel alur. Anda biasanya 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 ditetapkan untuk jalur permintaan, parameter kueri, parameter formulir, header, elemen XML (dalam payload XML yang ditentukan menggunakan XPath), atribut objek JSON (dalam JSON payload yang ditentukan menggunakan JSONPath).

Contoh kebijakan RegularExpressionProtection berikut melindungi backend dari SQL serangan injection:

<!-- /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>

Anti-pola

Perhitung default (*, +, dan ?) bersifat serakah dalam alami: mereka mulai sesuai dengan urutan terpanjang. Jika tidak ditemukan kecocokan, mundur secara bertahap untuk mencoba mencocokkan pola. Jika {i>string<i} yang dihasilkan cocok dengan pola tersebut adalah sangat singkat, maka penggunaan {i>greedy quantifiers<i} bisa memakan waktu lebih banyak daripada yang diperlukan. Hal ini terutama benar (true) jika payload-nya besar (dalam puluhan atau ratusan KB).

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

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

Dalam contoh ini, kebijakan RegularExpressionProtection terlebih dahulu mencoba mencocokkan kecocokan terpanjang urutan—seluruh string. Jika tidak ditemukan kecocokan, kebijakan akan kembali secara bertahap. Jika {i>string<i} yang cocok berada dekat dengan awal atau tengah payload, maka gunakan greedy quantifier seperti .* dapat memerlukan lebih banyak waktu dan daya pemrosesan daripada enggan penentu seperti .*? atau (lebih jarang) perhitung kepemilikan seperti .*+.

Perhitung enggan (seperti X*?, X+?, X??) mulai dengan mencoba untuk mencocokkan satu karakter dari awal {i>payload<i} dan secara bertahap menambahkan karakter. Perhitungan positif (seperti X?+, X*+, X++) mencoba mencocokkan seluruh {i>payload<i} hanya sekali.

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

Penggunaan .* greedy tidak berperforma baik dalam kasus ini. Polanya .*Exception in thread.* membutuhkan 141 langkah untuk mencocokkan. Jika Anda menggunakan pola .*?Exception in thread.* (yang menggunakan penghitung enggan), hasilnya akan hanya 55 langkah.

Dampak

Menggunakan penghitung 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 (>1MB) gagal dengan 504 Gateway Timeout Errors jika periode waktu tunggu yang telah ditentukan berlalu di Router Edge
  • Pemakaian CPU yang tinggi pada Pemroses Pesan karena banyaknya pemrosesan yang dapat memengaruhi permintaan API lainnya

Praktik terbaik

  • Hindari menggunakan penghitung serakah seperti .* dalam ekspresi reguler dengan Kebijakan RegularExpressionProtection. Sebagai gantinya, gunakan perhitung enggan seperti .*? atau perhitung kepemilikan seperti .*+ (lebih jarang) di mana pun sebaik mungkin.

Bacaan lebih lanjut