Its a simple message, but worth repeating.
Yesterday I came across the website of a major internet security firm making a few first-day-on-the-job mistakes. While I am not going to "out" them before contacting them directly, what they did is silly enough that it warrants a bit of discussion in the abstract.
Display_errors was enabled in their web server's php.ini. As a result, a few helpful messages were displayed briefly at the top of several of pages on the site
1. The name of the database
2. The name of the table in use by that page
3. A list of every column in that table
4. An error indicating that the table is exceeding its maximum allowable size of 4GB
The site collects information about its users - IP address, browser info, referrer, etc, and stores that information to a table in a MySQL database - we know from the error itself that database is running on a server using a 32 bit operating system. With the structure of the database, we have everything we need for SQL injection.
That said, there was one additional level of security. The internet security company is masking database queries in URLs - clicking around the site, it became clear that calls to the database are encoded using an encrypted hash. Unfortunately for the internet security company, this technique obscures rather than protects. Because the hashing is not applied consistently across all requests, it actually helps to draw attention to pages that require further scrutiny from an attacker. And of course, since we already have the structure of a database, we can use php's md5 and sha-1 functions to encode our own injection attempts. I will give the internet security company bonus points for not using base64 encoding for the masking - its surprising how often base64 is used for this purpose when it is trivial to decode and under normal circumstances does not provide any performance benefit. If anyone knows of some good reasons to use base64, please shoot me an email or leave a comment.
In summary - I hope this post helps to illustrate how displaying error information, a very common mistake, can lead to the compromise of an otherwise secure site. I left out a lot of information as it was not my intention to create a "how to" guide on SQL injection. That said I hope I found a good balance between providing a practical example without encouraging nasty behavior. Always remember to disable remote error reporting and debugging features on production servers. When debugging is needed, enable it just long enough to resolve the issue and then turn it back off. Do not attempt to use verbosity settings as a way of securely displaying error information - it only takes one poorly worded error message to compromise a site.
Yesterday I came across the website of a major internet security firm making a few first-day-on-the-job mistakes. While I am not going to "out" them before contacting them directly, what they did is silly enough that it warrants a bit of discussion in the abstract.
Display_errors was enabled in their web server's php.ini. As a result, a few helpful messages were displayed briefly at the top of several of pages on the site
1. The name of the database
2. The name of the table in use by that page
3. A list of every column in that table
4. An error indicating that the table is exceeding its maximum allowable size of 4GB
The site collects information about its users - IP address, browser info, referrer, etc, and stores that information to a table in a MySQL database - we know from the error itself that database is running on a server using a 32 bit operating system. With the structure of the database, we have everything we need for SQL injection.
That said, there was one additional level of security. The internet security company is masking database queries in URLs - clicking around the site, it became clear that calls to the database are encoded using an encrypted hash. Unfortunately for the internet security company, this technique obscures rather than protects. Because the hashing is not applied consistently across all requests, it actually helps to draw attention to pages that require further scrutiny from an attacker. And of course, since we already have the structure of a database, we can use php's md5 and sha-1 functions to encode our own injection attempts. I will give the internet security company bonus points for not using base64 encoding for the masking - its surprising how often base64 is used for this purpose when it is trivial to decode and under normal circumstances does not provide any performance benefit. If anyone knows of some good reasons to use base64, please shoot me an email or leave a comment.
In summary - I hope this post helps to illustrate how displaying error information, a very common mistake, can lead to the compromise of an otherwise secure site. I left out a lot of information as it was not my intention to create a "how to" guide on SQL injection. That said I hope I found a good balance between providing a practical example without encouraging nasty behavior. Always remember to disable remote error reporting and debugging features on production servers. When debugging is needed, enable it just long enough to resolve the issue and then turn it back off. Do not attempt to use verbosity settings as a way of securely displaying error information - it only takes one poorly worded error message to compromise a site.