Search code examples
emailoauth-2.0gmailphpmailer

Can I safely make some XOAuth authentication information public?


I am using PHPMailer with GMail in order to send SMTP mail. This works fine, as long as the account has the Allow Less Secure Apps feature enabled. I am working on a system where users will give permission for their GMail accounts to be used to send email.

I'd like to try XOAuth2 so that I don't have to ask users to enable the Less Secure switch. To do so, I am reading these instructions from the PHPMailer project.

Now, I think these instructions have been written from the perspective that the email will be sent from a system that is under the control of a single system owner. He or she (me in this case) would use their own Gmail account to set up these values:

// This is known to admin and to a single user (private)    $mail->oauthUserEmail = "<your gmail address>@gmail.com";
// User cannot see these, only admin
$mail->oauthClientId = "237644427849-g8d0pnkd1jh3idcjdbopvkse2hvj0tdp.apps.googleusercontent.com";
$mail->oauthClientSecret = "mklHhrns6eF-qjwuiLpSB4DL";

The user would then use their own GMail account to go through a Google consent screen to generate the final piece of information, which the admin uses on behalf of the user:

// This is known to admin and to a single user (private)
$mail->oauthUserEmail = "<your gmail address>@gmail.com";
// User cannot see these, only admin
$mail->oauthClientId = "237644427849-g8d0pnkd1jh3idcjdbopvkse2hvj0tdp.apps.googleusercontent.com";
$mail->oauthClientSecret = "mklHhrns6eF-qjwuiLpSB4DL";
// User gives this to the admin to complete the required info
$mail->oauthRefreshToken = "1/7Jt8_RHX86Pk09VTfQd4O_ZqKbmuV7HpMNz-rqJ4KdQMEudVrK5jSpoR30zcRFq6";

However, my use case will work slightly differently. I am deploying this app on behalf of the GMail account holder to a web hosting of their choosing, so essentially all auth values (except for the per-user refresh token) can now be regarded as public:

// This is known to me and to a single user (private)
$mail->oauthUserEmail = "<your gmail address>@gmail.com";
// Essentially these values would be public
$mail->oauthClientId = "237644427849-g8d0pnkd1jh3idcjdbopvkse2hvj0tdp.apps.googleusercontent.com";
$mail->oauthClientSecret = "mklHhrns6eF-qjwuiLpSB4DL";
// This is known to me and to a single user (private)
$mail->oauthRefreshToken = "1/7Jt8_RHX86Pk09VTfQd4O_ZqKbmuV7HpMNz-rqJ4KdQMEudVrK5jSpoR30zcRFq6";

My question is, what is the risk of making the oauthClientId and oauthClientSecret public? Since one of theme is called "secret", it feels not recommended, but I'm looking for a more concrete answer than that. Is my GMail account at risk if I publish these? Is a third party's GMail account at risk?

Use case

My use case is follows. I am setting up a service that offers form-to-email programs (e.g. a contact form) and will deploy them to a web server belonging to a third party. I have a wizard UI that gathers data from them, and they press a publish button at the end. Ideally I would like for users who opt to use a GMail account to go through the Google consent screen that I've set up, so the process is highly simplified for that user.

The alternative is that they have to go through creating their own OAuth2 entry in the Google Developers interface (see screenshots in earlier link), and add T&C and Privacy Policy links, when really that stuff is my job, not theirs!

It may be that I need to choose a different auth system in Google (they offer straightforward API keys too) but I don't know how that will play with PHPMailer.


Solution

  • If your mailer backend wants to use GMail to send emails on behalf of its users, it will have a role of OAuth2 client and the users will be resource owners. So the mailer backend will always use its own clientId and client secret, just with different access tokens allowing it to send emails. The workflow will be like this:

    1. Mailer backend detects that it needs access (or refresh) token. It sends a redirect response (to Google's /auth OAuth2 endpoint) to the browser. It uses the Authorization code grant flow, because it needs a refresh token.
    2. The user gets authenticated and accepts the consent.
    3. The browser gets redirected to the mailer backend's redirect URL along with an authorization code.
    4. The mailer backend exchanges the code for a refresh and an access token. The refresh token is a long lived token, so it can be saved for further use.
    5. The mailer backend passes the refresh token to PHPMailer to send an email.