I am about to start a new project with Flask+AngularJS, first time experience with such mix. But my questions are not related to my choice of platform/framework.
There would be loads of situations where some lists of items are presented to user, and user can click on one of the items to browse it. Naturally, such functionality would be provided by passing to the client a list of item database ids, and browsing would happen by requesting item info by its id. However, I am uneasy about enabling user retrieving some information by its it. There could be cases when a user is not entitled to open certain item.
So, I have two questions:
Is it good idea to share database object ids to the client? It's definitely easier, but doesn't it reveal too much info for a malicious logged-in user? An alternative could be generating a unique ID for every clickable item, and keeping at the server side a dictionary what those ids mean. Feels like pretty big hassle (not to mention extra processing overhead), but maybe it's worth the pain?
If I'd go with revealing the item database ids to the client, then I should still keep a list of the items that were shown to the client (in this session), and let the user browse only those. Thus, any attempt to browse an item by entering its id directly in URL (or POST request) would be stopped, if the user "had no legal way to access it". Is there any name for this technique, so I could read on the best practices how to implement it?
Related
I am building an ecommerce website which should be able to handle guest checkout. When a user visits the website, they are considered "Guests" unless they register / log-in to their account.
However, even as a guest, certain information needs to be stored about that visitor (partially incase they make an account in the furture, but also just for the website to function for them) like their prefered currency, email (if provided), cart and its contents, and an order_id (if they placed an order)
My question is which of the following choices would be better for handling this?
By the way: I am using NodeJS's express-session in this project.
Creating a "User" object for all new visitors and adding the user_id to the session. In this case that user object would need a feild called is_guest: true/false to tell the two apart, and it would also need a is_logged_in: true/false feild so the front-end can tell whether to load the log-in form or the profile page because a user object would always be present.
Only creating a "User" object after an account has been registered through the register form, and storing all data about the cart and email ect. for guests on the session object instead.
I can see problems with both. 1) could result in a really large database if all new visitors create a user object. 2) could result in information being scattered more and the session object becoming cluttered (especially if the cart becomes large). Having never done something like this before, I would appriciate any ideas about objections or solutions to the approaches and what you think would be the best.
Both solutions are fine, and I've seen both being used.
I would guess that storing things in the database is more common. Since you will probably be logging user interactions in your database anyways, it won't take up much more data. Secondly it's slightly simpler to use the same function to render pages for logged-in and logged-out users.
If you don't use a database, you may wish to use LocalStorage instead of a cookie since there are size limits to cookies (although few carts will get large enough to reach that limit).
Given that clients can tamper with GUIDs if they are generated client-side, wondering how to mitigate this problem if you allow working offline.
Say you have a Todo list application and are working offline. From what I'm thinking, as you create todos, the client is creating GUIDs for the todos, as well as any attachments or associated records. Then say you go back online and it syncs. The GUIDs created on the client could have been tampered with, so something possibly needs to happen during a merge. Maybe all new GUIDs are created server-side, and sent back to the client to overwrite the client-generated ones. Not sure.
Wondering what best-practice is here.
I think yes, ids could be reassigned when sent to the server. One way this could be done is have a client-side id and a server-side id, the latter only assigned if it's saved. The client-side id can then also be removed from the design, but then upon a succesful save all references must be updated.
And then the problem is the inevitable inconsistency, because what happens if the server already received the update, assigned a server-side id, but the confirmation response never made it back to the client. Upon the next download, the client will see a new item on the server which it cannot associate with any client-side item, unless there is some kind of a heuristic to identify duplicates (eg. if all fields are the same in a client item without a server-side id, it is most probably the same).
I think this is less of a security question though, if the format of the id is validated (for example it must be a guid, ie. numbers, letters and dashes), it doesn't really matter what exactly the client sends. So from a security point of view, this is almost purely an input validation question, which of course must be in place, errors must be thrown on already existing ids and so on. Then it touches on access control as well, if multiple users are using the app, but that's a different topic, any access must be authorized anyway, and access control decisions must not be made solely on the id. That is, it's not a good access control model if you can access anything you know the id of.
My title is probably vague so please check my situation below.
I have a web application to manage a list of employees. The application is set up in a hub-spoke pattern where clicking an employee from the employee list redirects to a new window showing the chosen employee's personal details for possible updates.
The application uses HTTPS. The employee list and details are retrieved via GET while the details are updated via POST. The application uses HTTPS and all users (there are only a few of us) have the authority to retrieve and update employee details.
My question is, will it still be required or suggested to check the employee ID (the primary key) during update/post operations? A sophisticated user can theoretically change the employee ID before the POST and update another employee's details even without pulling out the 2nd employee's record. Still, even if that user somehow fools the interface, any of his "hacks" would simply be acceptable since the user can retrieve and update any employee anyway.
So in my case, would you still consider it necessary to enforce a mechanism so that only the currently shown record is updateable? If yes, what are the accepted practices for implementing this? Thanks
Many web based systems are designed to be stateless. The main reason is to allow multiple sessions/windows.
You could potentially store the currently edited employee ID in a session variable and only allow changes to that employee ID, however, what if the user has two browser windows open in the same session? Now, you have to keep the currently edited employee ID for each window. Well, you don't have this information, so you have to store the employee ID in the form itself, and this is all editable by the client.
So, instead, simply enforce the rules on the server, and if they have permission to edit that employee, let them.
Ensure that your system is using HTTPS to prevent man in the middle attacks, escaping all output to prevent cross site scripting (XSS), and requiring POST for all updates as well as using sessions and form tokens to prevent cross site request forgery (CSRF). Once you've done that, any employee ID manipulation will likely be self-inflicted, and your job isn't to protect the user from themselves.
What you usualy do is - click on a row, get the employee ID and send it to the server, retrieve information by ID and publish it to the user. Usualy you keep the ID as some jind of hidden value, so when you update, you update this ID. And, usualy, you don't allow ID changes. IMO no need of checking ID, but if you think some one can jump over, just check if the ID of the page is the same you have in the hidden value.
I'm currently working on a web application which deals with multiple users. Whilst it currently works, it relies on some real bad practises which I'll outline in a minute.
We're using MySQL as the database system, since we're updating our current application, we want to ensure everything is backwards compatible. Otherwise I'd look at MongoDB etc.
Our users are stored in a table aptly named login. This contains their username, email, hashed password etc and a field which contains a JSON encoded object of their preferences. There is no real reason for doing this over using a meta table.
So the bad practises:
We're storing the entire users login row, excluding their password (although this is an internal-only app) in a cookie. It's JSON encoded.
Once the user logs in we have a secure HTTP cookie, readable only via Node.js for their username and their password so that we can continue to keep the user logged in automatically.
We have a app.get('*') route which constantly ensures that the user has their three cookies and updates their acc cookie with new preferences. This means that every time the user switches page or accesses a new AJAX item (all under the same routes) they have an updated cookie.
Every time a user performs an action we do this to get their user id: JSON.parse(res.cookies.acc).agent_id yuck!
Now, each user is able to perform actions to certain elements on the page, this effects everyone as the application is internal and anybody can work on the data inside of it.
I know what I want to achieve and how it should be done in say PHP, but I can't figure out the most effective way in Node.js.
I've started creating a User module which would allow us to get the user who performed the action and neatly update their preferences etc. You can see this here bearing in mind that it's a WIP. The issue I'm having with the module is that it doesn't have access to the users cookies, since it's not "a part of" Express. Which explains the last bad practise.
What would be the best way to handle such a system and remain bad-practise free?
I doubt it meets all of your requirements but its worth checking out out Drywall; A website and user system for Node.js
Hopefully it (or parts of it) could be helpful to you.
http://jedireza.github.io/drywall/
CouchDB offers validation prior to allowing an object/row to be inserted into the database. This make sure that if you have a public facing couch application, you're database won't be filled with junk by just anyone.
User <-> CouchDB
However, I'm tring to figure out what that looks like comming from the standard application design process where you have a trusted middle layer that does much of the auth work. For example, most apps place Ruby or PHP between the database and user agent which allows the application to figure out information about the user agent before allowing something like a post to be saved to the database.
User -> Ruby -> MySQL
User <- Ruby <- MySQL
How do you trust the user to do administrative tasks when the user can't be trusted?
For example, how would you do something like "email verification" prior to inserting a user row using just couchDB? You can't let the user agent insert the row - because they would fill the system with spam accounts. On the other hand, there is no middle layer either that can insert the row after they click the link in the email.
How about this, I would assume that you would allow anyone to enter their email by creating a new record in a public table like email_verify. This is something that a public user agent could do as the table would not do anything in the application - it would just be a holding tank.
Then node.js could track the _changes feed and send an activation email while creating a new entry in a private table (like email_confirm) (node.js would serve as a trusted middle layer). If the user clicks that link and comes back then... [unknown] ... and node.js could finally create a record in the private user table (user).
At this point we could then rely on couchdb validation for the rest of the application since we got a confirmed user account created.
As more background lets imagine a discussion built on couchdb that anyone can register for. We don't want to allow just anyone to directly submit content without some kind of verification - yet the user agents all directly run the system. (Tables would be Thread, Comment, & User). How would this work?
I would think about adding roles to existing users in this issue.
Using couchdb's validation and changing _design/_auth can be a good idea to add email, email_verified and randomly generated email_verification_code in _users database when the user firsts registers.
To send mail, get confirmation, resend confirmation you can use external processes. (for an example usage of external process you can check couchdb-lucene).
And at last you can again do a quick check in _design/_auth in user update process if verification code matches and add verified_user role for that user.
This way all your requests would pass over couchdb, you would use external process only when you need to send mail and get confirmation.
Edit : Forgot to add (since it was pretty obvious), I would add verified_user role to database readers.
Couldn't you just make use of CouchDb's Validation ?
Users could be flagged. Upon registration, a User is added to the Users database. He gets his mail and then is flagged "valid:true" or something like this upon answering to that mail or clicking a link.
With validation users could not only be "logged in/out" but also access authorization can be implemented with more granular access rights. E.g.: Only mark threads solved if one is the author, admin, whatever...
Or does this seem impracticable?
After talking with some people on #couchdb IRC, it seems that they can't figure out out a way to do something administrative (like activation users that click on a email link) with out using a "backend" process like a node.js server which keeps track of the _changes feed.
I was hoping for a pure couchdb app - but it seems like couchdb still has a little ways to go.
Still, the good news is that you can hand off 80% of your applications logic/processing to your users. The other 20% will be 1) a node.js instance for things like sending emails or checking recaptcha and 2) record validation functions running in your couchdb, and 3) map/reduce (query) functions. These three things cannot be offloaded to something "untrusted" like a user-agent.