Init/data returns records without login — how to fully lock it down?

Hi all — I’m trying to pass a security review and ran into an access-control issue.

If I visit this endpoint while logged out, Bubble still returns some data: https://bookpilot.co/api/1.1/init/data?location=https://xxx/xxx/1756813939720x797068929125331000

I’m not even passing a real frontend page (it’s a fake path with a real userID), but init/data still returns something.

I’ve tried

  1. Page-level redirect if Current User is logged out.

  2. Disabled caching for the page.

Question: How can I completely block init/data from returning any data unless the user is authenticated?

No. It is used to load a page’s data type (if configured) and also the Current User (though that’s off the top of my head so I might be wrong)

Privacy rules will restrict data access when configured correctly, so if this is returning data you don’t expect, then that’s the root cause.

Thank you for the response! I’ve done some testing and here’s my observation.

It may not be related to “page data type“ or “current user“.

Reason is that:

1. I tested that this location value in the url(location=https://xxx/xxx/1756813939720x797068929125331000) is not even a real location, you see I replaces value with “xxx“ and it still returns data

2. If I put user ID, it returns some user data: https://bookpilot.co/api/1.1/init/data?location=https://xxx/xxx/1756813939720x797068929125331000

If I put another data type’s ID, it returns a different data type.

Regarding Privacy Rule

There are 2 questions:

1 - Even though if I tried to disable everything for everyone else, it still returns something.

2 - I need to evaluate whether a user has been failed logged in several time before they log in, if I disable everyone else to see the “log in failure count“, the workflow won’t be able to

That returns the current user’s information.

Well that’s good, because otherwise the user’s data would be leaking. You need to run this logic in a backend workflow that ignores privacy rules.

I see! I’ll move the login check to backend workflow.

But regarding the current user’s information point, it’s actually returning the data of what ever the ID I passed into this url. As shown below, first screenshot is when I pass user ID, and second screenshot is when I pass a transaction ID.

There’s no data returned (presumbably because you have privacy rules on the transaction data type)

”data”: {}

for user though, it seems like it’ return {“authentication”:{“email”:{}},“user_signed_up”:true} in the data as a minimum?

There’s no way to let it return just empty like this? For example if i change the location url to this instead:https://bookpilot.co/api/1.1/init/data?location=https://xxx/1756813939720x797068929125331000 it won’t return anything.

No, there isn’t.

What data is this returning that you can’t already access given your app’s privacy rules?

I didn’t get what you mean here. since the security check is pretty strict, less data show here may be better. For email, I can set in the privacy rule to hide it, but I don’t think I can hide “user_signed_up”:true in the privacy rule.

If you have the user ID, you know they’re signed up, don’t you?

If you don’t have find this in searches enabled, people can only find a unique ID by guessing, and that’s near impossible. And, if they do guess it, there’s not much they can do with it other than know an item with that ID exists.

1 Like

This seems related to the Bug I raised a few days ago.

When testing and trying to understand what was the cause of the protected data remaining visible after logout and using browser back button, I saw a lot of stuff about the init/data.

There was some help in understanding, but nothing that was definitive. It was hypothesized to becoming from the BFcache, but from testing it was coming from http ‘memory disk’ cache, which as far as I can understand, those two are different. ChatGPT was helpful in helping me setup some tests to uncover exactly what was going on and it seems Bubble is allowing private data to be cached if a page has a content type, or if a search uses a unique ID in the URL path list item #2.

I know the reason for the private data remaining accessible even after logout is different from how you are seeing private data available as you are doing a direct api call to the init/data. I just mention what I saw as during the testing I could see that same api call running and recall it as suspect when navigating back to the protected page after logout.

Try reaching out to Bubble support. They likely have a web security expert that could look into it. I imagine if you are doing this for a the purpose of a security review, and the review failed because of this issue, whoever did the review is likely a qualified and experienced web security expert with some deep knowledge on a subject like this.

I was trying to figure that out for the bug I was dealing with. ChatGPT suggested intercepting the api call to attached headers to it so as to force it not to cache the data.

Out of curiosity, are you experiencing this on a page that has content type set on it, so as to use the ‘current page thing’ in dynamic expressions on the page?

The endpoint does not return data the user does not already have access to :man_facepalming:

Yes, I understand it doesn’t return data the user can’t access. However the security review has been strict—we’ve been marked unqualified multiple times. They still haven’t confirmed whether returning {"authentication":{"email":{}},"user_signed_up":true} is acceptable yet. Hopefully this is fine but the safest is to return .

Thank you I saw your post too! I’ll try to reach out to the support.

The weird thing is that I am able to get the data even without passing an actual page url. As long as I put the uniqueID in the third-level, it’ll return some data. Like this one it’s just dummy data “xxx“: https://bookpilot.co/api/1.1/init/data?location=https://xxx/xxx/1756813939720x797068929125331000

Well, any security reviewer shouldn’t find an issue with an intentionally public endpoint that only returns data that the user has access to :joy: Hope you can get through it

1 Like

Just heard back from the security review team—unfortunately, this doesn’t meet the requirement. The endpoint should return a 404 or 400 error when no data is found, rather than the current behavior.

Would appreciate any help or suggestions on how to address this! Thanks in advance.

That’s awfully pedantic of them. There’s nothing insecure about returning a 200 rather than a 4XX so long as no data is returned. They’re wasting your money.

1 Like

I can only also agree with @georgecollier

In fact, this would be an error to return a 404 (not found) or 400 (bad request). They doesn’t represent what really happen.

404 mean this endpoint doesn’t exist. This is not the case.

400 mean the request to the endpoint was not the one expected. Again, this is not the case.

I also think it doesn’t really make sense… But I am trying to submit the app to a product’s marketplace, so I can’t really argue anything

1 Like