Two weeks after the last global outage, yesterday the content delivery network Cloudflare, which serves about 20% of the world’s web traffic, was partially unavailable for 25 minutes. During the incident, about a third of requests through Cloudflare resulted in an empty page with error code 500. This time, the cause was a long-standing issue in the Lua code used in the traffic filtering system WAF (Web Application Firewall) to block malicious requests.

To protect customer systems from a critical vulnerability (CVE-2025-55182) in the server components of the React framework, after the exploit was made public, Cloudflare engineers implemented protection at the WAF level. However, the implementation did not go smoothly: during the process, the buffer size for traffic verification on the proxy was increased,servers, but it turned out that the WAF testing toolkit being used did not support the set buffer size. Since this toolkit does not affect traffic, it was decided to disable it.
To disable it, the engineers used the ‘killswitch’ subsystem for quickly changing configurations and disabling specific Lua handlers on the proxy servers without replacing the rules. This method of disabling rules is periodically used to quickly fix errors and results in skipping the execution of part of the Lua code. However, the engineers did not take into account that the ‘execute’ method, which triggers an additional set of rules, was used to call the disabled testing toolkit in the Lua rules. Previously, the ‘killswitch’ mode had never been applied with rules that include an ‘execute’ call, and this combination had not been tested.
The use of the 'killswitch' resulted in the code for defining an additional test rule set being disabled, but the invocation of this rule set through 'execute' remained. The code did not include additional checks for the existence of the object, and it was assumed that if the rule set contained the 'execute' action, the object 'rule_result.execute' must exist. As a result, an attempt was made to execute the 'execute' method on an uninitialized object, which caused the handler to crash with the error 'attempt to index field 'execute' (a nil value)'. if rule_result.action == 'execute' then rule_result.execute.results = ruleset_results[tonumber(rule_result.execute.results_index)] end
Source: opennet.ru
