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

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

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

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

مثال زیر از سیاست RegularExpressionProtection برای محافظت از backend در برابر حملات تزریق 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 ابتدا سعی می‌کند طولانی‌ترین دنباله ممکن - کل رشته - را مطابقت دهد. اگر هیچ تطابقی پیدا نشود، این سیاست سپس به تدریج به عقب برمی‌گردد. اگر رشته منطبق نزدیک به شروع یا وسط payload باشد، استفاده از یک کمیت‌سنج حریصانه مانند .* می‌تواند زمان و قدرت پردازش بسیار بیشتری نسبت به توصیف‌کننده‌های بی‌میل مانند .*? یا (به ندرت) کمیت‌سنج‌های ملکی مانند .*+ مصرف کند.

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

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

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

استفاده از تابع حریصانه‌ی .* در این مورد ناکارآمد است. الگوی .*Exception in thread.* برای تطبیق، ۱۴۱ مرحله طول می‌کشد. اگر به جای آن از الگوی .*?Exception in thread.* (که از یک کمیت‌سنج بی‌میل استفاده می‌کند) استفاده می‌کردید، نتیجه فقط ۵۵ مرحله می‌شد.

تأثیر

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

  • افزایش تأخیر کلی برای درخواست‌های API برای حجم متوسط ​​بار داده (تا ۱ مگابایت)
  • زمان طولانی‌تر برای تکمیل اجرای سیاست RegularExpressionProtection
  • درخواست‌های API با حجم بالای داده (بیش از ۱ مگابایت) که در صورت اتمام مدت زمان از پیش تعیین‌شده‌ی زمان انقضا در روتر لبه (Edge Router)، با خطای ۵۰۴ Gateway Timeout مواجه می‌شوند.
  • استفاده زیاد از CPU در پردازنده‌های پیام به دلیل حجم زیاد پردازش که می‌تواند بر سایر درخواست‌های API تأثیر بگذارد.

بهترین شیوه

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

مطالعه بیشتر