Let me first start by stating that I am by no means a webdeveloper, so please do point out if I'm going in the wrong somewhere in my story.

I think most people agree with the idea that using prepared statements effectively stops injections if executed properly. With that said, in order to write prepared statements in PHP, you need to establish a connection with the database in your php file. In other words, if the webserver ever becomes compromised, the account used to establish a connection with the database becomes compromised as well as its basically there inside a php file, allowing your attacker to basically create dumps out of your database. If I were to design an application, I would separate the website and the logic, through some API server or something similar, in order to make sure that the database account isn't compromised as well.

Why is it that nobody points out what in my eyes looks like an obvious security flaw in PHP? Or is the chance of this being exploited so small that people aren't even considering the chances that it might happen?

EDIT: Allow me to clarify a bit more about the subject. I don't think there's anything wrong with using prepared statements and people seem to have the wrong idea that I'm against it. My point is that if you use prepared statements on your webserver, it would also mean that a database account is stored on the webserver. Your webserver getting breached is a pretty bad problem, but I would like to think that it's even worse if a database account in plain text is leaked because of this breach. This is what I am referring as a security flaw, because wherever I check guides about PHP, nobody seems to mind the fact that you would have a database leak the moment your webserver is breached.

As I was saying, there's nothing wrong with using prepared statements, but I do think that there's a problem with using prepared statements in PHP specifically. Would it cause a problem for the webserver to proxy the request to another server that handles all the queries if you have a website written in PHP, for example?

  • 1
    Your question is actually not about prepared statements at all. It is about directly accessing the database from the web application (with or without prepared statements) vs. indirectly accessing it via some additional gateway. But note that access to such API gateway should need authorization too - which means that such API does not solve the problem of storing some credentials in the web application. – Steffen Ullrich Apr 20 at 5:09
  • @SteffenUllrich I honestly do think I should've done a better job in formulating the question, but there's not much I can do about it now :/ But direct access vs indirect access, is that what they call it nowadays? – Tsubakura Apr 20 at 5:20
  • 1
    "But direct access vs indirect access, is that what they call it nowadays?" - it is definitely more to the point of what you want to know since the difference is not between prepared statements and non-prepared statements - both require direct access to the database. But again, no matter if the database is directly accessed or some API gateway instead: the web applications has to authenticate itself somehow against database or API gateway and these credentials need to be stored somewhere. – Steffen Ullrich Apr 20 at 5:30
  • @SteffenUllrich The current question is probably too badly formulated for me to get a good answer out of people. Since you're the one who gave an answer that helped me the most so far, do you mind creating an answer for me to accept? – Tsubakura Apr 20 at 5:45
  • I don't think that it makes sense to add yet another answer here. The problem is (as you noticed yourself) that the question itself is badly formulated and just adding another answer does not fix this problem. Don't worry about this, just learn from it and ask a better question next time. – Steffen Ullrich Apr 20 at 6:40

Why is using prepared statements in PHP considered best practice?

To avoid SQL injection attacks originating from outside your server (e.g., the Internet).

Why is it that nobody points out what in my eyes looks like an obvious security flaw in PHP?

What flaw? That your server could be breached? It's not clear from your question what "obvious security flaw" you mean? That if the web server is breached then the attacker has access to the database? Yes, that is true, and it doesn't help to move the database to a separate server. In fact, most real web apps will have the web server on a separate machine from the database server.

Or is the chance of this being exploited so small that people aren't even considering the chances that it might happen?

As above, it's not clear what this "obvious" flaw is that you are discussing here... The server getting breached?

Yes, if the server gets breached you have major problems. That is not a flaw with PHP prepared statements. So, these latter two questions don't make much sense in the context of the title of your post.

| improve this answer | |

An "API server" as you describe it would add zero real security. If the Web server got compromised, then it could just dump whatever information it wanted by querying your "API" instead of querying the database. And you certainly wouldn't fix SQL injection by doing that; you'd just push it to the other server.

| improve this answer | |
  • This whole thing isn't exactly about preventing SQL injections, since we all can agree that prepared statements is the way to go for that. It's more about preventing attackers from compromising the database account the moment the website gets hacked, in order to slow down the attacker. I personally don't think its necessary to store the database credentials on the webserver, but I was wondering how PHP developers think about this scenario, hence my question. – Tsubakura Apr 20 at 4:39

I think the answer you're looking for is that a database server can be configured as the "API server" you describe. That is, a database does not have to allow arbitrary queries! You can use a feature that some database engines call "stored procedures": blocks of SQL (usually with procedural programming extensions like loops and local variables) that are stored in the database, not in the client (which in this case is the web server). Then, you can create a database user who only has permission to execute those procedures/statements. If your web server establishes its database connection using that limited-access user account, it cannot execute arbitrary statements; it can only run the commands that it needs.

This sort of strict "principle of least privilege" - the web server only gets the DB access that it needs to do its job, preventing it from doing anything weird - is a good way to harden a system when you must design it to be resilient even in the face of expected compromise. However, it's slow to develop (although can be fast to execute) and requires breaking apart the program logic in ways that are sometimes strange (for example, you might perform more processing on the DB server than you normally would, on the assumption that the web server can't be trusted to validate things correctly). This kind of slow and careful development is expensive; most companies don't feel it's worth the time for their developers to work this way, and many developers feel that it's a lot of "busy work" per feature. It can also require using more expensive or complicated software; I believe MySQL fully supports stored procedures and limited users now but older versions did not, and certainly things like sqlite don't.

Also, this doesn't necessarily solve everything. While it does mean that compromising the web server won't automatically give unrestricted access to the database, it is totally possible that either the DB engine itself or the procedures you wrote for it have bugs that could lead to anything from SQL injection to arbitrary code execution on the DB server. Additionally, you still need to secure the database; it doesn't do much good to have the web server only use a low-privilege user if the administrator password is still its default value, and the attacker just opens a new connection using those credentials (or if they're stored on the same machine and the web server is running as a user with access to the DB file or some such thing).

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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