Salesforce, Python, SQL, & other ways to put your data where you need it

Need event music? 🎸

Live and recorded jazz, pop, and meditative music for your virtual conference / Zoom wedding / yoga class / private party with quality sound and a smooth technical experience

Salesforce Spring '20 Community Guest User Apocalypse

08 Jan 2020 🔖 salesforce security architecture
💬 EN

Post Header Image

Table of Contents

All right … a nuisance, not an apocalypse. Heads up: There are some things changing with Guest User access Salesforce Communities in the Spring ‘20 release that can break your business’s customer experience if you’re not on top of them.

Below, I’ll explain my understanding so far of what’s changing for Guest Users in Salesforce production orgs on March 1 – alongside examples of the issues my org is dealing with.

  • Update: Salesforce backed off a bit. The apocalypse is delayed to Summer ‘20. Production orgs will still implementing these changes on March 1, but will let you flip them back off until Summer 20.

Are you impacted?

Do you have a Community?

To determine if you use Salesforce Communities, visit Setup -> All Communities and see if any “communities” are listed in “Active” status.

If you don’t have any at all, you can ignore this whole article – although make sure to spread the word to a friend who does use Communities.

Do you let Guest Users use the Community?

If you have active Communities listed, look at each one’s URL (something along the lines of https://yourorg.xx00.force.com/something) and ask yourself what kinds of humans you send to web sites beginning with that URL.

Now ask yourself:

“Do I ever send members of the general public to any such web sites?

“If so, do those web sites provide them data out of my Salesforce org or let them write data into my Salesforce org?”

Are you really, really sure?

Don’t be too quick to answer “No.”

For example, we use Communities to host forms that collect sensitive data from prospective customers.

Most of the web pages within our Community that do anything interesting require someone to be logged into the Community with a username and password. Those web pages are not impacted by Spring ‘20 changes.

However, the web page where people sign up for an account upon their very first visit most definitely is impacted, because it writes a new User record to our Salesforce org when they provide us their e-mail address and the password they’d like to use.

So even though we might initially think, “No, everything’s locked down behind a Community User login page,” it turns out it’s not! The “get an account” page itself is open to the public.

Furthermore, we also have a few forms that allow people to see upcoming events and RSVP to the events. These Community web pages are not hidden behind a login requirement at all (they don’t ask private enough information to bother – they’re more like Eventbrite events).

Each of these RSVP forms reads information about the event it is allowing someone to RSVP to (so as to display the event’s name at the top of the form), and also writes data back to our Salesforce org (noting the details about the person who RSVPed).

Be sure to sit down with your org’s whole administrator + developer team and really think through these kinds of “edge cases.”

Visit each page yourself

If you come up with such web pages, visit them, using versions of their URLs from a sandbox that has Spring ‘20 turned on.

In such a sandbox, Salesforce should have already “flipped the switches” it plans to flip on March 1.

  • Check if the web pages load properly.
  • Fill out all their form fields, click all their buttons, and see if anything doesn’t behave as expected.

If you only have a Winter ‘20 sandbox, you can manually check/uncheck the boxes that Salesforce will be auto-checking/auto-unchecking on March 1 – I’ll go over where to find them in the review, below, of what changed.

You might need to use a web browser in “Incognito” or “Private” mode, with password manager autologin functionality turned off, to make sure you aren’t accidentally logged into the Community or into Salesforce.


  1. Besides the release notes, I recommend reading the “View Details” and “Get Started” links of the 3 alerts dated Feb 29, 2020 inside your org under Setup -> Security Alerts. I find them a little less abstract.
  2. Salesforce employees put together an unofficial blog post at “Learn Community Cloud” elaborating upon the high-level information given in the release notes.
    • Devs: If you’re responsible for writing Apex to fix this problem, you absolutely need to read it, but note that, in my opinion, it’s not tailored for distracted skimming. It’s written more in the style of a coding book. Put your “learning hat” on and take time to read it properly. (For me, that meant printing it to paper. Sorry, trees.)
    • Admins: The “TL;DR” is that in certain Flows (e.g. Screen Flows driving the content of a web page in a Community), “Get Records” and “Update Records” might break – you might have to replace them with Invocable Apex, a.k.a. Apex Actions.
    • If you’re an admin, and if your testing (as recommended above), combined with your knowledge of how your communities are built, leads you to believe Flows might be involved in “fixing broken things”: read the “plain-English” parts of the article as best you can and skip the code. Pay particular attention to “pattern 3” & “pattern 4.” If some of it goes over your head, partner with a developer to study the article together.
  3. There’s a Success Community group called Securing Community Cloud where people are geeking out about implementation details.
  4. If you’re part of the Power of Us nonprofit sucess community hub, developer Thad Dahlberg started a great discussion thread about implementation details as well.

What’s changing #1: No ownership allowed

Under Setup -> Communities Settings, there’s a little checkbox labeled “Reassign new records created by guest users to the default owner” that is going to get checked. From what I understand, you won’t be able to un-check it.

The “Security Alert” notes within Salesforce also seem to imply that there won’t be any ownership of Salesforce records allowed by community Guest Users, since the notes ask you to edit old data to make sure that records are owned by someone else.

(If you’re in Winter ‘20 in your sandbox and want to see what will happen when Salesforce implements these changes, just check it yourself and change your records to be owned by someone else.)

This likely doesn’t impact you from a business perspective, except that it prevents a loophole through the change I’m about to describe next …


What’s changing #2: Record access lockdown

Under Setup -> Sharing Settings, there’s a little checkbox that says “Secure guest user record access” that is going to get checked From what I understand, you won’t be able to un-check it.

(If you’re in Winter ‘20 in your sandbox and want to see what will happen when Salesforce implements this change, just check it yourself.)

Here’s what that little checkbox does:

Impacts

Impact 1: Private sharing

This checkbox toggles every object in your org so that Guest Users have no Read or Write access to records from those objects.

That is, it puts the objects into “Private” sharing mode from the perspective of the Guest User.

“Private sharing” mode means that a user can only learn about the existence of, or modify, records that it owns. (And since there’s another change coming out on March 1 saying that Guest Users will no longer own records, this is effectively a lockdown for Guest Users preventing any Read/Write access.)

That said, you can sort of restore “Read” sharing-access to Guest Users on a record-by-record basis. More on “sort of” in a moment.

Impact 2: No manual sharing

This checkbox disables making an end-run around the new rule by granting access to Guest Users by using “manual sharing” on a record-by-record basis.

Impact 3: No public group membership

This doesn’t impact my org, so I don’t have much to say about how impactful it would be.

Impact 4: No queue membership

This doesn’t impact my org, so I don’t have much to say about how impactful it would be.

Fixes

Restoring read access

Under Setup -> Sharing Settings, most of the page is taken up by a “Related List” for each object in your org listing out existing “Sharing Settings” for that object and offering a “New” button for creating additional ones.

Once the “Secure guest user record access” checkbox has been checked in an org, a new “Guest user access, based on criteria” option shows up under “Step 2: Select your rule type” when you click this “New” button.

The only type of access it allows you to grant to an object, for a Guest User, is Read.

Unfortunately, the user interface doesn’t allow you to grant Read access to every record of the object. You have to pick at least 1 field-value-based filter criterion under “Step 3: Select which records to be shared,” and “Id NOT EQUALS (blank)” is not an option, you sly devil.

If your business case for Guest Users in Communities absolutely requires that they be able to see data from every single record of a given object, I can think of three solutions:

  1. You get very sly about your “criteria” – e.g. CreatedById startsWith 005 (which should always be true, since that’s the first 3 digits of any User ID).
  2. You leave record access locked down to No Read/Write for Guest Users, don’t bother with “Sharing Settings, and have your Community pages do essential work on behalf of Guest Users with Apex running in “without sharing” mode. (BE CAREFUL! NOT FOR AMATEURS!)
  3. If the only object you care about letting a Guest User be able to read data from is User, and if the only type of user record you need them to be able to read data from is “user of the same community who doesn’t also happen to be a proper internal Salesforce user,” instead of using “Sharing Settings” against the “User” object, you can go to Setup -> All Communities -> (pick a community) -> Workspaces -> Administration -> Preferences, and check a checkbox called Let guest users see other members of this community.
  4. (Credit for 4th option to Mitch Spano:) Instead of using a page within the Community to display the information to non-logged-in people, send them to a web page hosted as a “Public Site,” which can have a sort of “system mode” effect. (BE CAREFUL! NOT FOR AMATEURS!)

Write access workaround

  1. You may have to amend the Apex and Visualforce / JavaScript behind pages of your community so that the Apex classes supporting certain Community pages do work on behalf of Guest Users “without sharing” (BE CAREFUL! NOT FOR AMATEURS! You don’t want to just add “without sharing” to the first line of entire Apex classes, for security reasons.).
    • Look through any controllers or extensions driving the behavior of the pages themselves.
    • Look through any trigger handlers that fire in reaction to DML performed by the controllers/extensions.
  2. (Credit for 2nd option to Mitch Spano:) Instead of using a page within the Community for non-logged-in people to interact with, have them interact with a web page hosted as a “Public Site,” which can have a similar sort of “system mode” effect. (BE CAREFUL! NOT FOR AMATEURS!)

Bring snacks – this is going to take some serious Admin-Dev collaboration time, with a healthy dose of concern about security.

Remember that you want to follow principles of “least privilege” when designing these workarounds, not make your life easier as an admin or a dev.


What’s changing #3: No “user records” read-access loophole

The profile-specific permission “View All Users” will no longer be a checkbox you’re allowed to check for a profile used by Guest Users.

This could have served as a loophole to the “record access lockdown” in the case of the User object – now it can’t.

(If you’re in Winter ‘20 in your sandbox and want to see what will happen when Salesforce implements this change, just check un-check the “View All Users” checkbox under System Permissions within the relevant profile yourself.)

Restoring access

Other Community Users, not Salesforce

If the only type of User record that you need Guest Users to be able to read data from is “user of the same community who doesn’t also happen to be a proper internal Salesforce user,” instead of using “Sharing Settings” against the “User” object, you can go to Setup -> All Communities -> (pick a community) -> Workspaces -> Administration -> Preferences, and check a checkbox called Let guest users see other members of this community.

Salesforce Users

If you also need Guest Users to be able to read data from User records belonging to people who happen to be proper internal Salesforce users (e.g. letting the “create an account” page for a community match to someone who already works for your company as a Salesforce user)

…You’ll want to create “Sharing Settings” on the User object, like you would for any other object.

See “Restoring Read Access” above.

Admins and Devs should partner to think carefully about, and test, whether this is actually necesary. Remember, follow principles of “least privilege” when designing workarounds to Salesforce locking down security.


Business impact

When the “Secure guest user record access” checkbox was checked as Spring ‘20 went live in our QA sandbox, some things broke and others didn’t.

What stayed up

  1. A Visualforce Page called EventRegistration, accessible publicly at https://orgname.cs00.force.com/communityname/EventRegistration, still loaded and showed a calendar shape – it didn’t redirect people to log in (however, it was blank).
  2. A Visualforce Page called CreateNewAccount, accessible publicly at https://orgname.cs00.force.com/communityname/CreateNewAccount, still prompted for a name, email address, and password as usual.
  3. A Visualforce Page called LogMeIn, accessible publicly at https://orgname.cs00.force.com/communityname/LogMeIn, still allowed a registered community users to type an e-mail address and password, and to access the Community behind the login prompt.
  4. A Visualforce Page called ForgotPassword, accessible publicly at https://orgname.cs00.force.com/communityname/ForgotPassword, still prompted for an e-mail address.
    • Upon submitting an e-mail address that didn’t exist, it gave the usual error message saying, Sorry, that's not even a member of our community.
    • Upon submitting an e-mail address that does exist, it took me to https://orgname.cs00.force.com/communityname/PasswordSent – I was testing with a fake e-mail address, so no idea if it really arrived. But it rendered the page saying it sent me a password reset link.

What broke

  1. Actually trying to submit data to the Visualforce Page called EventRegistration, accessible publicly at https://orgname.cs00.force.com/communityname/CreateNewAccount, took the user to a Visualforce page with a red error message at the top saying, “Your request cannot be processed at this time. The site administrator has been alerted.
  2. Trying to visit the URL to register for an event, which involves passing a Salesforce record ID as a URL parameter to the Visualforce Page called EventRegistration.
    e.g. When visiting https://orgname.cs00.force.com/communityname/EventRegistration?eventId=0AA000008298v89 with a web browser, people got instantly redirected to https://orgname.cs00.force.com/communityname/LogMeIn?startURL=%2Fcommunityname%2FEventRegistration%3FeventId%3D0AA000008298v89 (the Visualforce Page called LogMeIn).
    • Note: Although I was able to get the page to load properly by adding a guest-user-specific sharing setting for “Our Events” object with a criterion of CreatedById startsWith 005, the “submit” button still does not work properly, because it involves writing data to the database.
    • When I try to submit a registration form, I am shown an error message at the top of the registration form saying:
      Insert failed. First exception on row 0; first error: INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY, insufficient access rights on cross-reference id: []
  3. The calendar at EventRegistration (without an eventId URL parameter) was blank instead of filled with a list of events and their registration links.
    • Note: I believe I was able to fix this by adding a guest-user-specific sharing setting for “Our Events” object with a criterion of CreatedById startsWith 005.

Expected technical issues

Here’s what I suspect we’ll have to examine closely:

  1. The business process of “Checking against existing User records by e-mail address and deciding whether or not to create a new User” could be part of the problem with CreateNewAccount.
  2. We have 3rd-party “managed package” triggers in place that, upon new User creation, create a new Contact. That could also be part of the problem with CreateNewAccount.
  3. What worms do we have to shove back into a can (e.g. very carefully rewrite pieces of them to run in “system mode without sharing” concerning Process Builders / Workflow Rules / Flows / Triggers that run when User or Contact records are created/edited)?
    And how about all of the automations that kick off when those automations cause other records to be created/edited/deleted? Yikes.
  4. What kinds of data processes (e.g. creation of records in our “who’s registered for what event” object) will we need to carefully rewrite to run in something like “system mode without sharing” when someone clicks the “submit” button on a page? e.g. EventRegistration?eventId=0AA000008298v89?

Photo of Jon Stewart depressedly blowing a party noisemaker

So. January’s going to be a real party.

How’s your #GuestUserPocalypse going?


Did you excape the GuestUserPocalypse?

Yay! I’m thrilled if I was able to help in any way.

If you’d like, I’d love a Ko-Fi. (Chai for me!) 🥰

Support me on Ko-Fi


--- ---