skip to Main Content

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


  1. Chosen as BEST ANSWER

    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}.


  2. $updatedRule = [
        "id" => $ruleId,
        "paused" => false,
        "description" => "BlockBadIP",
        "action" => "block",
        "filter" => [
            "id" => $filerID,
            "expression" => $newFilterExpression
        ],
    ];
    
    $updateUrl = "https://api.cloudflare.com/client/v4/zones/{$zoneIdentifier}/firewall/rules/{$ruleId}";
    
    
    $data = json_encode($updatedRule);
    
    
    $updateResponse = makeCurlRequest($updateUrl, $headers, "PUT", $data);
    

    If the above doesn’t work, it might be helpful to verify the following:

    Ensure that the $newFilterExpression variable holds the correct format for the expression that Cloudflare's API expects. You might check the Cloudflare documentation or test the expression format separately.
    Verify that the permissions associated with the API key used for authentication have the necessary access rights to modify firewall rules.
    Check the Cloudflare API documentation for any specific requirements or constraints related to updating expressions within firewall rules.
    

    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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search