4

I have heard from my colleagues and some other people on web suggest that it is more secure to run this configuration:

Web server -> Application server -> Database, than this:

Web server -> Database

The reasons that if an adversary takes control of a web server, then there is one more layer to overcome if you need the database.

I think that if an adversary controls the web server then they are as good as having full access to the database, since they will be able to execute arbitrary requests to the application server that will trust them. It will slow them down I guess, but the extra effort to implement a middle tier + all possible holes in the application introduced by that seems not to be worth the effort to me.

P.S. Since I was told that my question is to generic, I will add more information on the setup that I have.

I have a SPA client that talks only to the API and token is used as an authentication scheme. Web application really provides only the initial request to hook up the application and there are no other calls apart from static files and API. The web application then talks directly to the database in the Data Layer. I have just one user in the database and all access is controlled by the business logic and/or the authorization layer in my framework (e.g. roles in a token can be verified with attributes before it goes to business layer, so without a required role you are not allowed to access some API at all). So there is not danger in anyone calling any of the API (unless I fail in protecting them appropriately, but that's another story).

So taking into account this setup, would there be any advantage from security point of view to make web application's data layer to talk to the application server that will handle the business logic instead of the database directly (and the application server will talk to the database). In this case the web application is generally reduced to the initial loading of the client + a proxy to the application service, which seems quite superfluous to me.

Ilya Chernomordik
  • 2,197
  • 1
  • 21
  • 36

3 Answers3

5

If you distinguish between web server, application server and database then you actually mean front end, business logic and back end (storage). This is also called a multi-tier architecture with presentation tier, application tier and data tier. In this case the application server will not simply pass through any requests from the web server but only allow actions which fit the business logic. This means that all the security stuff (i.e. who can access what) is essentially done in the application server and the web server is just there to make this information accessible via a web browser.

If you instead only have web server and database then the business logic is essentially part of the web server. While this makes it often easier to start wih some web application the missing distinction between presentation and business logic will lead easily into a mess which nobody can understand anymore and which often allows to bypass the business logic and thus get direct access to the database for an attacker.

Note that the separation between the layers does not necessarily need to be done with a separate server or application, but it can also be an in-process seperation (i.e. API, classes...). But it is important that this separation can not be simply bypassed which can often be handled more securely with a separate process or server. A missing separation between presentation and application can sometimes be seen in that you can't access specific information by HTML but they are still accessible by a JSON or XML API.

Steffen Ullrich
  • 184,332
  • 29
  • 363
  • 424
  • 1
    The distinction between presentation and business logic can be properly maintained without putting it into the separate tier. It's just the way you architect your application, so I am not worried to much about that part. I don't see what the web-server is for at all in this case, since I e.g. use SPA and the web server is only responding to API calls + returns static js, css, etc. So you might think of the browser as the client that talks to the application server (which is web server based). – Ilya Chernomordik Feb 07 '16 at 12:35
  • @IlyaChernomordik: of course there is no requirement to do it as separate tiers, but it makes lots of things easier to maintain. I think that for anything but simple applications it is better to have a clear separation between presentation and business logic, no matter if this is a separate application, separate server or just a clean API **which can not be bypassed**. And things like adapting to specific browsers, distinction between JSON and HTML access etc don't belong to business logic. – Steffen Ullrich Feb 07 '16 at 12:59
  • I do understand that, but I am more interested of a bit another aspect, and that is what additional vulnerabilities are there in the direct database access (provided my API that the client accesses is adequately secure). – Ilya Chernomordik Feb 07 '16 at 17:47
  • @IlyaChernomordik: if your API is adequately secure then there should be no direct database access possible. Only database access guarded by business logic should be possible. A simple in-process API might not be fully able to protect this since maybe it can be bypassed by simple not using the API. Separation by using a different process ("application server") on same or different host might be safer. There is a reason OpenBSD is doing all the privilege separation stuff with separate processes. – Steffen Ullrich Feb 07 '16 at 18:45
  • I see what you mean, but it is not possible to bypass the API, unless there is a bug in the framework itself (ASP.NET MVC in my case). Otherwise there is no access outside of the API available, it's not like you can run a query right to the database from the browser :) – Ilya Chernomordik Feb 07 '16 at 19:06
  • 1
    @IlyaChernomordik: So you are asking a very general architecture question and get a general answer. But then you'll find the answer does not fit your specific case? Maybe you should have asked a more specific question then. – Steffen Ullrich Feb 07 '16 at 19:41
  • I am sorry for that, I guess I'll have to change the question with more details on the architecture since my question is to generic. – Ilya Chernomordik Feb 07 '16 at 20:01
4

You need an application layer as a filter because most* database systems do not allow permission handling which is fine-grained enough to handle multiple users.

Usually* you can create users with different read- and write permissions, but usually* these are designed for up to a few dozen users and do not scale well for thousands or even millions of users. Also, you usually* can only set permissions on a table-level not on a per-row level yet alone a per-field level.

This means it is hard for you to control what data your users can and can't view and which data they can and can't edit. To give an example, let's take a users-table with these columns

userId
password
profilePicture
createdDate
lastLoggedInDate

People should be allowed to change their own profilePicture, but not that of other people. Nobody should change the createdAt field and changing the userId could cause all kinds of hijinks. Every user must edit the lastLoggedInDate when they log in and set it to the current date, but not set it to anything different. Can your database handle this complexity*? Oh, and we haven't even talked about references between tables yet.

Well, but what if you simply forbid this on the client-layer by just not writing the GUI code to do the stuff the user is not supposed to do? The problem is that your database has no way to verify that your client application is really the program you wrote. When it speaks SQL and sends valid login credentials, the database will trust it. A malicious user could write their own client and send arbitrary SQL commands to your database.

* I don't want to say it is impossible for a database to exist which can do all that, but so far I haven't seen one. When you know one, feel free to comment.

Philipp
  • 48,867
  • 8
  • 127
  • 157
  • Most databases can handle complex authorization by having stored procedures do the updates, and only granting access to stored procedures rather than the tables. Whether this is a good idea is another question. – paj28 Feb 08 '16 at 09:13
  • I guess I'll have to expand the question once more: I have just one user with full read/write access and control the access on the web application, but I take precautions to not trust any user input, it's not like there is an action you can take that is hidden in the GUI. So provided I do control all the input in the API and do ACL in the business layer of my web application, do I get anything by introducing new layer? – Ilya Chernomordik Feb 08 '16 at 10:56
4

"More secure" is unconstructive

Thinking something is "more secure" often leads to poor decision making. All sorts of things are more secure while being a bad idea. It's more useful to ask "Does this add meaningful security?" and "Is the security gained a reasonable tradeoff between cost and benefit?"

Tiers don't add much security

Most infosec books recommend the three-tier model. I've found the two-tier model is just as common (maybe more common) and this includes a large number of highly critical apps I've audited: online banking, etc.

The reality is that having two tiers is only a marginal security benefit over a single tier. People will often say "if the web server is hacked, they're not on the database". While technically true, that is misleading. The web server will have credentials to connect to the database, which will allow an attacker to extract all the data. You can imagine certain attack scenarios where having two tiers blocks particular exploit vectors, but these are uncommon.

The security benefit of three tiers vs two is even less than two vs one. And this is especially so with SPAs, where the web tier is on the client.

Edit To be clear, I mean tiers as in tiers on separate servers (virtual or physical) - rather than a purely logical separation.

paj28
  • 32,736
  • 8
  • 92
  • 130
  • What do you mean by one-tier? Is that a web server and a database on one server or something? It seems to me this is completely irrelevant where it's located since as you say you have the credentials anyway. And with 3 tiers you kind of cannot perform queries directly, but you can have full access to internal API which is almost the same (just harder to find out, but it's security by obscurity). Is that the main reason that you say it's not adding "meaningful security"? – Ilya Chernomordik Feb 08 '16 at 11:54
  • @IlyaChernomordik Yes, one-tier means web server and database on the same server. And yeah, having access to a query API is pretty much the same as having access to the database, so it doesn't add meaningful security. – paj28 Feb 08 '16 at 12:03
  • Thank's a lot, these were my thoughts already, but I wanted some proof from security professionals, though other answers (e.g. Steffen Ullrich) suggest that it is actually more beneficial to add this layer. – Ilya Chernomordik Feb 08 '16 at 12:10
  • @paj28 I don't think thinking about having the stack on the same OS is a common way of expressing tiers. Thus Ilya's question. Also, consider the case where the webserver only has read access to the database. If the webserver and DB on on the same OS, getting access to the webserver gives a large attack surface at gaining higher privileges to the DB server. I'd agree about 3 tier architectures though as adding little security benefit. – Steve Sether Feb 08 '16 at 15:32
  • @SteveSether - read only access from web server to database? Sure that would give some benefits to tiering. I don't think I've ever seen a read-only web app though. And I'm not sure what you're getting at about the same OS - I didn't even mention OS choice? – paj28 Feb 08 '16 at 15:47
  • @paj There's plenty of sites that are read only. Static website driven by a database for instance. I use the word OS in place of "server" since server is ambiguous. Normally separating the two into different OS/Server is driven more by performance and other concerns than it is by security. – Steve Sether Feb 08 '16 at 17:14
  • @SteveSether - Ok, I was using "tier" to mean separate OS. This is standard terminology (CISSP, etc.) in my experience. Enterprise architects are usually keen to put tiers on separate OS instances, because of the perceived risk of privilege escalation flaws. Large BS I think, due to reasons in my answer! I take it you mean tiers as logical tiers? – paj28 Feb 08 '16 at 19:14
  • @paj28 I don't know what the silly CISSP test says. But the standard in web development and architectural development is to refer to tiers as separating different responsibilities. How many OS's you're running under is irrelevant. – Steve Sether Feb 08 '16 at 19:23
  • @SteveSether - I've edited my answer to make clear the meaning of "tier" I was using. – paj28 Feb 08 '16 at 19:33