Usually, I use PDO's prepared statements, type casting to (int), or PDO::quote() to prevent SQL injection. For this application, I need to modify the date using PHP before adding it to the query. Do I need to take extra steps to prevent SQL injection, or am I safe? Thanks

Assuming the DateTime constructor doesn't have a security hole I'd say you are fine.
–
lc.Jan 22 '13 at 16:13

@lc. Would you still do a redundant PDO::quote()?
–
user1032531Jan 22 '13 at 16:14

Note that new DateTime($someUserValue) might throw an exception as of PHP 5.3. // Edit: A call to PDO::quote() would not be redundant as DateTime doesn't to anything to make your value query-safe. However, the value just doesn't contain any malicious content.
–
Daniel MJan 22 '13 at 16:14

1

I'd honestly use a prepared statement and a parameter like everything else, but maybe it's just me. It shouldn't make a difference though in this particular case. Once it's a DateTime object you shouldn't get anything funny out of it save an exception if the user data is strange.
–
lc.Jan 22 '13 at 16:14

6 Answers
6

It doesn't matter if the DateTime object is safe or not. You should escape the data you are passing to the query and not to rely on the safety of the provided library. If you change the implementation, you will not need to care if the new implementation is safe or not. You should always escape. Otherwise you will try to answer - and to remember - for each function - was it safe for SQL? for HTML? for CSV? for http / mail headers? for... don't! The line of code that send a query should know nothing about the DateTime implementation and if it's safe or not

It's a good question: is the PHP date formatter safe from SQL injection?

I guess the starting point is whether the format is hard coded as per your example. The date format string allows raw characters to be included in the formatted date, which could include unsafe characters, so if you're using a variable for the format string then the answer is definitely No, it isn't safe.

If you are using a hard coded format, as in the example you've given, then it's a more difficult question, but it boils down to "Can the the output of DateTime::format ever deviate from the desired format?"

The answer to this is Yes it can -- it can output false if it fails. This won't break your SQL, but could give you unexpected results.

In theory, that should be as bad as it gets.

However, you should be thinking defensively. There's nothing to say that a subtle bug won't be found in the DateTime class that causes it to output a badly formatted date. Ordinarily, this kind of bug wouldn't be considered a security issue; it would just be an annoyance. Particularly if it's difficult to reproduce in normal use. But combined with passing it directly to SQL, it could easily be a security problem.

The lesson is Defensive Programming: Sanitise everything. Even if you are sure it's safe. Don't assume that your language or frameword doesn't contain bugs. Defensive programming means being secure at every level, so that an unexpected bug further up the program or outside of your control can't leave your code open to attack.

The DateTime constructor will parse the argument and try to make it a date.

If it can't it returns false (actually throws an exception as of PHP 5.3).

Meaning you are safe since SQL injection attempts to "trick" the SQL query string with quotes for instance, while new DateTime returns either a DateTime instance or false (throws exception).But you could anyway process the error case (from PHP 5.3)

I feel bad. Your response was the only one to answer the question. Yes DateTime will prevent SQL Injection. Darhazer's answer didn't directly answer the question, but appropriately (in my opinion) tells you not to trust it.
–
user1032531Jan 22 '13 at 16:28

Don't feel bad. Just accept the answer you feel fits the better your question and will help other readers.
–
ring0Jan 22 '13 at 16:32

Yes, I did. Yours was the best direct answer, but I felt the others would better help future readers. Thank you for your help!
–
user1032531Jan 22 '13 at 16:33

Thanks Hek2mgl. +1 for the detailed example. I understand, however, how to use prepared statements. My complication results from having multiple parts of the query which are sometimes shared between other queries, come from different parts of the application, and are later assembled and executed.
–
user1032531Jan 22 '13 at 16:22

Hmm sounds like a bit wired design. Note that dynamic SQL generation - beside from being potentially vulnerable - can lead to bad code and debugging nightmares
–
hek2mglJan 22 '13 at 16:24

Don't I know it. My head hurts from trying to get it right!
–
user1032531Jan 22 '13 at 16:26

Depending on the output format of the date. If you were to change the format and put it to output some text (like the month or day name in the current locale), it may lead to unsafe (or at least failing) queries because it may have some quotes. Or you could put quotes yourself for some reason. So yes, do not doubt and use pdo->quote() or better yet, prepared statements.