Shopify / koa-shopify-auth

DEPRECATED Middleware to authenticate a Koa application with Shopify
MIT License
80 stars 63 forks source link

Cross-site scripting​ Issue #162

Closed upsc-karthik closed 1 year ago

upsc-karthik commented 2 years ago

Issue summary

We are working on an embedded application built using React /nodeJS. We performed a penetration testing using Netsparker and cross script scripting issue was identified.

Write a short description of the issue here ↓ The response presented does indicate that the App is injecting user supplied input into a script which is not ideal, but they have not demonstrated exploitation by escaping the string context and writing arbitrary HTML or javascript.

Expected behavior

What do you think should happen? Escaping user input is a common good practice to handle Cross-site scripting attacks, prevent running malicious code.

Actual behavior

Injection Request

GET /? hmac=e55ccce06cd0c112210b71d8226184173e00bbf7a593ec65ce19831a412be1a3&host=dWF0LWluZm9zZWMtdGVzdGluZy1zdG9yZS5teXNob3BpZnkuY29tL2FkbWlu&locale=en- US&session=785e205cc4b100b464450dc7ec06e56f6b4898ad5b6356fb304b77cf0f6ef3b7&shop=%2527%2522-- %253E%253C%252Fstyle%253E%253C%252FscRipt%253E%253CscRipt%253Enetsparker%25280x0003AE%2529%253C%252FscRipt%253E&timestamp=1647460888 HTTP/1.1 Host: .com Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.9 Cookie: ASLBSA=e9f15f2243d647e0fd8429467aeed7b0e0aede28e2ec14203a8a1ed14b93f6bc; ASLBSACORS=e9f15f2243d647e0fd8429467aeed7b0e0aede28e2ec14203a8a1ed14b93f6bc; shopifyTestCookie=1; shopifyNonce=164746477100601; shopifyNonce.sig=BkQj-0-wyt_3m1wZkrd0z4aOD-g; shopifyTopLevelOAuth=1; shopifyTopLevelOAuth.sig=CV9UEj-VSD9QG2gmfHL3RjkL0hQ Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="99", "Google Chrome";v="99" Sec-Ch-Ua-Mobile: ?0 Sec-Ch-Ua-Platform: "Windows" Sec-Fetch-Dest: iframe Sec-Fetch-Mode: navigate Sec-Fetch-Site: cross-site Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.0 Safari/537.36

Injection Response

HTTP/1.1 302 Found Content-Type: text/html; charset=utf-8 request-context: appId=cid-v1:cf661f67-d8bf-45b2-b33c-d286798ceee5 X-Content-Type-Options: nosniff Server: null X-Powered-By: null Pragma: no-cache X-XSS-Protection: 1; mode=block Content-Security-Policy: frame-ancestors https://*.myshopify.com Content-Length: 235 X-Cache: CONFIG_NOCACHE Strict-Transport-Security: max-age=31536000; includeSubDomains; preload Expect-CT: max-age=7776000, enforce X-Azure-Ref: 0RFEyYgAAAAC9GUSEGVeWTZREeAmFNv8VQk4zRURHRTExMDYANDZlOGVmZjgtMTIyZC00OTZhLTliYWMtZmM1OGI4NjNkN2U3 Location: /auth?shop=%27%22--%3E%3C%2Fstyle%3E%3C%2FscRipt%3E%3CscRipt%3Enetsparker%280x0003AE%29%3C%2FscRipt%3E Date: Wed, 16 Mar 2022 21:06:11 GMT Cache-Control: no-store, no-cache Redirecting to /auth?shop=%27%22-- %3E%3C%2Fstyle%3E%3C%2FscRipt%3E%3CscRipt%3Enetsparker%280x0003AE%29%3C%2FscRipt%3E.

What actually happens? The call goes to /auth within koa framework (@shopify/koa-shopify-auth) where it is not handled.

Flow:

  1. /auth call exists within the package shopify/koa-shopify-auth. The shop parameter is sent to /auth within the package.
  2. Once authenticated the control enters the app through afterAuth(ctx) highlighted below in code snippet.

Code Snippet: const { default: createShopifyAuth } = require("@shopify/koa-shopify-auth"); app.prepare().then(() => { const server = new Koa(); server.proxy = true; server.use(session({ secure: true, sameSite: "none" }, server)); server.keys = [SHOPIFY_API_SECRET_KEY]; server.use( createShopifyAuth({ apiKey: SHOPIFY_API_KEY, secret: SHOPIFY_API_SECRET_KEY, scopes: [ "read_products" ], accessMode:"offline", async afterAuth(ctx) { let urlreq = ctx.req.url; let url_parts = url.parse(urlreq, true); let query = url_parts.query; const shop = query.shop; ctx.cookies.set("shopOrigin", shop, { httpOnly: false, secure: true, sameSite: "none", }); ctx.redirect("/install"); }, }) );

Steps to reproduce the problem

  1. Perform Netsparker penetration testing on the embedded application.
  2. Manipulate the parameters in the request by adding script tags to it.

Request GET /auth?shop=%27%22--%3E%3C%2Fstyle%3E%3C%2FscRipt%3E%3CscRipt%3Enetsparker%280x0003AE%29%3C%2FscRipt%3E HTTP/1.1 Host: Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8 Accept-Language: en-us,en;q=0.5 Cookie: ASLBSA=e9f15f2243d647e0fd8429467aeed7b0e0aede28e2ec14203a8a1ed14b93f6bc; ASLBSACORS=e9f15f2243d647e0fd8429467aeed7b0e0aede28e2ec14203a8a1ed14b93f6bc; shopifyTestCookie=1; shopifyNonce=164746477283000; shopifyNonce.sig=2qvg9weAuzIbBfnJYGGuc93Vpc0 Referer: /? hmac=e55ccce06cd0c112210b71d8226184173e00bbf7a593ec65ce19831a412be1a3&host=dWF0LWluZm9zZWMtdGVzdGluZy1zdG9yZS5teXNob3BpZnkuY29tL2FkbWlu&locale=en- US&session=785e205cc4b100b464450dc7ec06e56f6b4898ad5b6356fb304b77cf0f6ef3b7&shop=teststore.myshopify.com&timestamp=1647460888 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.0 Safari/537.36


Checklist

arhumalihaider commented 2 years ago

any update on this? @upsc-karthik

github-actions[bot] commented 1 year ago

Note that this repo is no longer maintained and this issue will not be reviewed. Prefer the official JavaScript API library. If you still want to use Koa, see simple-koa-shopify-auth for a potential community solution.