Just learning php and aiming to write quality code.
I read everywhere that you should close all database connections to reduce vulnerability of your system. It's okay, but why and when?
Connections are closed automatically at the end of runtime. So questions are:
Can anyone please refer to me a resource that explains how an open database connection can actually be exploited? And for how long can it safely be open?
What is the difference if I close it with the last line of my application or leave it for the shotdown handler?
Some worth-reading description on the topic would be welcome.
Here are 3 simple tips that will help improve the security profile of your code, when it comes to databases:
Use PDO or mysqli, and don't use mysql.
Use prepared statements, always.
Never trust user input.
Database connections are not a real worry because:
They are automatically discarded at the end of your script, unless you are using persistent connections.
The database server will not let you hold on to an open connection indefinitely.
There is a limit on the database server on how many open connections are allowed. After this limit is exhausted, the database will refuse new connections with an appropriate message to the client.
Related
I know that PHP automatically closes open MySQL connections at the end of the script, and the only viable way to open a persistent connection is to use the appropriate PHP function; many questions have been asked and answered.
What I would like to know is the benefit - or the inconvenient - of keeping a temporary connection instead of a persistent connection
EDIT :
A persistent connection for each PHP user session.
For instance, statements such as the following:
session_start();
$connection = new mysqli($host, $user, $pass, $db);
$_SESSION['connection'] = $connection;
might set up a reference to a mysqli object useful for performing multiple queries across navigation in the website within the same session by the same user.
If the connection is supposed to be used soon after its activation, would not be the right choice to leave it just open for further queries? Maybe this approach would generate an inconvenient situation (and possible security risks) when multiple users are HTTP-requesting pages from a web site which keeps MySQL connections alive?
I would like to know more. Thank you.
There's overhead to connecting to MySQL or any database, although it isn't typically large. This overhead can be greater when the MySQL service is running on a different server, or depending on the authentication method and init commands needed.
More, MySQL connections may have associated caches. So reusing a connection may be able to reuse these caches.
But saving a resource in the session doesn't work. Session data is serialized, and stored in e.g. a file between requests. That's why the persistent connect methods have to be used.
The reason is that the connection is ultimately a resource, or a socket connection on an internal class, and this can't be "saved" without special handling. Try it, and you'll see that you get an error (with PDO and mysqli.)
mysqli::query(): Couldn't fetch mysqli
I don't think there's any way to get session-specific connection reuse without writing an extension to implement it. Theoretically it's possible, though, and you could theoretically implement a method to pull a connection from the pool by session id.
There are a lot of potential drawbacks and risks to persistent db connections, though:
If your application creates TEMPORARY TABLEs, those tables will still exist on the next run, since it's the same MySQL session.
If you set any variables (SET SESSION or etc.), they will be retained.
Depending on how transactions are handled, it's theoretically possible a persistent connection may have an in-progress transaction.
If the application issues any LOCK commands or uses user-locks, the locks could be held between requests and unknowingly held in new requests.
On a multi-tenant (shared) webserver, the risk of another process somehow obtaining database access it shouldn't have is higher.
This may leave large numbers of connections open for long periods of time, increasing resource usage on the database server.
You still have to expect that the connection might be lost between requests.
When querying the db is it plausible to feel extremely paranoid? I go as far as opening and closing mysql connection every time a new query has to be done. I am afraid that (especially with the ajax enabled pages) this would cause great performance downgrading.
Should I continue in this method or at least open and close connections once in everypage (instead of per-query)? (i'm writing in php btw)
thank you.
Yes, the overhead of connecting every time will be considerable. I suggest you just close it when you're done, it's very unlikely that simply having an open connection without running queries on it will open you to vulnerabilities.
I'd recommend a connection pool if it's possible with PHP. It's a way to simultaneously maximize performance and minimize connection time.
You should not close MySQL connections immediately. It's better to use a single connection for the entire PHP script. PHP will automatically close the connection if you don't explicitly.
Opening a new connection incurs some small time penalty, particularly if MySQL lives on another server on the network. New TCP connections require a three-way handshake, and each TCP connection consumes kernel resources for at least two minutes.
Although PHP doesn't support full-fledged connection pooling, the procedural MySQL API does support persistent connections. See mysql_pconnect() for more details. At my office we use pconnect to avoid crashing the TCP stacks on our high-traffic PHP site.
Consider PHP Data Objects, which can keep a persistent connection for you. You really only connect with credentials once and then cache the connection. Create the connection with something along these lines:
$dbh = new PDO('mysql:host=HOSTNAME;dbname=DBNAME',
'USER', 'PASSWORD',
array(PDO::ATTR_PERSISTENT => true));
For more information, see this page in the php manual.
Can't speak for PHP, but when I write this kind of thing in Apache/Perl I generally do two things to boost performance:
a) allow MySQL handles to stay open as long as the Apache daemon does.
b) keep cached statement handles around (using an LRU cache).
On production servers, some of those MySQL handles have been around for days, serving many thousands of quite complicated SQL queries. It isn't a problem.
When I load a php page on my browser, it connects to the DB and runs some sql... let's say I now follow a link and it takes me to another page within the same website. What happened server wise? Did my first connection to the DB close, and re-opened again? Is that what happens in most cases?
Its very likely that the connection to your database is closed once the page has been processed by PHP, obviously then the result of the PHP is sent to the browser and viewed by the user.
Assuming you're running MySQL the only reason this wouldn't be the case is if the PHP script uses mysql_pconnect, where the connection will be kept open. However its usually good practice not use use this unless the MySQL server and the PHP server have a low bandwidth connection that's unused by other processes.
Yes, in most cases your database connection will close and re-open. In particular if the PHP interpreter is restarted for each page then it has no choice but to do this.
I believe the typical exception (although I've never used this myself) is where you're using something like mod_php.so (for Apache) and you arrange for a DB connection object to be stored as part of the user's session state. I don't believe that's recommended practise, though.
See http://php.net/manual/en/features.persistent-connections.php for more.
That's the usual case yes. But if you're talking about MySQL, you can use mysql_pconnect to keep persistent connections.
It depends on how the PHP was developed. If it was coded to close after each transaction, then yes it will be re-opened each time you view a page.
There is also the concept of a database connection pool. When a connection is used it is not closed but placed into a "pool" of connections waiting to be used again. Once a specified amount of time is passed without the connection being used it is then closed to save resources.
Pooling connections saves on processing time having to reopen a connection on each page reload.
I had never heard of persistent connections before, and I don't understand the advantages.
I run a PHP/MySQL based website, it receives tens of thousands of page views per day. In my header file on each of these pages I have just used mysql_connect() and I haven't bothered with terminating the connection in the footer file.
In my case are there any advantages of using mysql_pconnect()?
Using a persistent connection leaves the connection open after the script has finished executing. Opening and closing connections over and over causes overhead, while small, that will eventually mount up as the number of requests go up.
However, if you read the manual page for mysql_pconnect it states:
If PHP and MySQL are on the same server or local network, the connection time may be negligible, in which case there is no advantage to persistent connections.
If this is the case it may not be worth the trouble changing your code.
You can find more detailed information on persistent connections at the same site as above.
Check out this URL:
http://us3.php.net/manual/en/function.mysql-pconnect.php
Basically mysql_pconnect() tries to find a persistent connection already open with the credentials that you've specified. If it doesn't find one it makes a new one. It also doesn't close the connection after a statement is executed
So really in your case you may not notice a difference but in reality you should probably be using mysql_pconnect().
Are there any tricks to transferring and/or sharing the Resource Links across multiple PHP pages? I do not want the server to continue connecting to the database just to obtain another link to the same user in the same database.
Remember that the link returned from mysql_connect() is automatically closed after the script it originated on completes executing. Is there anyway to close it manually at the end of each session instead?
PHP allows persistent mysql connections, but there are drawbacks. Most importantly, idle apache children end up sitting around, holding idle database connections open. Database connections take up a decent amount of memory, so you really only want them open when they're actually being used.
If your user opens one page every minute, it's far better to have the database connection closed for the 59 seconds out of every minute you're not using it, and re-open it when needed, than to hold it open continually.
Instead, you should probably look into connection pooling.
One of the advantages of Mysql over other heavier-weight database servers is that connections are cheap and quick to setup.
If you are concerned about large numbers of connections to retrieve the save information, you may like to look at such things as caching of information instead, or as well as getting the information from disk. As usual, profiling of the number, and type of calls to SQL that are being made, will tell you are great deal more than anyone here guessing at what you should really be doing next.