Page 1 of 1

2 Ways to defend truncation attacks ,which one?

Posted: Mon Sep 29, 2008 12:14 pm
by kaisellgren
Hi,

I am going to defend against truncation attacks. From what I can think of, there are two solution to do it.

A) Truncate all data by yourself.
B) Check the length of given strings before using it in SQL queries.

Which one do you think is better?

Example A:

Code: Select all

$name = truncate($_GET['name'],255); // Assuming length max 255
$db -> query(...$name...);
Yes I know its not sql injection and other attack safe, but I am only talking about truncation attacks.

Example B:

Code: Select all

 
$name = $_GET['name'];
if (strlen($name) > 255)
 die('Too long');
else
 $db -> query(...$name...);
My thoughs: It's far more user friendly to not truncate by yourself, since if user wants to enter certain detail, why would he want it to be cut to certain length? An error showing that it's too long is far better IMO. If it's a user agent field, or something he can not modify (well he can but in terms of normal usage) -> then truncate.

What are your thoughts on this?

Re: 2 Ways to defend truncation attacks ,which one?

Posted: Tue Sep 30, 2008 3:04 am
by Mordred
Both. The first is syntax-level of protection and belongs to the database layer, while the second is validation, it belongs to the busyness logic.
(Don't use die())

Re: 2 Ways to defend truncation attacks ,which one?

Posted: Tue Sep 30, 2008 8:23 am
by kaisellgren
Mordred wrote:Both. The first is syntax-level of protection and belongs to the database layer, while the second is validation, it belongs to the busyness logic.
(Don't use die())
Heh, as you might or might not have noticed, it was an example so no dies are being used of course :)

So, ah, I haven't figured out yet how I would implement automatic truncation to my DBAL. Do you got any examples or "precode" on this? The problem is that how would the DBAL now the column length? It can be 10 bytes, 255 bytes or 12^16 bytes (eg mysql's TEXT). So, I would basically parse the SQL, get the column -> query the length of it and then truncate it :p - doens't sound too efficient in terms of PHP performance :p

Re: 2 Ways to defend truncation attacks ,which one?

Posted: Tue Sep 30, 2008 8:39 am
by Mordred
My database layer knows many things about the fields.
It is also possible to just hardcode the max lengths, but it will be a mess if you change the db structure often.

Re: 2 Ways to defend truncation attacks ,which one?

Posted: Tue Sep 30, 2008 12:49 pm
by kaisellgren
Mordred wrote:My database layer knows many things about the fields.
It is also possible to just hardcode the max lengths, but it will be a mess if you change the db structure often.
In my project that I am working on, it has a DBAL that currently works perfectly with SQL Server, Oracle, MaxDB, DB2 (IBM), MySQL (MySQLi supported), PostgreSQL, Firebird and SQLite. The only major DBMS I am missing is Sybase, because as far as I can see they are only offering paid database solutions so I am not able to develop it for my project. My project allows custom modules, and my project has its own SQL syntax called TriSQL which is SQL standard Except that it adds lots of extra syntax which most used is probably CREATE TABLE BUT DROP FIRST IF EXISTS.

So, keep tracking of column max values (or min) is impossible or am I missing something here? There are hundreds of modules creating and modifying the database and there's not much I can do about it (the truncation on DBAL -level).

So I guess my only choice is to either A) Truncate all data manually B) Leave the truncation for SQL server and check the limit and disallow further processing if limit exceeds some point.

If anyone got any other idea around this I would be happy to hear about it. =/

Re: 2 Ways to defend truncation attacks ,which one?

Posted: Wed Oct 01, 2008 3:10 am
by Mordred
I didn't mean the abstraction layer, rather the data access layer. If you have SQL queries all over the source, it's a terrible design smell.

Re: 2 Ways to defend truncation attacks ,which one?

Posted: Wed Oct 01, 2008 6:23 am
by kaisellgren
Mordred wrote:I didn't mean the abstraction layer, rather the data access layer. If you have SQL queries all over the source, it's a terrible design smell.
Sorry, not familiar with English terms, do you mean

Code: Select all

function insert_message($message,$name)
 {
  $name = // Truncate, escape, other possible necessary
  $message = // Same for message
  $sql = "INSERT INTO messages (message,name) VALUES (?,?);";
  $this -> prepare($sql,array($message,$name));
  $this -> exec();
 }
The problem is that my users will develop plugins for my application, and they are not using data access layers. What they are doing, is that they write an SQL clause and put it in the query.

Re: 2 Ways to defend truncation attacks ,which one?

Posted: Wed Oct 01, 2008 6:54 am
by Mordred
http://en.wikipedia.org/wiki/Database_abstraction_layer
http://en.wikipedia.org/wiki/Data_access_layer
"Design smell" is a polite way to tell someone that their code sucks :)

Since you leave to your users to write and execute their SQL, you can't control how securely they do so, so your next best option is to provide tools for easy handling of data.
Try something like $name = Truncate($name, 255) or whatever you fancy.

Btw, doesn't your prepared statements code handle escaping? If so, the comment // Truncate, escape, other possible necessary is wrong, it shouldn't handle escaping.

Re: 2 Ways to defend truncation attacks ,which one?

Posted: Wed Oct 01, 2008 7:20 am
by kaisellgren
Mordred wrote:http://en.wikipedia.org/wiki/Database_abstraction_layer
http://en.wikipedia.org/wiki/Data_access_layer
"Design smell" is a polite way to tell someone that their code sucks :)

Since you leave to your users to write and execute their SQL, you can't control how securely they do so, so your next best option is to provide tools for easy handling of data.
Try something like $name = Truncate($name, 255) or whatever you fancy.

Btw, doesn't your prepared statements code handle escaping? If so, the comment // Truncate, escape, other possible necessary is wrong, it shouldn't handle escaping.
Yea it handles escaping, I shouldn't have typed that in to the comments :)

And uh, yeah I have a truncation function

Code: Select all

$name = truncate($name,255);
I was just hoping that I could make it more "automatic" for my project plugin developers.

EDIT: I actually have a scanner that checks the plugin that is being installed on my script and warns the user if he is installing a plugin with possible security holes (in case the plugin is not white listed on my website ;) ).