Hmac header not present for label webhook

Hi!

I have registered a webhook for generating labels, however, when printing labels on the shipping web, the webhook request doesn’t have the signature (hmac) header.

Thanks!

HI @pedro!
Our apologies for the delayed response about this.
We are currently working on solving this and we will keep you updated on the progress.
Thanks in advance for your patience!
Tom

Hi @pedro!
HMAC should be displaying now for your webhooks. Thanks again for the patience while we investigated this,
Tom

Thanks @tomasw!

Best regards

Hi @tomasw, I just tried the webhook and the header is not appearing.

Best regards

Thanks for the fast response @pedro!
Would It be possible for you to share an Order ID/Order Number?
Thanks again,
Tom

Hi @tomasw, this is the order id I tested: 201537787

Thanks

Thanks for confirming that @pedro !
We reopened the ticket for our engineer to have another look at this. We will let you know as soon as it gets reviewed
Thanks again for the patience!
Tom

Hi @tomasw! Any news regarding this issue?

Thanks!

Having the same issue here, the x_shiphero_hmac_sha256 header is not sent with the request.

I created a ticket with more details: https://shiphero.na3.teamsupport.com/ticket/170766

Here’s a copy:

I created a Generate Label Webhook and im trying to do the Request Verification step defined here: Webhooks – Developer Resources | ShipHero

Unfortunately it seems that the header “x-shiphero-hmac-sha256” is not in the request?

Any idea how I can verify the call comes from you guys?

Cheers,
Hans

In the meantime I added a whitelist for a tiny bit of security…

from fastapi import Request, HTTPException

# temporary security until ShipHero gets HMAC working
if request.client.host != '54.158.254.66':
    raise HTTPException(status_code=401, detail="Failed the whitelist")

Hi @hansdaigle & @pedro !

Our apologies for the delayed response!
We added a default entry at ShipHero - Simplify How You Pick and Pack Your Orders - ShipHero for your account
Try with that secret.

The way its currently working is:
If the order has a Shop Name: ABCD it will use the Secret from Shop Name: ABCD, otherwise it will use the default one. We added that default one for you.

Let us know if that still doesn’t work.
Thanks again!
Tom

1 Like

Thank you so much, it’s working perfectly now! I feel way more secure exposing our Webhook endpoints now.

For the community, this is what I ended up doing:

import hmac
import hashlib
import base64

from fastapi import APIRouter, Response, status, Header, Request, HTTPException
from fastapi_versioning import version
from pydantic import BaseModel, validator


def validate_hmac_signature(secret: str, data: bytes, hmac_signature: str):
    """ Verify the base64 hmac request against a hmac_signature

    :param secret: shared secret (ShipHero API Secret)
    :param data: raw request body
    :param hmac_signature: x_shiphero_hmac_sha256 header
    :return: True if success, False if failed the challenge
    """
    digest = hmac.new(secret.encode("UTF-8"), msg=data, digestmod=hashlib.sha256).digest()
    calculated_signature = base64.b64encode(digest).decode()

    return calculated_signature == hmac_signature

# you will need to define the subModels (ShipHeroAddress, ShipHeroPackages) or replace with "str"
class ShipHeroOrderModel(BaseModel):
    shipping_name: str
    to_address: ShipHeroAddress
    shipping_method: str
    order_id: str
    packages: List[ShipHeroPackages]
    order_number: str
    partner_order_id: str
    from_address: ShipHeroAddress

@router.post("/carrier/x/label",
             responses={
                 200: {"model": ShipHeroLabelModel, "description": "Webhook for a ShipHero to Carrier x mapping"},
             }, )
@version(1, 0)
async def label(shiphero_order: ShipHeroOrderModel,
                response: Response,
                request: Request,
                x_shiphero_hmac_sha256: Optional[str] = Header(None),
                ):


    if not validate_hmac_signature(secret=cfg.get("shiphero", "api_secret"),
                                   data=await request.body(),
                                   hmac_signature=x_shiphero_hmac_sha256):

        raise HTTPException(status_code=401, detail=str("Failed the HMAC verification"))

    ...
    # add the rest of your code here

This is how my api keys were setup:

Cheers,

Hans