Block Access to The Public Data - Members/PublicData Collection!

Recently, Wix has released a new collection/database for your site members, it contains their profile pictures, nicknames, and of course, their system IDs.

The risks of exposing this data

If your privacy policy promises your customers or members maximum security and privacy for their data, you should be concerned, this collection not only leaves you no choice to disable it, or change its permissions, but it also leaves you with a hole that you won’t be able to fill in with your privacy policy, a potential hacker might be able to run malicious code on your website to get a list of all your members data, here’s a brief of what the hacker will be able to get:

  1. The number of your members.

  2. The details themselves: Here’s an example of the data that the hacker can, and will be able to get their hands on:

[{
    _id: "7VJsCV6Bj55waLJ9jYZV4EPXvdLawbUr",
    nuckname: "User 1",
    profilePicture: "https://static.wix.com/..........png"
},
{
    _id: "tGYj26jTEz9BjNwnME4Z5MVdVZBRZn9x",
    nuckname: "User 2",
    profilePicture: "https://static.wix.com/..........jpg"
}]

I’ve made an argument for Wix, that in some websites and countries, the profile picture is considered confidential, and should never be publicly exposed unless the user explicitly allowed it, or has chosen to, remember guys, this is not a social network website, users don’t provide their data to share it publicly, but rather to enhance their experience, unfortunately, Wix disagrees with me and just didn’t listen, either way, whether they cared and listened or not, we’re not just going to stand hand-in-hand, we must do something, fortunately, we’ve got your back.

Block access to the collection

To block access to the collection, we’re going to use the collection’s data hooks.

We’re going to use the following hooks:

  1. beforeGet.

  2. beforeQuery.

  3. beforeCount.

Now on the backend, open the data.js file that was created upon creating the above hooks on the collection, and add the following code inside each one of the above functions.

export function Members$PublicData_beforeGet(itemId, context) {
    return Promise.reject({
        type: 'forbidden',
        message: 'Error: This action (get) is not allowed!'
    })
}

export function Members$PublicData_beforeQuery(query, context) {
    return Promise.reject({
        type: 'forbidden',
        message: 'Error: This action (query) is not allowed!'
    })
}

export function Members$PublicData_beforeCount(query, context) {
    return Promise.reject({
        type: 'forbidden',
        message: 'Error: This action (count) is not allowed!'
    })
}

When someone - including you - tries to access this collection, they’ll get an error message.

Error: This action (query) is not allowed!
Here’s an example of what you - the admin - will get when you try to open the collection in the editor.

You might be wondering: What if I want to get data from this collection? :thinking: The answer is simple, you only need to suppress the hooks, just like when you want to suppress the authentication of a user who doesn’t have access to a resource, pass the suppression data as the options object to the method that you want to run, for example:

wixData.get('Members/PublicData', "item_id", { suppressHooks: true });

// OR

wixData.query('Members/PublicData').find({ suppressHooks: true });

You might also ask: What if I want to open the collection in the editor? Well, to do that, we first need to check the user authorization and only allow access to admins.

Inside your hook function’s code block, add the following code - do NOT redeclare the hook function.

export async function Members$PublicData_beforeGet(itemId, context) {
    const isAdmin = async () => {
        if (wixUsersBackend.currentUser.loggedIn) {
            return wixUsersBackend.currentUser.getRoles().then((roles) => {
                return roles.filter(items => items.name === 'Admin').length > 0 ? true : false;
            })
        } else {
            return false;
        }
    }

    const adminUser = await isAdmin();
    if (!adminUser) {
        return Promise.reject({ type: 'forbidden', message: 'Error: This action (get) is not allowed!' })
    }

    return itemId;
}

This way, only admins will have access to the resources, and the others’ access will be blocked.

Here you have it, folks, you’ve successfully patched that security hole and fulfilled your privacy policy. :blush:


Hope this helps ~! :wink:
See you next one :raised_hand_with_fingers_splayed:
Ahmad

3 Likes

Masterclass content but maybe someone want to create a social network in Wix. So for sometimes it’s make sense maybe IDK :smiley:

You can then create a function to retrieve the necessary data from the members’ database, it’s generally better to have your data stored privately and securely, and only expose the necessary data depending on the situation, than having your data exposed by default, and make you look for ways to secure it.

If users don’t know whether their data is private or publicly exposed, they’ll sure hope it’s private.

Also, even in case of someone wants to build a social media network, do you think that social media networks like Twitter, Facebook, Instagram, etc… have their databases publicly exposed? If that’s true, you should be able to get a list of millions of users.

2 Likes

@ahmadnasriya I’m not a master but you are right at least I guess :slight_smile:

Hi Ahmed
Roy from Wix Security here.
We’ve looked very closely and thoroughly into your tutorial.
A few points about operability of public profiles on Wix .

  • A user can opt out of the site’s community, which will make their account private, and as a result not discoverable through any Wix API. (including the Members/PublicData collection)

  • After signup, a member can go into their profile and set their profile as private, if they haven’t done so already during the signup process.


The default option of a profile private\public status is determined by the application that installed the Members application whether it be the Forum application, Blog, or any other social application. Installing such a social application will make the default signup public (in any case, as stated above, the member can change the privacy during sign-up or later).

On the opposite end, we have applications that add Members Area that will not set the default sign-up as public, but rather keep it private. Furthermore, even when there is a social application on the site (like Groups, Blog, Forum), when a user is signing up during a purchase flow in Stores or other transactional applications, the member will be private by default. This was designed as a way to prevent mixing of intents of the members and to keep their privacy.

When the member signs up and the checkbox is marked as public (being a member of the community), the slug, nickname, and Image (if it exists), will be available to site visitors. Again, at any time the user can opt-out, either during signup or afterwards.


We provide more controlling tools for the owner of the site, and at any time the owner can change the default status of the privacy when members are signing in. In the settings of the member login, there is an option to change the default

Based on your input, we understand that the above logic is not clear enough, and we will devote some product efforts to improve the exposure of our tools and capabilities.

3 Likes

Hi Roy, thank you for the reply!

I’ll reply to each of points by quoting them and then replying to each one.

A user can opt out of the site’s community, which will make their account private, and as a result not discoverable through any Wix API. (including the Members/PublicData collection)
Yes, most websites (the basic ones) uses the default signup on lightbox, however, advanced and custom websites do not, which discarded this point completely in these cases, and if it’s public by default, then the user will have no choice but to go to their profile and set it to private, which takes us to your the second point.

After signup, a member can go into their profile and set their profile as private, if they haven’t done so already during the signup process.
As mentioned in the previous point, this is only applicable if the site allows its users to access their - default - wix profile, which as we all know, not applicable to cases where the site has a custom-built members area.

As of know, and AFAIK, there is no API to control this behavior.

And even if the users can change their profile exposure, still, having a public database of any data, especially about the number of the site members, can be a significant privacy concern, especially if competitors can see these data.

Being on a public databse means your name is publically indexed, I use Twitter, but I don’t want anyone to search Twitter’s members database for my name, and if I’m the site owner, I wouldn’t prefer my site’s - public - members number to be public.

1 Like

Hi Ahmad,
Happy to let you know that the functionality you were looking for is now accessible through Velo APIs, which would give you better ways of controlling site members privacy when using Velo.
https://www.wix.com/velo/reference/wix-members
https://www.wix.com/velo/reference/wix-members-backend

Specifically the a method to allow you to set profiles to public can be found here.
https://www.wix.com/velo/reference/wix-members/currentmember-obj/makeprofileprivate

If you have other concerns regarding privacy please let us know and we’ll do our best to address them.

1 Like

Thank you for your efforts, much appreciated :blush: