Antipattern: در خط مشی RegularExpressionProtection از کمیت سازهای حریص استفاده کنید

شما در حال مشاهده اسناد Apigee Edge هستید.
به مستندات Apigee X بروید .
اطلاعات

خط مشی RegularExpressionProtection عبارات منظمی را تعریف می کند که در زمان اجرا بر روی پارامترهای ورودی یا متغیرهای جریان ارزیابی می شوند. شما معمولاً از این خط‌مشی برای محافظت در برابر تهدیدات محتوا مانند تزریق SQL یا جاوا اسکریپت یا بررسی پارامترهای درخواستی نادرست مانند آدرس‌های ایمیل یا URL استفاده می‌کنید.

عبارات منظم را می توان برای مسیرهای درخواست، پارامترهای پرس و جو، پارامترهای فرم، سرصفحه ها، عناصر XML (در یک بار XML که با استفاده از XPath تعریف شده است)، ویژگی های شی JSON (در یک بار JSON که با استفاده از JSONPath تعریف شده است) تعریف کرد.

مثال زیر خط مشی RegularExpressionProtection پشتیبان را از حملات تزریق 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>

ضد الگو

کمیت‌کننده‌های پیش‌فرض ( * ، + و ? ) ذاتاً حریص هستند: آنها شروع به تطبیق با طولانی‌ترین دنباله ممکن می‌کنند. هنگامی که هیچ منطبقی یافت نشد، آنها به تدریج به عقب برمی‌گردند تا با الگو مطابقت داشته باشند. اگر رشته منطبق با الگو بسیار کوتاه باشد، استفاده از کمیت‌کننده‌های حریصانه می‌تواند بیش از حد لازم زمان ببرد. این امر به ویژه در صورتی صادق است که محموله بزرگ باشد (در ده ها یا صدها کیلوبایت).

عبارت مثال زیر از چندین نمونه از .* استفاده می کند که عملگرهای حریص هستند:

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

در این مثال، خط مشی RegularExpressionProtection ابتدا سعی می کند طولانی ترین دنباله ممکن را مطابقت دهد - کل رشته. اگر مطابقت پیدا نشد، این خط‌مشی به تدریج عقب‌نشینی می‌کند. اگر رشته تطبیقی ​​نزدیک به شروع یا وسط بار باشد، استفاده از یک کمیت‌گر حریص مانند .* می‌تواند زمان و قدرت پردازش بسیار بیشتری نسبت به واجد شرایط بی‌میل مانند .*? یا (به طور معمول) کمیت کننده های مالکیتی مانند .*+ .

کمیت‌کننده‌های بی‌میل (مانند X*? , X+? , X?? ) با تلاش برای مطابقت با یک کاراکتر از ابتدای بار شروع می‌شوند و به تدریج کاراکترها را اضافه می‌کنند. کمیت‌کننده‌های دارای مالکیت (مانند X?+ ، X*+ ، X++ ) فقط یک بار سعی می‌کنند کل محموله را مطابقت دهند.

با توجه به متن نمونه زیر برای الگوی بالا:

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

استفاده از حریص .* در این مورد غیر قابل اجرا است. الگوی .*Exception in thread.* 141 مرحله طول می کشد تا مطابقت داشته باشد. اگر به جای آن از الگوی .*?Exception in thread.*

تاثیر

استفاده از کمیت‌کننده‌های حریصانه مانند حروف عام ( * ) با خط‌مشی RegularExpressionProtection می‌تواند منجر به:

  • افزایش تاخیر کلی برای درخواست‌های API برای اندازه بار متوسط ​​(تا 1 مگابایت)
  • زمان طولانی تر برای تکمیل اجرای خط مشی RegularExpressionProtection
  • درخواست‌های API با بارهای بزرگ (بیش از 1 مگابایت) با 504 خطای وقفه زمانی دروازه در صورت سپری شدن دوره وقفه از پیش تعریف‌شده روی Edge Router با شکست مواجه می‌شوند.
  • استفاده زیاد از CPU در پردازشگرهای پیام به دلیل حجم زیاد پردازش که می‌تواند بر سایر درخواست‌های API تأثیر بگذارد.

بهترین تمرین

  • با خط مشی RegularExpressionProtection از استفاده از کمیت کننده های حریص مانند .* در عبارات منظم خودداری کنید. در عوض، از کمیت‌کننده‌های بی‌میل مانند .*? یا کمیت‌کننده‌های مالکیتی مانند .*+ (که کمتر رایج است) تا جایی که ممکن است.

در ادامه مطلب