Zoomapps-sample-js tutorial gives me a blank page, and an error of Missing OWASP Secure Headers

I followed the tutorial at GitHub - zoom/zoomapps-sample-js: A Hello World Zoom App built with Vanilla JS and managed to install the app.

However, when I open the app in Zoom, it gives me a blank page and "Missing OWASP Secure Headers: [“Strict-Transport-Security”,“X-Content-Type-Options”,“Content-Security-Policy”] for URL https://.ngrok.io/api/zoomapp/home
Global Code

I tried also installing the advanced tutorial, i.e. GitHub - zoom/zoomapps-advancedsample-react: This repository contains an Advanced Zoom Apps Sample. It should serve as a starting point for you to build and test your own Zoom App in development. , but the result was the same. Again, a blank page with OWASP error.

One other strange thing I am noticing: my backend doesn’t seem to be hearing anything from my Zoom app. If I, for example, reload my zoom app, the backend doesn’t log anything new.

My App credentials include these:
Home URL: https://mydomain.ngrok.io (in the advanced tutorial with /api/zoomapp/home)
Domain allow list: mydomain.ngrok.io , appssdk.zoom.us, (in advanced tutorial also images.unsplash.com). Both get next to them “This domain requires review. Briefly explain your reason for using it.”

I am using the free version of ngrok

For zoom/zoomapps-advancedsample-react app did you fill zoomapps-advancedsample-react/.env.example at main · zoom/zoomapps-advancedsample-react · GitHub. These instructions might be helpful GitHub - zoom/zoomapps-advancedsample-react: This repository contains an Advanced Zoom Apps Sample. It should serve as a starting point for you to build and test your own Zoom App in development.

This warning meant that when you submit your for review to Zoom, an explanation is needed. But, these warnings won’t block you during development phase.

My .env contains currently this:

I have followed the instructions for setting up .env that you mention.

Installing the app works well, but it just keeps showing a blank page.

Did you fill in domain allow list and oauth allow list sections in marketplace build flow? Also, can you share any error messages you might be seeing in console?

Yes, they look like this:

My docker-compose looks like this when I install the app:

➜  zoomapps-advancedsample-react git:(main) ✗ docker-compose up

[+] Running 3/0
 ⠿ Container zoomapps-advancedsample-react-frontend-1  Created                                                                                                                                                 0.0s
 ⠿ Container zoomapps-advancedsample-react-redis-1     Created                                                                                                                                                 0.0s
 ⠿ Container zoomapps-advancedsample-react-backend-1   Created                                                                                                                                                 0.0s
Attaching to zoomapps-advancedsample-react-backend-1, zoomapps-advancedsample-react-frontend-1, zoomapps-advancedsample-react-redis-1
zoomapps-advancedsample-react-redis-1     | 1:C 20 Jul 2022 16:38:00.304 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
zoomapps-advancedsample-react-redis-1     | 1:C 20 Jul 2022 16:38:00.304 # Redis version=7.0.4, bits=64, commit=00000000, modified=0, pid=1, just started
zoomapps-advancedsample-react-redis-1     | 1:C 20 Jul 2022 16:38:00.304 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
zoomapps-advancedsample-react-redis-1     | 1:M 20 Jul 2022 16:38:00.304 * monotonic clock: POSIX clock_gettime
zoomapps-advancedsample-react-redis-1     | 1:M 20 Jul 2022 16:38:00.308 * Running mode=standalone, port=6379.
zoomapps-advancedsample-react-redis-1     | 1:M 20 Jul 2022 16:38:00.308 # Server initialized
zoomapps-advancedsample-react-redis-1     | 1:M 20 Jul 2022 16:38:00.315 * Loading RDB produced by version 7.0.4
zoomapps-advancedsample-react-redis-1     | 1:M 20 Jul 2022 16:38:00.315 * RDB age 45 seconds
zoomapps-advancedsample-react-redis-1     | 1:M 20 Jul 2022 16:38:00.315 * RDB memory usage when created 1.00 Mb
zoomapps-advancedsample-react-redis-1     | 1:M 20 Jul 2022 16:38:00.315 * Done loading RDB, keys loaded: 1, keys expired: 0.
zoomapps-advancedsample-react-redis-1     | 1:M 20 Jul 2022 16:38:00.315 * DB loaded from disk: 0.004 seconds
zoomapps-advancedsample-react-redis-1     | 1:M 20 Jul 2022 16:38:00.315 * Ready to accept connections
zoomapps-advancedsample-react-frontend-1  |
zoomapps-advancedsample-react-frontend-1  | > za-reference-react@0.1.0 start
zoomapps-advancedsample-react-frontend-1  | > react-app-rewired start | cat
zoomapps-advancedsample-react-frontend-1  |
zoomapps-advancedsample-react-backend-1   |
zoomapps-advancedsample-react-backend-1   | > za-reference-node@0.1.0 start:dev
zoomapps-advancedsample-react-backend-1   | > nodemon server.js
zoomapps-advancedsample-react-backend-1   |
zoomapps-advancedsample-react-backend-1   | [nodemon] 2.0.15
zoomapps-advancedsample-react-backend-1   | [nodemon] to restart at any time, enter `rs`
zoomapps-advancedsample-react-backend-1   | [nodemon] watching path(s): *.*
zoomapps-advancedsample-react-backend-1   | [nodemon] watching extensions: js,mjs,json
zoomapps-advancedsample-react-backend-1   | [nodemon] starting `node server.js`
zoomapps-advancedsample-react-backend-1   | [HPM] Proxy created: /  -> http://frontend:9090
zoomapps-advancedsample-react-backend-1   | [HPM] Proxy created: /  -> https://zoom.us
zoomapps-advancedsample-react-backend-1   | [HPM] Proxy rewrite rule created: "^/zoom/api" ~> ""
zoomapps-advancedsample-react-backend-1   | 123
zoomapps-advancedsample-react-backend-1   | process.env.PUBLIC_URL https://5ANONYMIZEDu.ngrok.io
zoomapps-advancedsample-react-backend-1   | Please add Auth0 env variables to enable the /auth0 route
zoomapps-advancedsample-react-backend-1   | Zoom App is listening on port 3000
zoomapps-advancedsample-react-frontend-1  | (node:27) [DEP0148] DeprecationWarning: Use of deprecated folder mapping "./" in the "exports" field module resolution of the package at /home/node/app/node_modules/postcss-safe-parser/node_modules/postcss/package.json.
zoomapps-advancedsample-react-frontend-1  | Update this package.json to use a subpath pattern like "./*".
zoomapps-advancedsample-react-frontend-1  | (Use `node --trace-deprecation ...` to show where the warning was created)
zoomapps-advancedsample-react-frontend-1  | ℹ 「wds」: Project is running at http://172.18.0.2/
zoomapps-advancedsample-react-frontend-1  | ℹ 「wds」: webpack output is served from /api/zoomapp/proxy
zoomapps-advancedsample-react-frontend-1  | ℹ 「wds」: Content not from webpack is served from /home/node/app/public
zoomapps-advancedsample-react-frontend-1  | ℹ 「wds」: 404s will fallback to /api/zoomapp/proxy/
zoomapps-advancedsample-react-frontend-1  | Starting the development server...
zoomapps-advancedsample-react-frontend-1  |
zoomapps-advancedsample-react-frontend-1  | Browserslist: caniuse-lite is outdated. Please run:
zoomapps-advancedsample-react-frontend-1  | npx browserslist@latest --update-db
zoomapps-advancedsample-react-frontend-1  |
zoomapps-advancedsample-react-frontend-1  | Why you should do it regularly:
zoomapps-advancedsample-react-frontend-1  | https://github.com/browserslist/browserslist#browsers-data-updating
zoomapps-advancedsample-react-frontend-1  | Compiled with warnings.
zoomapps-advancedsample-react-frontend-1  |
zoomapps-advancedsample-react-frontend-1  | src/App.js
zoomapps-advancedsample-react-frontend-1  |   Line 4:16:  'invokeZoomAppsSdk' is defined but never used  no-unused-vars
zoomapps-advancedsample-react-frontend-1  |
zoomapps-advancedsample-react-frontend-1  | src/components/ApiScrollview.js
zoomapps-advancedsample-react-frontend-1  |   Line 1:27:  'useEffect' is defined but never used  no-unused-vars
zoomapps-advancedsample-react-frontend-1  |
zoomapps-advancedsample-react-frontend-1  | Search for the keywords to learn more about each warning.
zoomapps-advancedsample-react-frontend-1  | To ignore, add // eslint-disable-next-line to the line before.
zoomapps-advancedsample-react-frontend-1  |
zoomapps-advancedsample-react-backend-1   | starting headers set
zoomapps-advancedsample-react-backend-1   | process.env.PUBLIC_URL https://5ANONYMIZEDu.ngrok.io
zoomapps-advancedsample-react-backend-1   | headers set
zoomapps-advancedsample-react-backend-1   | INSTALL HANDLER ==========================================================
zoomapps-advancedsample-react-backend-1   |
zoomapps-advancedsample-react-backend-1   | 1. Begin add app - generated state for zoom auth and saved: KANONYMIZEDf
zoomapps-advancedsample-react-backend-1   |
zoomapps-advancedsample-react-backend-1   | 2. Redirect url to authenticate to Zoom: https://zoom.us/oauth/authorize?redirect_uri=https%3A%2F%2F5ANONYMIZED
zoomapps-advancedsample-react-backend-1   |
zoomapps-advancedsample-react-backend-1   | 3. Redirecting to redirect url
zoomapps-advancedsample-react-backend-1   |
zoomapps-advancedsample-react-backend-1   | GET /api/zoomapp/install 302 8.428 ms - 808
zoomapps-advancedsample-react-backend-1   | starting headers set
zoomapps-advancedsample-react-backend-1   | process.env.PUBLIC_URL https://5ANONYMIZEDu.ngrok.io
zoomapps-advancedsample-react-backend-1   | headers set
zoomapps-advancedsample-react-backend-1   | ZOOM OAUTH REDIRECT HANDLER  ==============================================
zoomapps-advancedsample-react-backend-1   |
zoomapps-advancedsample-react-backend-1   | 1. Handling redirect from zoom.us with code and state following authentication to Zoom
zoomapps-advancedsample-react-backend-1   |
zoomapps-advancedsample-react-backend-1   | 1a. code param exists: PANONYMIZEDA
zoomapps-advancedsample-react-backend-1   |
zoomapps-advancedsample-react-backend-1   | 1b. state param is correct/matches ours: KANONYMIZEDf
zoomapps-advancedsample-react-backend-1   |
zoomapps-advancedsample-react-backend-1   | 2. Getting Zoom access token and user
zoomapps-advancedsample-react-backend-1   |
zoomapps-advancedsample-react-backend-1   | 2a. Use code to get Zoom access token - response data:  {
zoomapps-advancedsample-react-backend-1   |   access_token: 'eANONYMIZEDQ',
zoomapps-advancedsample-react-backend-1   |   token_type: 'bearer',
zoomapps-advancedsample-react-backend-1   |   refresh_token: 'eANONYMIZEDg',
zoomapps-advancedsample-react-backend-1   |   expires_in: 3599,
zoomapps-advancedsample-react-backend-1   |   scope: 'user:read zoomapp:inmeeting'
zoomapps-advancedsample-react-backend-1   | }
zoomapps-advancedsample-react-backend-1   |
zoomapps-advancedsample-react-backend-1   | 2b. Use access token to get Zoom user - response data:  {
zoomapps-advancedsample-react-backend-1   |   id: 'zANONYMIZED',
zoomapps-advancedsample-react-backend-1   |   first_name: 'ANONYMIZED',
zoomapps-advancedsample-react-backend-1   |   last_name: 'ANONYMIZED',
zoomapps-advancedsample-react-backend-1   |   email: 'ANONYMIZED',
zoomapps-advancedsample-react-backend-1   |   type: 1,
zoomapps-advancedsample-react-backend-1   |   role_name: 'Owner',
zoomapps-advancedsample-react-backend-1   |   pmi: ANONYMIZED,
zoomapps-advancedsample-react-backend-1   |   use_pmi: false,
zoomapps-advancedsample-react-backend-1   |   personal_meeting_url: 'ANONYMIZED',
zoomapps-advancedsample-react-backend-1   |   timezone: 'ANONYMIZED',
zoomapps-advancedsample-react-backend-1   |   verified: 0,
zoomapps-advancedsample-react-backend-1   |   dept: '',
zoomapps-advancedsample-react-backend-1   |   created_at: 'ANONYMIZED',
zoomapps-advancedsample-react-backend-1   |   last_login_time: 'ANONYMIZED',
zoomapps-advancedsample-react-backend-1   |   last_client_version: 'ANONYMIZED',
zoomapps-advancedsample-react-backend-1   |   pic_url: 'ANONYMIZED',
zoomapps-advancedsample-react-backend-1   |   host_key: 'ANONYMIZED',
zoomapps-advancedsample-react-backend-1   |   cms_user_id: '',
zoomapps-advancedsample-react-backend-1   |   jid: 'ANONYMIZED',
zoomapps-advancedsample-react-backend-1   |   group_ids: [],
zoomapps-advancedsample-react-backend-1   |   im_group_ids: [],
zoomapps-advancedsample-react-backend-1   |   account_id: 'ANONYMIZED',
zoomapps-advancedsample-react-backend-1   |   language: 'en-US',
zoomapps-advancedsample-react-backend-1   |   phone_country: '',
zoomapps-advancedsample-react-backend-1   |   phone_number: '',
zoomapps-advancedsample-react-backend-1   |   status: 'active',
zoomapps-advancedsample-react-backend-1   |   job_title: '',
zoomapps-advancedsample-react-backend-1   |   location: '',
zoomapps-advancedsample-react-backend-1   |   login_types: [ 1 ],
zoomapps-advancedsample-react-backend-1   |   role_id: '0',
zoomapps-advancedsample-react-backend-1   |   account_number: ANONYMIZED,
zoomapps-advancedsample-react-backend-1   |   cluster: 'ANONYMIZED'
zoomapps-advancedsample-react-backend-1   | }
zoomapps-advancedsample-react-backend-1   |
zoomapps-advancedsample-react-backend-1   | 2c. Save the tokens in the store so we can look them up when the Zoom App is opened
zoomapps-advancedsample-react-backend-1   | 3. Generated deeplink from Zoom API using access token:  https://zoom.us/launch/zoomapp/ANONYMIZED
zoomapps-advancedsample-react-backend-1   |
zoomapps-advancedsample-react-backend-1   | 4. Redirecting to Zoom client via deeplink . . .
zoomapps-advancedsample-react-backend-1   |
zoomapps-advancedsample-react-backend-1   | GET /api/zoomapp/auth?code=ANONYMIZED 302 1593.534 ms - 528

Then, the console of the app inside Zoom gives me only this:

Nothing changes in my docker if I refresh the Zoom app.

Can you add https://XXX.ngrok.io/api/zoomapp/home to your oauth allow list and see if it fixes the issue?

Unfortunately, this doesnt seem to make any difference.

I re-installed the app to be sure but the page remains blank with no content at all.

try adding ngrok.io and countrycode.ngrok.io (for ex: in.ngrok.io if using free version) to Domain allow list

Are you still encountering issues with the headers when using Ngrok?

I have published my App and received the below error from Zoom support

Unfortunately, I am not getting the above error. So the main concern is why they are facing the above issue and from my side it is working fine. How Should I simulate the above case.

I have already allowed the domain url in allow list.

I would make sure to use the Basic Sample App along with the latest version of Ngrok to ensure that you don’t encounter this issue

I think you didn’t get it. Let me explain you in more detail.
I am not getting the above error of OWASP header error. APP is working fine for me.
When I published the app. The above issue faced by Zoom support who is reviewing my app faced the above issue and reported back to me. so my concern is why the App is working correctly for me and not working for them.
If the App is working correctly then how should I simulate the above issue. I can’t fix any error which is not producing at my side.

However I am not using npm or the zoomsdk etc. Created the app using core JS and using CDN process.

Can you please take a look into the case.
Let me know how I can produce the error mentioned in comment or how I can resolve it.

Thanks for sharing those details. Can you share how you are setting the headers for the app and what backend framework you’re using? If you have a git repository of the app that you can share that should help to investigate the issue. If they are conditionally set I would make sure that the condition is set for the reviewers of the app.