Best security questions in June 2011

How to overcome this security issue

22 votes

I have implemented an ajax-polling script that calls an action in the server Controller every 10 seconds. With the response, I replace the content of a div:

function getFoo() {
    var link = '/Secure/GetFoo';

    $.post(link, function (response) {
        $('#FooSection').replaceWith(response);
    });

    setTimeout("getFoo();", 10000);
}

This is done through https. After some time of being "idle", IE displays the following message:

This page is accessing information that is not under its control. This poses a security risk. Do you want to continue?

If the user clicks Yes, the page is redirected to the div displaying the response only. If the user clicks No, nothing happens, but the div container will not be refreshed.

I know I can suppress this message through browser settings, but that will just bring me to a default Yes selection as per the above dialog.

A similar issue has been asked before, but unfortunately there hasn't been any solution. I basically want to make my ajax-polling work even on a secure connection. Any ideas?

You should never see that dialog on an Internet-Zone page. By default, this operation is silently and automatically blocked in the Internet Zone.

There are two root causes for that dialog to appear in the Intranet zone:

1> Attempting to do a cross-origin request using the XMLHTTPRequest object (http://blogs.msdn.com/b/ieinternals/archive/2011/04/22/ie-security-prompt-page-accessing-cross-domain-information-not-under-its-control.aspx)

2> Attempting to navigate an OBJECT Tag hosting HTML to a cross origin page.

You can avoid case #1 by using XDomainRequest instead of XMLHTTPRequest. You can avoid case #2 by using an IFRAME instead of an OBJECT tag.

Why does PDO print my password when the connection fails?

8 votes

I have a simple website where I establish a connection to a Mysql server using PDO.

$dbh  =  new PDO('mysql:host=localhost;dbname=DB;port=3306', 'USER', 
'SECRET',array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));

I had some traffic on my site and the servers connection limit was reached, and the website throw this error, with my PLAIN password in it!

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[08004] [1040] Too many connections' in /home/premiumize-me/html/index.php:64 Stack trace: #0 /home/premiumize-me/html/index.php(64): PDO->__construct('mysql:host=loca...', 'USER', 'SECRET', Array) #1 {main} thrown in /home/premiumize-me/html/index.php on line 64

Ironically I switched to PDO for security reasons, this really shocked me.

Because this exact error is something you can provoke very easily on most sites using simple http flooding.

I now wrapped my conenction into a try/catch clause, but still. I think this is catastrophic!

So I am new to PDO and my questino is: What do I have to consider to be safe! How to I establish a connection in a secure way? Are there other known security holes like this one that I have to be aware of?

You should have display_errors = off in your PHP.ini anyway to avoid this problem. Errors that reveal details like these come from many places, in addition to PDO.

Yes, you should also have it in a try/catch block.

You can also $pdo->setAttribute(PDO::ERRMODE_SILENT), but then you need to be checking the error codes manually rather than using a try/catch block. See http://php.net/manual/en/pdo.setattribute.php for more error constants.

How dangerous is it to provide a means for the public to run SELECT queries on a database?

5 votes

Suppose I do the following:

  • I create a MySQL database, and populate it with some data.
  • I create a MySQL user who has access only to that database, and who only has SELECT privileges.
  • I create a web page through which a user (any user, no password required) can enter arbitrary SQL, and on submitting the form, a script attempts to run the SQL as the MySQL user I created; any result set generated is displayed to the user; any error message generated is displayed to the user.
  • Assume that the database contains no stored procedures etc, just tables and views, and that I am happy for anybody to see any of the contents of that specific database.

We assume that the setup will be probed by a malicious user. What is the worst that could happen?

Some thoughts:

  • MySQL provides various statements like SHOW etc. that a user even having only SELECT privileges could use to gather information about the database server or about my databases. Other information could be obtained from error messages. While probably not sufficient to gain improper access, this information could surely help in doing so.
  • There might be flaws in the database software, or in my scripts, or in the scripting language itself, that could allow a visitor to do things they are not supposed to be able to do through this interface.
  • Doing this might violate a terms of service agreement, particularly if I am using shared hosting.

Hmmm. Clever users may attack via syntax like:

select some_function_that_updates() from some_table;

And there's a denial of service attack that could blow memory, like:

select * from some_massive_table cross join some_other_massive_table;

And frankly, it's hard enough for experienced programmers to write queries that behave well... what chance does a poor user have even if they try to write a good query