> ## Content Index
> Fetch the complete content index at: https://notes.hiddenbay.tech/llms.txt
> Use this file to discover other available public pages before exploring further.

# How Self-Registration Can Become a Fast-Track for Attackers
- URL: https://notes.hiddenbay.tech/how-self-registration-can-become-a-fast-track-for-attackers/
- Published: 2026-10-05T04:00:17.000Z
- Updated: 2026-10-21T13:11:13.000Z
- Author: Daniel Harfleet
- Tags: Experience Cloud Security

Self-registration looks like a convenient out of the box feature. However if you skip over the details it can quietly hand a newly registered, unverified user access they were never meant to have.

Experience cloud includes an out-of-the-box feature that allows guest users to sign-up for membership of your portal. Switching on this feature without checking through wider configuration can inadvertently put registered users in a scenario where they can see data that is unintentionally shared with them due to schema and visibility configuration. If overridden by custom code, typically due to a more complex sign-up process, the signup process itself can inadvertently expose data.

If your sign-up process puts your newly registered users in immediate positions of privilege (for example exposure to PII or commercially sensitive information) without human intervention, then it's important that that process carries out stringent validation the person is who they say they are and that the registration data they have provided is true. This is more likely, but not exclusively the case in a B2B scenario.

If your sign-up process is complex and hence is multistage (perhaps due to introducing human and/or asynchronous checks), then it's important that whilst those checks are in progress, the user is isolated from the eventual data they will be exposed to, using a holding pattern.

There is no single right way to implement self-registration in Experience Cloud, but regardless what approach you take, it is important to carry out threat analysis on your chosen implementation and for each stage of the lifecycle the user passes through (e.g. guest, holding pattern, fully validated).

What follows are some of the technical details. If the technical details are not for you right now, skip to the summary for some important considerations.

## Technical considerations

### How to see if a site has self-registration

As an admin:  
In Setup, search for 'Digital Experiences' > Sites, select your site, then 'Workspaces>Administration>Login & Registration', 'Registration Page Configuration' > 'Allow customers and partners to self-register'

As an anonymous user of the site:

1. Look for a UI clue like 'Register', 'not a member?' or similar.
2. Navigate to \[domain\]/\[site\]/SelfRegister
3. Navigate to \[domain\]/\[site\]/.well-known/auth-configuration (check values for 'SelfRegistrationEnabled' and 'SelfRegistrationUrl' under 'LoginPage')

To switch it off, in setup by going to the same place in setup and disabling the checkbox 'Allow customers and partners to self-register'.

### Default self-registration

In the setup you will see that aside from specifying the page that will hold your self registration functionality, you can also specify an Account.

If you leave the account lookup empty, the built in self-registration behaviour will automatically create a new User and attach them to their own PersonAccount.  
If you decide not to use PersonAccounts, the setup will require you to specify a specific Account to add all registering users to, once running, new users will be associated to that account and the related Contact accounts also.

From a security perspective, the PersonAccount approach is probably tighter because the user will be the only user associated with their Account or Contact (blended as a PersonAccount), so accidental sharing is less likely.

Of course the 'default account' approach has more opportunity for an accidental data share since business Accounts may have multiple Contacts and multiple Users.

While the user is attached to that default account, over and above Org-Wide Defaults (OWD), they **may** have sharing access to any data that users of that account have access to. That could be due to a sharing rule, sharing-set, or implicit sharing (see Appendix A for the tested behaviour). In addition, if 'Portal User Visibility' is switched on, they have the potential to see user records of other users attached to that account, including other users following the same self-registration process.

### Customisation

The default account approach is rarely of use to any real-world business scenario and hence often times some form of customisation will come into play.

At a high level that customisation will be one of two approaches:

1. Account reassignment
2. A custom self-registration UI

#### Account reassignment

The user is registered on the default Account. Then asynchronous processes reassign that user to an appropriate account based on 'business rules'. This reassignment could be almost immediately based on user input (e.g. a record triggered flow or apex trigger). Or it could be a slightly slower process which includes third party checks and/or a human in the loop.

There are two key considerations:

1. Depending on the speed of your reassignment process, the user may still be attached to that default account long enough for them to view data associated with that Account and its associated Users.
2. When the User eventually ends up getting attached to a different account, they will then have access to data associated with the 'correct' Account and its associated Users. So it's important to be sure that your reassignment process is rigorous and is not open to abuse by allowing the user to manipulate with incorrect registration data.

When following this reassignment pattern, I recommend you consider a 'holding pattern'. This approach can involve the following:

1. Assign the user to a 'holding' profile. That profile should have very tight permissions. I specifically recommend using a Profile because in the case of Sharing-sets, these are associated with a Profile, so it provides more flexibility with tighter (or no) sharing-set config. That is not to say that you can not use permission-sets to contain all of the relevant permissions and of course also use a different permission-set for this scenario, however, in my opinion a different profile is safer and more explicit when it comes to sharing sets.
2. Attach the user to a temporary business account solely to hold them while they are validated. After validation, they can be attached to the correct Account.

The key takeaway of following this approach is to carefully consider this 'lifecycle'. Sanity check sharing and visibility settings and carry out 'threat analysis' on the end to end process at all the stages of the lifecycle.

#### Custom self-registration UIs

There are a number of ways to implement a custom self-registration UI. One benefit of the upfront 'registration business logic' being carried out *before* user record creation is that it avoids license activation wastage. The other benefit of the upfront logic is that the user never becomes a registered user until they have been validated and hence the security risks of having non-validated users as members are reduced.

It is of course possible for the 'holding pattern' to be combined with a custom self-registration UI, in this case the custom UI would not carry out any business logic and would use a class very similar to the default self-registration apex controller, which for aura sites is 'LightningSelfRegisterController' (generated and Experience Cloud enablement in your org; take a look in your org apex).

Although there are several ways of creating an external user, including direct DML inserts, the passwordless login flow (`System.UserManagement` apex class) and SSO registration handlers, typically a custom LWC will be written and sometimes a screen flow, both of which will call pretty much the same apex (either apex controller or flow apex action).

One security anti pattern I have seen in B2B self registration is when the user experience is trying to ascertain the correct account to attach the user to. It can naively be seen as quite nice from a UX perspective to provide a type ahead lookup to aid the user to state their account which would have the added benefit of reducing account duplication. However, from a security perspective this is handing an attacker a data farming opportunity (a live enumeration attack) on a plate. In this scenario, I would assert it is better to put your user in an account 'holding' pattern until stronger matching checks have been carried out.

## Summary of key considerations

1. The default Account pattern is rarely adequate and carries some security risks if not adequately configured at the security layer.
2. Automated self-registration without stringent checks provides a fast-track to attackers, particularly when they are being attached to multi-user Accounts.
3. If in doubt, create a 'holding' pattern implementation (a kind of security waiting room), threat model each user state of the 'held' user's lifecycle.
4. Any registration process can introduce a 'data farming' opportunity. Sanity check UX convenience against data leak possibility.
5. Carry out threat modelling when designing your implementation regardless of which pattern you follow.
6. Carefully review all related code and configuration.
7. [Use the 'Authenticated and Guest User Access Report and Monitoring' package](https://appexchange.salesforce.com/appxListingDetail?listingId=a0N3A00000FYkDDUA1&ref=notes.hiddenbay.tech) from AppExchange to check that expected data access and actual data access match for each stage of your self-registration user lifecycle.

---

I provide fractional architect consulting around Experience Cloud. If you'd like to talk about this or any other Experience Cloud topic, please get in touch at [enquiries@hiddenbay.tech](mailto:enquiries@hiddenbay.tech)

---

## Appendix A: Tested behaviour — implicit contact sharing on a shared account

The purpose of this testing was to understand implicit sharing that could come into play when assigning multiple users of the same Profile to the same account.

[Designing Record Access for Enterprise Scale](https://developer.salesforce.com/docs/atlas.en-us.draes.meta/draes/draes%5Fobject%5Frelationships%5Fimplicit%5Fsharing.htm?ref=notes.hiddenbay.tech), which also tackles implicit sharing states for Experience Cloud:

*"Access to a customer or partner account and all associated contacts for all customer or partner users under that account."*

Whilst the example column specifies a Customer Community Plus (role-based sharing) user, the 'Provides' column is ambiguous with the term 'all customer users' which could easily imply a Customer Community (high volume sharing user). These sharing mechanisms work differently so I wanted to test both types of user in a same account scenario in relation to Contact visibility.

Testing implicit contact access on a single account post self-registration.

### Common setup

Two custom community Profiles, one CustomerCommunity, one CustomerCommunityPlus  
One business Account  
Two existing Contacts (without users) on the business Account  
External OWD for Contact set to private.  
Contact Record List configured in Experience Builder.  
Portal User Visibility off, Site User Visibility off (we are testing Contact visibility, not User visibility, but ensuring off *just incase* they affect Contact visibility).

### Test 1 - Customer Community (high volume portal user)

#### Setup

In self-registration setup, specify the CC profile as the profile to be assigned to newly registered users  
Incognito mode self-register first CC user (user 1). Logout

#### Execute

Self-register second CC user (user 2)

#### Result

Second user has no visibility of first user's Contact record.

### Test 2 - Customer Community Plus (role based user)

#### Setup

In self-registration setup, specify the CCP profile as the profile to be assigned to newly registered users  
Incognito mode self-register first CCP user. Logout

#### Execute

Self-register second CCP user

#### Result

Second CCP user (user 4) has visibility of user 3 (first CCP user)'s Contact, but not user 1&2 (CC/HVPU users)'s Contacts.

### Test 3 - External OWD for Contact set as Controlled-by-Parent

#### Setup

Change internal and external OWD for Contact to 'Controlled by Parent'  
Wait for sharing re-calc

#### Execution

Login as user 2 (CC), observe all 4 User associated Contacts available  
Login as user 4 (CCP), observe all 4 User associated Contacts available

#### Result

Both users can see the other user's Contacts (all 4)  
Additionally it is noted that when Contact OWD is set to Controlled by Parent, the checkbox under Setup>>Digital Experiences named "Allow users to see contacts that have not been enabled for partner or customer accounts" exposes Contact records that have no user associated with them (as per docs).

In all tests, Portal User Visibility was toggled on and off and the scenario re-tested, just incase some 'security logic' applied user visibility to user's contacts. This was not expected and was not the case.

### Conclusion

There are two situations where Users can see each other's parent Contact records when under the same Account:

1. When External OWD for Contact is set to Controlled by Parent
2. When the User is role-based (Customer Community Plus), they can see parent Contact records associated with each other on the same account.

Assumption: Partner Users will behave the same way as Customer Community Plus Users (not validated).