This question already has answers here:
Firebase Database - Risks associated with exposing uid on the client side?
(1 answer)
Is auth.uid a shared secret?
(2 answers)
Closed 2 years ago.
I'm designing a Firestore database for a Facebook-like, social media app and giving the users the option of posting publicly (name included) or anonymously. I had planned on putting all the posts in a top-level collection and using a uid field so users could retrieve and edit their own posts. However, it occurs to be that these uids would be pulled down when users read anonymous posts, so vulnerable to hacking? (e.g., finding non-anonymous posts with the same uids and exposing the user.)
So, now I'm thinking I'll keep the posts as subcollections of the user so that a uid isn't required.
Is my security concern valid? If so, is subcollections the better/best approach?
EDIT: My question is not a duplicate of this question or this question because it's asking about keeping user's anonymity, not editing their data.
Your point is right - the user ids could be exposed via initial method. There are several methods to approach this based on your solution.
All posts in users/{uid}/posts/{pid}
I wouldn't rate it the best method as it would require you to query all subcollections of user/post to show a "news feed".
Keeping the current structure & setting userid to anon
You can keep the current structure & set user id to anon in the document. This wouldn't let the OP edit his own anonymous post. To fix that, we can have another subcollection in users/{uid}/posts/{pid}. That would contain a "link" to posts/{pid}
This method is a combination of both of your methods.
Related
This question already has answers here:
Firestore Security Rules: Passing a request parameter in a get() call?
(1 answer)
Can I send value with request to Firestore rules
(2 answers)
Closed 3 months ago.
I have a URL like: https://myweb.com/customer/order?resId={resId}&tableId={tableId}
i research a lot but kind of like my issue was not anyone refuse yet: https://firebase.google.com/docs/rules/get-started
and I want to access this URL to allow read, and write without auth because I tend to use this route for Customers who scan QR and direct to my website
and my Firebase Cloud have tree collection like restaurant (auto-generate-ID) > table(auto-generate-ID)
What can I do to handle, please help me
The problem to face lies in the design of a RESTful API that can manage requests from multiple roles in an RBAC-based solution.
Currently we have different resources that can be accessed from different users, which can have one or more roles grouped according to their privileges.
The API we're trying to define must be as clear as possible to the client but without the overhead of adding additional metadata to the URL that could damage and even conflict with the REST practices and definitions. Therefore, we must avoid at all costs include information about the roles inside the URL. The plan is to use JWT tokens that carry in their payloads the info needed to know which permissions has the user making the request.
Having raised our current situation, let's provide an example and state the problem to solve:
Suppose we have * financiers * and * providers * as users with some roles who both want to access ** attentions ** (our resource). Should we add before the resource ** attentions ** information about the * user * whose trying to access the resource?
The endpoints in that case should be defined (as an example) as:
https://example.com/api/v1/financiers/:id/attentions
https://example.com/api/v1/providers/:id/attentions
This way we're attempting to inform the respective controllers that we want the ** attentions ** for that specific role / user which are, in some way, a sub-resource of them.
On the other hand, we could simply implement a much simpler endpoint as follows:
https://example.com/api/v1/attentions
The logic about which attentions return from the database should be now implemented in an unique method that must handle this two roles (and potentially new ones that could come up in the following features). All the information needed must be obtained from the payload from the token, exposing a much more generic API and freeing the web client from the responsibility of which endpoint call depending on the role.
I want to highlight that the attentions are managed in a Microservices Architecture and, hence, the logic to retrieve them is gathered in a single service. The cost of the API Gateway to route the two (and potentially more) of the endpoints from the first solution is a variable not to discard in our specific situation.
Having exposed our current situation:
Which we'll be the best approach to handle this issue?
Is there another alternative not contemplated that could ease the role management and provide a clean API to expose to the client?
In the second solution, is correct to return only the attentions accessible to that specific user based on the roles that it has? Isn't it counterintuitive to access an endpoint and only get some of the resources from that collection (and not all) based on its role?
I hope that someone could clarify the approach we're taking as there are little and none literature that I've found regarding this issue.
There there are multiple solutions for such kind of filtration, and developer have to select one depending on given situation.
As per my experience I can list following.
Structure
When data can't be accessed directly and developer has to use a relation (i.e a table JOIN). In that case URL have to include both the main and sub entities. Before going with this approach a good check is to ask, if the same URL can be used with POST ?
Example
If we have to fetch list of roles assigned to a specific user or want to assign additional roles then we can use
GET users/:uid/roles
POST users/:uid/roles
Security
With Multi-tenant systems where each user can have his/her private resources, i.e other users are prohibited from accessing those resources. Developer should save tenancy information and to filter the resources according to current authentication, without bothering client or requiring any additional info in URL
Example
Phone album of the user
GET photos
POST photos
Search
If it is not security or structure related but client still want to filter the result set depending on his scenario. then developer should use query-string for the filtration.
Example
Client have to fetch messages from his/her inbox or outbox or want messages which are not yet read. or he/she want to search his/her inbox
GET messages?folder=inbox
GET messages?folder=inbox&status=unread
GET messages?search=nasir
I am creating a database-backed application in native iOS. I see that there is a User UID attribute automatically generated by FirebaseAuth every time a user is created. Is it okay to use this UID as the documentID for a user in a dbUsers table?
My original firebase firestore schema had the UID being a field of the dbUsers collection, but this made it difficult to directly obtain information about the user since I no longer had a pointer (currentUser!.uid) to the user's document in the database and would have to perform a query and iterate over the querySnapshot. I'm wondering if there is a security risk or something else that would make this not a good idea.
Yes, it's OK. In fact, it's very common to do this, as it makes it easy to write per-user security rules for that document.
I want to create an app with IONIC to manage buildings. A user can hold multiple buildings. Each building has rooms. Each rooms has logs. Each user is a member of a cooperation.
For many years I've used LAMP. Now moving to mobile and made some IONIC apps. With 2 apps I've used sqlLite as datastore on the mobile device.
But now I've read up on couchDB and pouchDB and really like the concept and the sync option. So now I'm looking into this to use as my datastore (on the mobile and also on the backend).
Now I've got 2 major questions/concerns:
1) Authentication
In my LAMP situation, I usually have an SESSION (table which holds the sessions strings and userID) and an USERS table.
When the user logs in, the user is lookup in the USERS table, and a session string is created and saved with the userID.
Now each time a request is made to the server (for example update data), the session string is also supplied and matched to the SESSION table and retrieve the correct user. From that point on, I can validate if the post is valid and the data also belongs to the correct user.
Back to couchDB, I know there is a cookie management in couchDB (http://guide.couchdb.org/editions/1/en/security.html).
So here I can validate if an user exists and validate the credentials. Now the app can send requests with a cookie.
2) Fetch/Update the right data
In my LAMP situation, I always knew which data belongs to which user. And the back end always checks if this is correct.
In my couchDB I want to create database and each document is an user with all the data.
So now here comes the problem. I can validate an user in couchDB, put there's no way to validate the data (at least as far I know of) that it belongs to the right user.
My goal is that the mobile device syncs the document to the couchDB server.
3) Database structure
At first I wanted to create a database per user. But this is not scalable. Also an user is an member of a cooperation. I also need to generate reports per cooperation/user.
So now I was thinking to create a database per cooperation. But now the problem is, when a user login, I need to know wich database to connect to lookup the user data.
Now I want to use 1 database and each document is an user and holds al data (buildings/logs).
Has anybody got some other suggestions/resources on this approach?
You can try couchdb in combination with superlogin:
SuperLogin is a full-featured NodeJS/Express user authentication solution for APIs and Single Page Apps (SPA) using CouchDB or Cloudant.
github
Tutorial
I'm getting familiar with Breeze because I think that it can help me a lot dealing with data. Hovewer my biggest concern is data validation on server side. I read the documentation and I know that you should use your own ContextProvider and apply custom validation inside. I also read this SO post where someone was asking similar question.
But I think I got the case that cannot be handled in BeforeSaveEntity function. If it can, please tell me how:
Let's say that user is trying to update an article (his own article). This article has some ID.
How could I check if user is updating his article and not someone elses (he could change article ID in the browser, and this ID could be someone elses article ID). So entity would be still valid, but business rule does not allow to change other users articles by everyone.
I want to use EntityFramework and ASP.NET Web Api by the way.
If only i could get to something like "current user" and ID of article inside BeforeSaveEntity function...
You are rightly concerned to validate client save requests thoroughly and right also to distrust-in-principle anything the client sends.
Two issues here: who is the user and does s/he really own this article.
Who is the user?
Breeze stays out of the authentication business which we believe should be addressed by means that are (largely) external to the application code you write on server and client.
I would not roll my own security layer. That's asking for trouble. You might start your research with this article by Mike Wasson on Web API security.
Once you know who the user is, you must get application-specific facts about him or her such as the userId and what the user is allowed to do. I don't know where you get those facts as that is something specific to your application.
Whose article is this?
Let's suppose the current userId is 12345 and the update request specifies an article with articleId == 42 and userId == 12345. Clearly this article belongs to the current user. Is that good enough? Should we go ahead and save the changed article?
The answer depends upon how you assess the consequences of a rogue client updating another person's article. I'm not worried about updating a Todo (maybe I should?). I wouldn't trust this request if it concerned a bank withdraw.
I recommend spinning up a separate DbContext and querying the database for articleId 42.
Do not query the database with the DbContext from the Breeze ContextProvider inside the BeforeSave. That DbContext holds the modified article from the client. You want a separate DbContext to hold the actual entity per the database as it stands right now. These are separate entity objects in separate states. You can't have two different articles with the same id in the same DbContext.
If the queried article has userId 12345, you know the client made a valid request and you proceed. If the queried article's userId property is other than 12345, you reject the request.
You might treat this failed request as a potential attack and log it where you log security attacks. Maybe you'll monitor this user and the IP address and who knows what. I'm out of my depth here.
I'd probably reject the request with a mysterious 500. A real client wouldn't have made such a request and I don't want to tell a potential attacker the reason I rejected it.