انجیناکس؛ شب ۳۸: تنظیم false positive بدون خاموش کردن WAF
فهرست نوشته
وقتی یک فرم سالم مسدود میشود، باید بفهمیم کدام rule و کدام پارامتر سبب آن شده است. امشب استثنا را تا یک مسیر، پارامتر و شناسه محدود میکنیم و کارکرد قواعد دیگر را دوباره میسنجیم.
این جلسه بخشی از دورهٔ انجیناکس در ۵۰ شب است. قرارداد آزمایشگاه، مسیرها و روال اعمال تغییر در راهنمای دوره آمده است.
محیط: CRS شب ۳۷، یک نمونهٔ سالم که واقعاً در log به rule مشخصی میخورد؛ روی clone کار کن و رخدادهای حساس را منتشر نکن. false positive یعنی تشخیص اشتباه درخواست سالم بهعنوان حمله.
شواهد پیش از تغییر#
زمان، method، مسیر بدون اطلاعات ورود، rule ID، پارامتر matchشده، نسخهٔ CRS و anomaly score را یادداشت کن. فرق خطای parsing، محدودیت body، IP ACL، rate limit و خود rule را از log بفهم. متن سالم تکرارشونده را به درخواست قابل بازتولید تبدیل کن؛ کل log شامل cookie و محتوای کاربر را در issue نگذار.
استثنای runtime محدود#
ابتدا روی probe آموزشی 100500 تمرین میکنیم، نه یک ID حدسزدهٔ CRS. در exclusions-before.conf:
SecRule REQUEST_URI "@rx ^/feedback(?:\?|$)" "id:100501,phase:1,pass,nolog,chain"
SecRule REQUEST_METHOD "@streq POST" "ctl:ruleRemoveTargetById=100500;ARGS:lab_probe"
این استثنا target مربوط به lab_probe را فقط برای POST همین endpoint از rule 100500 کنار میگذارد. URI با query پذیرفته میشود، ولی /feedback-extra یا GET همان مسیر مشمول نیست. backend باید POST این endpoint را با پاسخ مشخص هندل کند؛ 501 Python http.server را موفقیت برنامه حساب نکن. یک handler آزمایشگاهی POST با body ثابت به برنامهٔ شب ۲۸ اضافه کن.
بعد از validate/reload، POST سالم روی feedback باید عبور کند؛ همان lab_probe روی مسیر دیگر یا GET باید همچنان توسط rule probe مسدود شود. برای استثنای واقعی CRS، شناسه و target مشاهدهشده را به همین الگو منتقل و بررسی کن rule در phase مناسب اجرا میشود. نام rule نمونه را با ID واقعی ثبتشده جایگزین کن، نه همهٔ قواعد SQLi را.
استثناهای configure-time مثل SecRuleRemoveById باید پس از بارگذاری ruleها قرار گیرند؛ runtime exclusion پیش از اجرای آنها قرار میگیرد. هدف از دو فایل before/after همین تفاوت است. regex و case normalization مسیر را مطابق برنامه بررسی کن؛ ورودی percent-encoded و trailing slash را هم تست کن.
مجموعهٔ regression#
فهرست کوچک اما معنیدار نگه دار: ورود سالم، فرم فارسی، upload مجاز، REST دارای احراز هویت، probe روی مسیر استثنا و همان probe بیرون مسیر. از مجموعهٔ تست پروژهٔ CRS، نمونهٔ حملهٔ دیگری را اضافه کن که استثنا نباید آن را آزاد کند. خروجی expected/observed، rule ID و نسخهها را در یادداشت محلی ثبت کن.
اگر latency یا memory افزایش یافته، نرخ و اندازهٔ body آزمون را ثابت نگه دار و هزینهٔ WAF را جدا از backend بسنج. بالا بردن anomaly threshold برای همهٔ سایت بدون تحلیل، دامنهٔ محافظت را کم میکند. استثنای WordPress باید با نسخهٔ افزونه و endpoint روشن ثبت شود و پس از ارتقا دوباره آزمایش شود.
بازگشت: فقط استثنای جدید را بردار و validate/reload کن؛ درخواست سالم ممکن است دوباره مسدود شود، پس مسیر نگهداری و تصمیم عملیاتی را از قبل مشخص کن. probe آموزشی را پس از پایان تمرین از policy واقعی حذف کن.