How do I update Cloudflare WAF rule via API

I have tried this 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 = '"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);
echo $response;
    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 = '"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.

What am I doing wrong.

For the $updatedRule variable i have tried

$updatedRule = [
        "id" => $ruleId,
        "paused" => false,
        "description" => "BlockBadIPNewName",
        "action" => "block", ///Issue is maybe here
        "expression" => $newFilterExpression
    ]; 

and

$updatedRule = [
        "id" => $ruleId,
        "paused" => false,
        "description" => "BlockBadIPNewName",
        "action" => "block", ///Issue is maybe here
        "filter" => [
            "id" => $filerID,
            "expression" => $newFilterExpression
        ],
    ];. 

None of these two change the expression, but like I said, I can change the name and the action

Someone else asked the same yesterday, see…

@sjr I’ve been struggling for two days, using the wrong endpoint for this purpose. I tried other endpoints as well but never considered using ‘filter.’ Many thanks!!

1 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.