GDPR webhooks and clickjacking rejection in App review

Topic summary

A developer is facing App Review rejections for two security requirements:

1. GDPR Webhook HMAC Verification

  • App must validate HMAC digest on HTTPS webhook endpoints
  • Must return HTTP 401 for invalid requests
  • Developer has implemented verification logic using base64-encoded SHA256 HMAC comparison
  • Code shows proper 401 responses for failed verification

2. Clickjacking Protection

  • App must set security headers to prevent clickjacking
  • Developer claims to have implemented Content Security Policy with frame-ancestors directive on all pages
  • Mentions attaching a CSP screenshot as evidence

Current Status:
The developer believes both requirements are correctly implemented but continues receiving rejections. They’re seeking community feedback on potential issues in their implementation, particularly regarding the webhook verification code provided.

Summarized with AI on November 23. AI used: claude-sonnet-4-5-20250929.

Our app is getting the following rejections:
1. App must verify the authenticity of the request from Shopify.
2.App must set security headers to protect against clickjacking.
But we checked and these are satisfied correctly.
Here is an example for one of our endpoint that listens to the webhook. Can anyone mention what we do here is not right as they mentioned one of the following issues also:

Your app’s HTTPS webhook endpoints must validate the HMAC digest of each request, and return an HTTP 401 (Unauthorized) response code when rejecting a request that has an invalid digest.

def verify_webhook(body, secret, hmac_to_verify):
    """
    Verifies hmac data from Shopify Webhook
    """
    hash_data = hmac.new(secret.encode('utf-8'), body, hashlib.sha256)
    hmac_calculated = base64.b64encode(hash_data.digest())
    return hmac_calculated.decode('utf-8') == hmac_to_verify

class CustomerRedactAPI(APIView):
    def post(self, request, *args, **kwargs):
        """
        This API recieves response from customers/redact Webhook
        """
        try:
            webhook_topic = request.META['HTTP_X_SHOPIFY_TOPIC']
            webhook_hmac = request.META['HTTP_X_SHOPIFY_HMAC_SHA256']
            webhook_data = json.loads(request.body)
        except:
            return HttpResponse('Unauthorized', status=401)
        verified = verify_webhook(request.body, settings.SHOPIFY_API_SECRET, webhook_hmac)
        if not verified:
            return HttpResponse('Unauthorized', status=401)

        return HttpResponse(status=200)

And I am attaching a screenshot of Content Security Policy that we have set for each page of our app. We have set the frame-ancestors content security directive just like they are required.