Preventing discovery of meeting number and PIN with Meeting SDK

Meeting SDK Type and Version
2.18 for Web

Description
Hello,

I’m working on integrating the Meeting SDK into a custom web app, and I love it so far; except for one nitpick. I would like to prevent users from joining the meeting outside of my website. My website integration makes it easy to control what usernames and emails the users come in with, and apply my own authentication logic to ensure the users are permitted to access the meeting.

The Zoom SDK makes some parts of this easy. With meetingInfo I can hide the meeting number and PIN from the check icon in the upper left, and have done so. However, it doesn’t change that my meeting number, and PIN number, are embedded in my website’s DOM and easily accessible by anyone who knows how to Inspect Element.

This seems like an oversight when I’m already signing a JWT with a Meeting Number, and no Password, in it. I know that is for authenticating that the request is coming from my app from Zoom’s perspective - but why can’t I go further? Because I’m pretty sure the SDK doesn’t have a workaround for this (outside of registrants which has serious flaws in our application - like sending emails containing the meeting link defeating the point); I’d like to make a suggestion.

My JWT that I’m passing to Zoom already contains this information:

$payload = [
    'appKey' => $zoomClientID,
    'sdkKey' => $zoomClientID,
    'mn' => $zoom->meeting_number,
    'role' => 0,
    'iat' => time(),
    'exp' => strtotime('+4 hours'),
    'tokenExp' => strtotime('+6 hours'),
];

And, of course, the user sees this token as well in my website’s DOM and can decode it to see the contents, even if it can’t be faked. So, what if instead, we had something like this?

$payload = [
    'appKey' => $zoomClientID,
    'sdkKey' => $zoomClientID,
  + 'useEncryptedMeetingInformation' => true,
  ~ 'mn' => encrypt($zoom->meeting_number),
  + 'passWord' => encrypt($zoom->password),
  + 'userName' => "my user name"
  + 'userEmail' =>  "user@email.com"
    'role' => 0,
    'iat' => time(),
    'exp' => strtotime('+4 hours'),
    'tokenExp' => strtotime('+6 hours'),
];

public static function encrypt(string $message) {
    // Some code here which takes the input message
    // (i.e. $zoom->meeting_number from above), 
    // And encrypts it with AES-128 or AES-256
    // With the $zoomClientSecret as the password
}

With the above setup, this would have the following advantages for my application:

  1. The username and user email would be set, and digitally signed, server side; making tampering much more difficult. The user would not be able to edit the DOM and re-call ZoomMtg.join() as a hypothetical scenario.
  2. The meeting number and password are provided in the JWT and encrypted using the Zoom Client Secret, which never leaves my server and Zoom’s server. Thus, even if the user decodes the JWT, the meeting number and PIN are still protected; but visible to Zoom with information Zoom already has. Massive improvement compared to having it plain text in the DOM.

If you can provide any thoughts or feedback on this proposal, I would be delighted.

Gabriel Sieben
Software Developer
Homeschool Connections