What's the problem with "firewallrules.api.malformed_request_body“

When I requst Create firewall rules, the error message is “firewallrules.api.malformed_request_body”.

$zoneid=$rs['result'][0]['id'];
$url_add_fw="https://api.cloudflare.com/client/v4/zones/".$zoneid."/firewall/rules";
$post = array(
    'filter' => array(
        'expression' =>'(not ip.geoip.country in {"CN"} and not ip.geoip.country in {"HK"} and not ip.geoip.country in {"MO"} and not ip.geoip.country in {"TW"})', 
    ),
    'action' => 'block',
    'description' => 'No China'
);
$post = json_encode($post,JSON_UNESCAPED_UNICODE);
echo $post;
$add_fw_rs = post_data($url_add_fw, $post, $header,8,1);
echo $add_fw_rs;

function post_data($url, $post=null, $header=array(), $timeout=8, $https=0)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_HEADER, 0);

if ($https)
{
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);  
}
if ($header)
{
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
}
if ($post)
{
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($post) ? http_build_query($post) : $post);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$content = curl_exec($ch);
curl_close($ch);
return $content;

}

1 Like

Hello. I understand that a lot of time has passed and the problem is no longer relevant, but I want to share a solution to a similar problem, maybe someone will come in handy.

My task: create a PHP function to update the expression (IP list) on the filter (zone_id/filters/:id), Cloudflare API v4 Documentation

As a result of execution I received an error “malformed_request_body”:

{ “result”: null, “success”: false, “errors”: [ { “code”: 10014, “message”: “filters.api.malformed_request_body” } ], “messages”: }

Spent 2 hours searching for a reason, the reason turned out to be very stupid and banal, I incorrectly placed square brackets in the body of the POST request.

Wrong:

CURLOPT_POSTFIELDS => [“{"id":"$filter_id","expression":"(ip.src in {{$ip_list}})","paused":false}”],

Right:

CURLOPT_POSTFIELDS => “[{"id":"$filter_id","expression":"(ip.src in {{$ip_list}})","paused":false}]”

Square brackets are needed even if I specify POST as an array (I guess you had the same reason):

$post_data = [
“id” => $filter_id,
“expression” => “(ip.src in {0.1.2.3} and not cf.client.bot)”,
];
$data_string = json_encode($post_data);
// …
CURLOPT_POSTFIELDS => “[$data_string]”,

Full working code:

function syncroniseBlacklistCloudFlare ($ip_for_block) {
$ip_list = implode(’ ', $ip_for_block); // convert array to string for Cloudflare filter

$api_token = ‘M_TOKEN’; // need access to edit firewall rules, dash.cloudflare.com/:account_id/profile/api-tokens
$zone_id = ‘MY_ZONE_ID’;
$filter_id = ‘MY_FILTER_ID’;

$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => “https://api.cloudflare.com/client/v4/zones/$zone_id/filters”,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => “PUT”,
CURLOPT_POSTFIELDS => “[{"id":"$filter_id","expression":"(ip.src in {{$ip_list}} and not cf.client.bot)"}]”, // need double curly braces
CURLOPT_HTTPHEADER => [“Authorization: Bearer $api_token”, “Content-Type: application/json”],
]);

$response = curl_exec($curl);
// echo $response;
$err = curl_error($curl);
curl_close($curl);

if (!empty($err)) return false;
$response = json_decode($response, true);
if (!$response[‘success’]) return false;
return true;
}

1 Like