Discussing APIs and development related to customers, discounts, and order management.
Hello,
I've added a bulk action link and while the default hmac validation works in all other cases, it fails on bulk action.
For example, if you add a bulk action "orders action drop-down", select multiple orders and then try to validate that request with hmac validation, none of the checks seem to work.
Multiple ids come in as ids[]=1234567890&ids[]=1234567891 etc.
There's actually no standard for arrays in queries, as it differs per language.
That said, the most common solution mentioned here is converting multiple 'ids[]' to a single key 'ids' with the value as a single string like '["1234567890", "1234567891"]' and then use that to validate.
However, I don't know what happened but since the last answer in 2020, but this does not work. So I've been guessing what the format should be for the last 5 hours, but to no avail.
I've also tried:
ids=["1234567890","1234567891"]
ids=['1234567890','1234567891']
ids=['1234567890', '1234567891']
ids[]=["1234567890", "1234567891"]
ids[]=['1234567890', '1234567891']
ids={"1234567890","1234567891"}
ids={"1234567890", "1234567891"}
ids={'1234567890','1234567891'}
ids={'1234567890', '1234567891'}
ids=[1234567890,1234567891]
ids=[1234567890, 1234567891]
Also tried shuffling the values in the array in case that matters for the lexicographical order. Of course, also tried using the param value as an actual array. Furthermore, also tried the more exotic 'solutions' found here, all of them very old and not working.
An up-to-date answer on what the format should be would be nice, unless we start recommending skipping validation the moment an array is found (which is a high security risk). I haven't seen any updated answer, does that mean no one is validating bulk action when using the bulk action extension?
Greetings,
Shin Ho
Plugin Development Team
DHL Parcel Netherlands
Solved! Go to the solution
This is an accepted solution.
Yes it works perfect, heres the full function
public function verifyHmac( $params ) {
///FIX FOR IDS[] INCLUDED HERE
// Ensure shop, timestamp, and HMAC are in the params
if (array_key_exists('shop', $params)
&& array_key_exists('timestamp', $params)
&& array_key_exists('hmac', $params)
) {
// Grab the HMAC, remove it from the params, then sort the params for hashing
$hmac = $params['hmac'];
unset($params['hmac']);
// Convert array values in the params to a string
foreach($params as $key => &$value) {
if (is_array($value)) {
$value = '["' . implode('", "', $value) . '"]';
}
}
ksort($params);
// Concatenate all of the params
$paramsString = urldecode(http_build_query($params));
// Return the comparison result
return $hmac === hash_hmac('sha256', $paramsString, $this->getShopifyField('shopify_secret'));
}
}
Did you find an answer to this? Having same issue... oh just found the solution to this using chatgpt:
// Convert array values in the params to a string
foreach($params as $key => &$value) {
if (is_array($value)) {
$value = '["' . implode('", "', $value) . '"]';
}
}
Did that chatgpt solution work for you? In my test that didn't work and it's already one of the solutions I've tried in the past. (Wrap in [ ], wrap values in double quotes, separated by comma and space).
This is an accepted solution.
Yes it works perfect, heres the full function
public function verifyHmac( $params ) {
///FIX FOR IDS[] INCLUDED HERE
// Ensure shop, timestamp, and HMAC are in the params
if (array_key_exists('shop', $params)
&& array_key_exists('timestamp', $params)
&& array_key_exists('hmac', $params)
) {
// Grab the HMAC, remove it from the params, then sort the params for hashing
$hmac = $params['hmac'];
unset($params['hmac']);
// Convert array values in the params to a string
foreach($params as $key => &$value) {
if (is_array($value)) {
$value = '["' . implode('", "', $value) . '"]';
}
}
ksort($params);
// Concatenate all of the params
$paramsString = urldecode(http_build_query($params));
// Return the comparison result
return $hmac === hash_hmac('sha256', $paramsString, $this->getShopifyField('shopify_secret'));
}
}
Hi Jason27,
Thanks for providing the whole function. I found the difference on where it broke for my code:
I was lacking `urldecode()` on `http_build_query($params)` and that happened to coincidentally break the hmac checks on only bulk calls.
Thank you so much!
Greetings,
Shin