Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Possible Duplicate:
Writing Web “server less” applications

So, let's say I'm going to build a Stack Exchange clone and I decide to use something like CouchDB as my backend store. If I use their built-in authentication and database-level authorization, is there any reason not to allow the client-side Javascript to write directly to the publicly available CouchDB server? Since this is basically a CRUD application and the business logic consists of "Only the author can edit their post" I don't see much of a need to have a layer between the client-side stuff and the database. I would simply use validation on the CouchDB side to make sure someone isn't putting in garbage data and make sure that permissions are set properly so that users can only read their own _user data. The rendering would be done client-side by something like AngularJS. In essence you could just have a CouchDB server and a bunch of "static" pages and you're good to go. You wouldn't need any kind of server-side processing, just something that could serve up the HTML pages.

Opening my database up to the world seems wrong, but in this scenario I can't think of why as long as permissions are set properly. It goes against my instinct as a web developer, but I can't think of a good reason. So, why is this a bad idea?

EDIT: Looks like there is a similar discussion here: Writing Web "server less" applications

EDIT: Awesome discussion so far, and I appreciate everyone's feedback! I feel like I should add a few generic assumptions instead of calling out CouchDB and AngularJS specifically. So let's assume that:

  • The database can authenticate users directly from its hidden store
  • All database communication would happen over SSL
  • Data validation can (but maybe shouldn't?) be handled by the database
  • The only authorization we care about other than admin functions is someone only being allowed to edit their own post
  • We're perfectly fine with everyone being able to read all data (EXCEPT user records which may contain password hashes)
  • Administrative functions would be restricted by database authorization
  • No one can add themselves to an administrator role
  • The database is relatively easy to scale
  • There is little to no true business logic; this is a basic CRUD app
share|improve this question

marked as duplicate by Jim G., ChrisF Dec 20 '12 at 12:25

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

    
Not exactly pure "client side to database", but have you looked at Parse and Firebase? (and also Meteor to some level), all of them have somewhat relevant concepts, and all handle security in creative ways. e.g. see this: blog.firebase.com/post/38234264120/… –  Eran Medan Dec 19 '12 at 18:59
    
Yes! I'd heard of Parse before but not Firebase. Very interesting, and definitely along the lines of what I was thinking. –  Chris Smith Dec 19 '12 at 20:53
    
How would your database protect against SQL injection or XSS being sent from the JavaScript? Pretty much anything sent from the client you have to assume it's unsafe, so what provisions are there in that database you can use to filter the data to make sure it's valid and insert data with prepared statements? –  zuallauz Dec 20 '12 at 3:45
    
"We're perfectly fine with everyone being able to read all data (EXCEPT user records which may contain password hashes)" Even data miners assuming a stack exchange maybe about the latest stock tips or somesuch? –  Erik Reppen Dec 20 '12 at 7:36
    
I have launched a similar project based on a MySQL database. I am absolutely sure (OK as sure as I can be) that I know my user base (+/- 200 Employees) and they must authenticate to do anything. Is my application still vulnerable? should I ask this as a separate question? Thanks –  Sydwell Dec 20 '12 at 8:27

11 Answers 11

up vote 34 down vote accepted

Doing as you suggest creates a tight(er) coupling between your client side language and your database.

That can be okay - there's less code to write and maintain, and in theory debugging could / should go a little quicker.

On the other hand, it makes other aspects more difficult. If / when you need to change either of those technologies, you'll have a harder time because of the tight coupling between them.

Protecting yourself against attacks will be (quite) a bit more difficult. You're assuming that the client will always present nicely formatted requests to the database. That presumes no one will ever hack the client side code to insert malicious statements. In other words, they'll "borrow" your authentication mechanisms and replace the normal client code with theirs.

I wouldn't recommend it, and many would vehemently tell you not to. But it can be done.

share|improve this answer
    
Interesting. How might an attacker borrow my authentication mechanism? I wouldn't be trusting the client to authenticate. The database would simply take an HTTPS POST to the session endpoint that would hash the POSTed password and check that it's valid. If it is, then it would return a session cookie to be used in future requests. –  Chris Smith Dec 19 '12 at 15:15
1  
All I need is the session cookie, right? I use your client to auth and get my session cookie. Then I steal the session cookie with my client and send up badly formatted requests to cause havoc. Remember that it's all on my machine, so I don't even need a MiTM attack. –  GlenH7 Dec 19 '12 at 15:33
4  
@ChrisSmith - so long as you feel you're addressing the security concerns then you're handling the primary objection to what you suggested. If you've got them handled or think you do then go for it. The simple version of your question is this: You asked why people don't do ABC. The primary answer is security and tight-coupling. Address those concerns and code away. –  GlenH7 Dec 19 '12 at 16:14
2  
Not to mention you don't have a place to cache frequently-requested data, so you'll have to hit the DB every time. Sure, maybe your DB driver does some caching, but how tunable is it? Will it share across threads? –  TMN Dec 19 '12 at 17:18
1  
I'm uncomfortable allowing direct access to my sql databases via direct sql statements from web clients because you never know what type of requests they'll be making. Will they run delete, update, or insert statements? If they do, will they provide the data your application expects? Will unexpected deletions happen? Unexpected database changes will usually break your application. It's best to minimize the commands going to your database so you can more easily sanitize the inputs you receive so your application has a better chance of working right. –  Nathan Pilling Dec 19 '12 at 18:19

Since this is basically a CRUD application and the business logic consists of "Only the author can edit their post" I don't see much of a need to have a layer between the client-side stuff and the database. I would simply use validation on the CouchDB side to make sure someone isn't putting in garbage data and make sure that permissions are set properly so that users can only read their own _user data.

Well, placing your authorization (the security concerns) and logic validation away from Database provides separation of concerns in your software system. Thus you may test, maintain, scale and reuse your logical code blocks with less risks of braking the functionality in the system.

Providing ability for client input directly communicate with Database has very big potential to screw up the data.

This also means that avoiding/removing tight coupling make your software system more maintainable and SOLID.

share|improve this answer
1  
I would normally agree with this, but I can test, maintain and scale code blocks within the client-side code just as easily as server-side. Doing it all in Javascript wouldn't be an excuse not to use proper separation of concerns. I'm simply moving the actual processing from the server to the client. So what is having the layer in between buying me? –  Chris Smith Dec 19 '12 at 15:18
2  
Having client-side validation is nice for client, but having it in place on your server side is more critical than ever. Because, your client side request can be easily simulated. Having logical separations and/or tiers helps in sociability and maintainability. –  Yusubov Dec 19 '12 at 15:24
    
So, playing devil's advocate: As I mentioned below, I could use CouchDB's validation functions to determine whether data being submitted is valid. Whenever you try to add or update a document, it would check that you're allowed and that it's correctly formatted. It puts more processing on the database side, but it is fairly lightweight and I need to consider scaling the data side anyway. Wouldn't this address the concern? –  Chris Smith Dec 19 '12 at 15:33
    
No, i don't think so. Placing your validation and authorization logic in DB is going to be performance hit on your system, once record numbers start to grow and you get more users on your system. –  Yusubov Dec 19 '12 at 16:15
    
The DB engines are meant to store and retrieve the data, not to manipulate or validate it. Of course you can do it your way, but it is not the efficient way to follow. –  Yusubov Dec 19 '12 at 16:16

Letting the user interact with the database directly seems really dangerous to me.

Is the authentication mechanism of CouchDB really so sophisticated that you can isolate the read- and write access of a user only to the data it is supposed to read and write (we are talking about per-document, maybe even per-document-field access privileges here)? What about "communal" data which is shared by multiple users? Doesn't this exist at all in your application design?

Do you really want the user to be able to change its data in ANY way? What about XSS injections, for example? Wouldn't it be better to have a server layer to filter those before they get into the database?

share|improve this answer
1  
You bring up good points, and I thought the same thing. I came to the conclusion that in this (hypothetical) application, I'm okay with anyone reading anything EXCEPT user records. They can only write to documents that they have originally created (which is the only "business logic" I mentioned above). CouchDB seems to have the ability to do both of these things through their internal _users database and validation functions. –  Chris Smith Dec 19 '12 at 16:44

If your security checks and business logic are contained in your client side javascript, they can be overridden by a malicious user. As an alternative, you can leverage a JavaScript based server-side technology (like Node.JS) to handle validation, authorization, and the like.

share|improve this answer
    
Authentication and authorization would be handled by the database itself, so I wouldn't be trusting the client at all in that regard. CouchDB has built-in validation functions that fire whenever you try to update a document so I would use those to check that what is being submitted is valid. –  Chris Smith Dec 19 '12 at 15:30

Any business constraint you may want to ensure should be validated server side. Even if you control user access, someone may send invalid data.

Following your stackoverflow clone example:

  • How would you block "closed" questions on the site from being edited anyway?
  • How would you prevent people deleting comments?
  • How would you prevent people from faking comment dates?
  • How would you prevent people from upvoting 50 times the same post?
  • There are probably a lot more examples if you dig a little bit more.

Any one could manipulate the client side code and violate data integrity completely (even if restricted to certain objects, like their own posts).

share|improve this answer

Edit page in firebug and at some point put a line similar to this:

ExecDbCommand("DROP TABLE Users")

Run it.

Edit:

The question was in fact about CounchDB so no sql to run here. Yet the idea is the same. I would presume that any non trivial application depends on data to respect some consistency rules that are checked/enforced by the application code. A malicious user can modify the client code to save data in a form that violates your business rules and might cause havoc in your application.

If your site considers all possible data states to be valid from a business perspective then by all means go this route but if this is not the case (likely) then you would want to have the guarantee that any data that gets stored is generated by your code and according to your rules.

share|improve this answer
    
CouchDB wouldn't know what to do with that, but I get your point. If permissions are set properly, the response to such a thing would be a 401 Unauthorized. –  Chris Smith Dec 19 '12 at 16:46
    
-1, when you post SQL code you obviously don't even know what CouchDB is. Also, just by creating an admin account on CouchDB you already prevent any other user from performing the most dangerous operations. –  Philipp Dec 19 '12 at 16:47
    
fair enough. i skipped the part on CouchDB in the question and only registered it as "access data store from client side JS directly". I'll edit response. –  AZ01 Dec 19 '12 at 16:51
1  
+1, SQL or not, his point still holds. A JS debugger could be used to alter how data is accessed. –  GrandmasterB Dec 19 '12 at 16:55

I think that, given all of your assumptions, it's feasible to go directly from the client to the database. However, it's reasonable to look at whether your assumptions are valid, and are likely to remain so in the future.

I would be worried that in the future it might not be OK for everyone to read all the data, and especially that it might develop more business logic in the future. Both of these are more likely if the project is successful.

As long as you leave yourself a way to deal with these problems in the future when and if you actually need to deal with them I think your design will work. I think you will need to be extra careful to separate concerns in the JavaScript code, and some of it might end up be rewritten on the server later.

But I could definitely see where it might be worth a risk of maybe doing that later vs. the benefit of fewer moving parts today.

share|improve this answer
    
Good point. This is definitely a narrow use-case, so it's not something you could apply to any application. –  Chris Smith Dec 19 '12 at 19:04

First of all thanks for the OUT OF THE BOX question.... :)

But what i would suggest is; Always try to maintain a segregation between your 3 layers. which are Presentation/Business and Database or DAO because that will be the best practice in those kinds of requirements and setups where there will be lots of changes every day.

In simple worlds your Presentation layer should not know about Database layer i.e. Format of some date type fields might be different from presentation layer and database layer so that user can have a freedom to select suitable format of the date as per his/her needs.

And Business Logic must act like a coupling between presentation layer and database/Dao layer like casting of the fields, some business validations, etc should be handled on Business Layer rather than in Javascript section as per your question.

This segregation will provide you great ease and comport during complex scenarios, functionality-es and even complex validations. The best advantage is: you can have different technologies to implement these layers and can be changed as per the business needs or scope.

Thanks

share|improve this answer

If you would like to build SQL in JavaScript and send it to the database, which verify the rights etc., than from security reason it would be a disaster. Simply because when you build an API, and build queries yourself, you have to analyse from the point of view of the security only the limited number of queries. If the queries are built outside your system, you have potentially unlimited number of tricks that someone could do.

But it's not the case since you are using key-value database (as fair as I understand, CouchDB generally falls into that category). The database interface itself is a kind of middle layer, and it is tested for security reasons by Apache team. Because of relatively simple JavaScript API this is even easier to analyse for potential flaws than such complicated interfaces that JSF applications have.

This can be a secure solution, if you do complex security tests. This can be even easier as when using frameworks such as JSF, which are often using hardly readable API behind. Security by obscurity is considered no solution.

Relating to your question, it won't be direct access to database anyway. Direct access would be the building SQL queries in JavaScript (unfortunatelly, I've seen such solutions). In your case the CouchDB itself provides the isolation layer. You could of course wrap it in your API to harden it, but as long as you can easily test what can particular user do and if the security constraints are working for you, you will have secure and robust solution without additional layers.

share|improve this answer

I see two problems:

1. Tight Coupling: Change your DB option? Well, now you gotta change all your client-side code too. Trust me. We don't need more problems on the client-side.

2. TMI Security Issue: Reveals way too much about how stuff works. Auth might still be an obstacle but finding an exploit is a Hell of a lot easier when you know exactly what's happening on the server-side.

A very-very-thin middle-tier might be a better way to go.

share|improve this answer

Your client cannot use your web app if javascript is disabled (or not supported on the browser of his device) if javascript is the only database-access-layer.

share|improve this answer
1  
Eh, not too worried about this. Most of the web now relies on Javascript anyway. I might just have to break out the <noscript> tags and tell them they need to turn it on if they want my site (and 80% of the other ones out there) to work. –  Chris Smith Dec 19 '12 at 15:19

Not the answer you're looking for? Browse other questions tagged or ask your own question.