След като преди две седмици се случи глобален срив, вчера мрежата за доставка на съдържание Cloudflare, обслужваща около 20% от целия световен уеб трафик, беше частично недостъпна в продължение на 25 минути. По време на инцидента около една трета от заявките през Cloudflare завършваха с връщане на празна страница с код на грешка 500. Този път причина за това беше проблем в кода на Lua, който беше незабелязан в продължение на години, използван в системата за филтриране на трафик WAF (Web Application Firewall) за блокиране на злонамерени заявки.

За да защитят системите на клиентите от критична уязвимост (CVE-2025-55182) в сървърните компоненти на фреймворка React, след като експлоитът стана публично достъпен, инженерите на Cloudflare внедриха защита на ниво WAF. Внедряването не мина гладко: по време на внедряването беше увеличен размерът на буфера за проверка на трафика на прокси-сървъри, но се оказа, че инструментариумът за тестване на WAF не поддържа зададения размер на буфера. Тъй като този инструментариум не влияе на трафика, беше решено да бъде деактивиран.
За деактивирането инженерите използваха подсистемата „killswitch“ за бързо променяне на конфигурацията и деактивиране на отделни Lua обработчици на прокси-сървърите без подмяна на правилата. Такъв метод за деактивиране на правилата периодично се използва за бързо отстраняване на грешки и води до пропуск на изпълнението на част от Lua кода. В същото време инженерите не взеха предвид, че за повикване на деактивирания тестови инструментариум в Lua правилата е използван метод „execute“, който стартира допълнителен набор от правила. Режимът „killswitch“ никога преди не е бил използван с правила, които имат повикване „execute“, и тази комбинация не е била тествана.
Приложение на 'killswitch' доведе до деактивиране на кода за определяне на допълнителен набор от правила, но извикването на този набор правила чрез 'execute' остана. В кода нямаше допълнителни проверки за съществуването на обекта и се подразбираше, че при наличие на действие 'execute' в набора правила, обектът 'rule_result.execute' задължително съществува. В резултат на това настъпи опит за изпълнение на метода 'execute' за неинициализиран обект, което доведе до аварийно прекратяване на обработчика с грешка 'опит за индексиране на полето 'execute' (нулева стойност). if rule_result.action == 'execute' then rule_result.execute.results = ruleset_results[tonumber(rule_result.execute.results_index)] end
Източник: opennet.ru
