Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shopify app approval #11334

Closed
3 tasks done
girarda opened this issue Mar 22, 2022 · 18 comments
Closed
3 tasks done

Shopify app approval #11334

girarda opened this issue Mar 22, 2022 · 18 comments

Comments

@girarda
Copy link
Contributor

girarda commented Mar 22, 2022

Shopify must approve our app application.

Oustanding issues are

  1. App must set security headers to protect against clickjacking.
    Your app must set the proper frame-ancestors content security policy directive to avoid clickjacking attacks. The 'content-security-policy' header should set frame-ancestors https://[shop].myshopify.com https://admin.shopify.com, where [shop] is the shop domain the app is embedded on.

  2. App must verify the authenticity of the request from Shopify.
    Expected HTTP 401 (Unauthorized), but got HTTP 200 from https://cloud.airbyte.io/partner/v1/shopify/shop/redact. Your app's HTTPS webhook endpoints must validate the HMAC digest of each request, and return an HTTP 401 (Unauthorized) response when rejecting a request that has an invalid digest. Learn more about verifying a webhook

@girarda
Copy link
Contributor Author

girarda commented Mar 28, 2022

The app was submitted for review on 03/25. We're waiting for an update on their end

@sherifnada sherifnada moved this to In Progress - current sprint in API Sources DX Roadmap Mar 30, 2022
@sherifnada sherifnada moved this from In Progress - current sprint to In review in API Sources DX Roadmap Mar 30, 2022
@sherifnada
Copy link
Contributor

After a couple of back & forths, still in review by the Shopify team

@mhbw
Copy link

mhbw commented Apr 20, 2022

just want to say I love this tool, and as a Shopify client, love seeing this is in progress! Thanks all.

@sherifnada sherifnada assigned sherifnada and unassigned girarda Apr 21, 2022
@sherifnada
Copy link
Contributor

update: our app is still in review.

the main blockers right now are:

  1. Shopify is requiring that we process any payments customers make to us to use the shopify connector through their billing API. e.g the customer puts their credit card in shopify, and when they want to use it in Airbyte, we call their API, and shopify pay us out based on the customer’s.
  2. shopify is requiring that we do oauth by redirecting the customer to the shopify UI, having them install our app from the Shopify appstore directly, then having Airbyte somehow figure out what their shop URL etc..

@sherifnada
Copy link
Contributor

@misteryeo assigning this to you for now to take the lead on making inroads with Shopify -- happy to help where I can here

@Echecivuole
Copy link

Shopify must approve our app application.

Oustanding issues are

  1. App must set security headers to protect against clickjacking.
    Your app must set the proper frame-ancestors content security policy directive to avoid clickjacking attacks. The 'content-security-policy' header should set frame-ancestors https://[shop].myshopify.com https://admin.shopify.com, where [shop] is the shop domain the app is embedded on.
  2. App must verify the authenticity of the request from Shopify.
    Expected HTTP 401 (Unauthorized), but got HTTP 200 from https://cloud.airbyte.io/partner/v1/shopify/shop/redact. Your app's HTTPS webhook endpoints must validate the HMAC digest of each request, and return an HTTP 401 (Unauthorized) response when rejecting a request that has an invalid digest. Learn more about verifying a webhook

Hi @girarda we hai the same issue of your point 2 and Shopify support is rejecting every time without telling us how to replicate their test! You will be loved by Mokapen team if you can tell us how to fix this issue :) thanks!

@girarda
Copy link
Contributor Author

girarda commented Jun 24, 2022

@Echecivuole you need to compute the HMAC digest for the requests, compare it with the value passed from the header, and return a 401 if they do not match.

The gist of what we do is

  1. Convert the response body to a string. You'll need to ensure the string you produces is formatted just like shopify sends it. (we applied .replaceAll("\" : ", "\": ") after converting the map to a string to ensure we don't have extra whitespaces.
  2. initialize a Mac object with the secret key. something like
final Mac hmac = Mac.getInstance("HmacSHA256");
hmac.init(new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
  1. apply the hmac on the response body string and encode it with Base64
Base64.encodeBase64String(hmac.doFinal(bodyAsString.getBytes(StandardCharsets.UTF_8)));
  1. compare the result with the HTTP header X-Shopify-Hmac-SHA256

@Echecivuole
Copy link

@Echecivuole you need to compute the HMAC digest for the requests, compare it with the value passed from the header, and return a 401 if they do not match.

The gist of what we do is

  1. Convert the response body to a string. You'll need to ensure the string you produces is formatted just like shopify sends it. (we applied .replaceAll("\" : ", "\": ") after converting the map to a string to ensure we don't have extra whitespaces.
  2. initialize a Mac object with the secret key. something like
final Mac hmac = Mac.getInstance("HmacSHA256");
hmac.init(new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
  1. apply the hmac on the response body string and encode it with Base64
Base64.encodeBase64String(hmac.doFinal(bodyAsString.getBytes(StandardCharsets.UTF_8)));
  1. compare the result with the HTTP header X-Shopify-Hmac-SHA256

Thanks @girarda for your time first of all! I think we already are doing this, using same code from Shopify documentation:

# The following example uses PHP to verify a webhook request:

<?php

# The Shopify app's API secret key, viewable from the Partner Dashboard. In a production environment, set the API secret key as an environment variable to prevent exposing it in code.
define('API_SECRET_KEY', 'my_api_secret_key');

function verify_webhook($data, $hmac_header)
{
  $calculated_hmac = base64_encode(hash_hmac('sha256', $data, API_SECRET_KEY, true));
  return hash_equals($hmac_header, $calculated_hmac);
}

$hmac_header = $_SERVER['HTTP_X_SHOPIFY_HMAC_SHA256'];
$data = file_get_contents('php://input');
$verified = verify_webhook($data, $hmac_header);

error_log('Webhook verified: '.var_export($verified, true)); // Check error.log to see the result

if ($verified) {
  # Process webhook payload
  # ...
} else {
  http_response_code(401);
}

?>

So we are checking the HMAC passed and verify with the verify_webhook() function. But Shopify is not telling us HOW to replicate the issue they say is and we don't see!

@girarda
Copy link
Contributor Author

girarda commented Jun 24, 2022

@Echecivuole I don't have much insights into what shopify does on their end either.

We tested this on our end by

  1. sending a valid request and validate the computed hmac matches the one in the header
  2. sending an invalid request and validate the computed hmac does not match the one in the header. You can try many variations of this by mutating either the hmac in the header or the body

@bazarnov
Copy link
Collaborator

@girarda Did we get the approval? What is the status of this issue?

@girarda
Copy link
Contributor Author

girarda commented Oct 10, 2022

The last update I have on this issue is from April. @YowanR is there an ongoing discussion with Shopify?

@YowanR
Copy link
Contributor

YowanR commented Oct 10, 2022

@girarda Not at the moment, no. Let me ramp up a little bit there and then re-engage with Shopify.
@bazarnov To make sure I understand, what do we miss if we don't get the shopify app approval? Is it only OAuth? Can we still support API key in the meantime?

@girarda
Copy link
Contributor Author

girarda commented Oct 10, 2022

@YowanR we're not allowed to support API key auth on Cloud. This ticket has a bit more context #8633 (comment)

@YowanR
Copy link
Contributor

YowanR commented Oct 10, 2022

I see. I'm starting to better understand the full picture now. We need this app approved to get OAuth and to get OAuth, we disable API key auth. So now, we are 100% relying on Shopify to get us approved before we can do anything. Let me re-engage with Shopify. FYI @ycherniaiev @igrankova

@sherifnada
Copy link
Contributor

@YowanR the main blocker with shopify isn't removing API key auth in cloud (that's pretty doable), it's the issues mentioned in this link #11334 (comment)

@YowanR
Copy link
Contributor

YowanR commented Oct 13, 2022

Oh I see. That's quite a lot of overhead for us to support this connector then. We have restarted the process but if these are the blockers, then this will require work from a lot of different teams. @sherifnada Do you know how Fivetran or other competitors handle this?

@sherifnada
Copy link
Contributor

when I asked, Shopify said that these were newer regulations, and that Fivetran will "eventually" have to become compliant with them. I don't quite buy it but we'll see :P

@bazarnov
Copy link
Collaborator

The Airbyte app got its approve for a public app. Closing this now.

@github-project-automation github-project-automation bot moved this from In review to Done in API Sources DX Roadmap Aug 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

No branches or pull requests

8 participants