I am trying to update a rule of a waf on Cloudflare using their API. You will see in the code that I get the rule and content first, then update the rule.
All the credentials are correct
$zoneIdentifier = "123"; //Real credentials are correct (tripple checked)
$authKey = "123"; //Real credentials are correct (tripple checked)
$accountID = "123"; //Real credentials are correct (tripple checked)
$ruleId = "123"; //Real credentials are correct (tripple checked)
$filerID = "123"; //Real credentials are correct (tripple checked)
$url = "https://api.cloudflare.com/client/v4/zones/{$zoneIdentifier}/firewall/rules/{$ruleId}";
$headers = [
"X-Auth-Email: [email protected]",
"X-Auth-Key: {$authKey}",
"Content-Type: application/json",
];
// Function to make a cURL request function makeCurlRequest($url, $headers, $method = "GET", $data = null)
{
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_POSTFIELDS => $data ? json_encode($data) : null,
CURLOPT_HTTPHEADER => $headers,
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
return false;
}
return json_decode($response, true);
}
// Retrieve information about the rule
$responseData = makeCurlRequest($url, $headers);
if ($responseData !== false) {
// Process the response
$filter = $responseData['result']['filter'];
$expression = $filter['expression'];
// New IP address to add
$newIpAddress = "123.123.1.0"; ///Test IP
// Check Cloudflare's documentation for the correct expression syntax
$newFilterExpression = "(ip.src eq {$newIpAddress})";
// If there's an existing expression, combine it with the new one using 'or'
if ($expression) {
$newFilterExpression = "{$expression} or {$newFilterExpression}";
}
// Updated rule details
$updatedRule = [
"id" => $ruleId,
"paused" => false,
"description" => "BlockBadIP",
"action" => "block",
"expression" => $newFilterExpression
];
// URL for updating the rule
$updateUrl = "https://api.cloudflare.com/client/v4/zones/{$zoneIdentifier}/firewall/rules/{$ruleId}";
// Set cURL options for the PUT request (update)
$updateResponse = makeCurlRequest($updateUrl, $headers, "PUT", $updatedRule);
// Check for cURL errors in the update response
if ($updateResponse !== false) {
// Output the update response
} else {
echo "Update failed.";
}
} else {
echo "Failed to retrieve rule information.";
}
I have done a lot of testing, I can change the name via the API, I can change the action via APIbut the expression never change.
For the $updatedRule variable i have tried
$updatedRule = [
"id" => $ruleId,
"paused" => false,
"description" => "BlockBadIP",
"action" => "block",
"expression" => $newFilterExpression
];
and
$updatedRule = [
"id" => $ruleId,
"paused" => false,
"description" => "BlockBadIP",
"action" => "block",
"filter" => [
"id" => $filerID,
"expression" => $newFilterExpression
],
];.
Not of these two change the expression, but like I said, I can change the name and the action
There are no errors. The response indicate that success:
["success"]=> bool(true) ["errors"]=> array(0) { } ["messages"]=> array(0)
Yet, the expression is not updated.
Expression sample in plain text: (ip.src eq 123.123.1.0) or (ip.src eq 123.123.1.1) or (ip.src eq 123.123.1.2)
What am I doing wrong?
2
Answers
With the help of the Cloudflare Community, I managed to solve the problem. I used the wrong endpoint for the purpose I was attempting. The correct endpoint for updating a rule in the firewall is
https://api.cloudflare.com/client/v4/zones/{$zoneIdentifier}/filters/{$filterID}
.If the above doesn’t work, it might be helpful to verify the following:
If you’ve already triple-checked the expression format and verified the permissions, and the issue persists, reaching out to Cloudflare support or their developer community might provide additional insights or assistance specific to their API behavior.