[kwlug-disc] Security arguments

Chris Frey cdfrey at foursquare.net
Wed Sep 23 13:01:05 EDT 2009


On Wed, Sep 23, 2009 at 10:13:51AM -0400, Khalid Baheyeldin wrote:
> On Tue, Sep 22, 2009 at 6:42 PM, Chris Frey <cdfrey at foursquare.net> wrote:
> > Make programming badly hard.
> >
> 
> I don't think that this should be a goal, not is it effective. Making it
> very hard, will make it very expensive too because the pool of qualified
> developers will be less.
> 
> I think that education is the key here to mitigate all this, not making
> programming hard. Another route is open source, were a pool of people look
> at the product, not just one or two people who may be not very qualified.

Slightly rephrased for clarity:  Make bad programming hard.
Good programming shouldn't be hard, but it is often harder than bad
programming.

I'll craft an example from my language of choice, C++.

Here are two silly classes that do the same thing, but the API is crafted
differently to make bad programming hard in one, and easy in the other.

//
// Bad programming easy
//
class Output {
public:
	char *str;
	Output() {}
	void Print() { cout << str << endl; }
};

// Usage:
Output out;
out.str = "hello";		// there's no help from compiler to eliminate
out.Print();			// initialization mistakes



//
// Bad programming hard
//
class Output {
	const char *str;
public:
	Output(const char *str) : str(str) {}
	void Print() { cout << str << endl; }
};

// Usage:
Output out("hello");		// only one way to initialize and cleanup
out.Print();			// with this API



I do see instances of the first example, and it makes good programming
hard.  Yes, it is due to lack of education, but library developers can
craft their APIs in such a way to make it hard to use in the wrong way.

Various languages give the library author tools to encourage or even force
safe programming.  Object oriented languages have more such tools,
in my opinion, but with care, pure functions can encourage good programming
too.

Another example: if a class depends on another, you can use language
features to encourage the safest way to initialize:

class One {};
class Two {
public:
	Two(One &o);
};

This forces One to exist before Two, and the constructor taking a reference
encourages the programmer to avoid heap allocation, and lets the programmer
know that null pointers are not allowed here:

// awkward, with risk of memory leaks:
One *po = new One;
Two *pt = new Two(*po);

// easier and safer:
One o;
Two t(o);




> One thing we did in Drupal, is have our own db abstraction layer that
> when used correctly, would escape all SQL queries and prevent SQL injection.
> 
> See here
> http://drupal.org/writing-secure-code
> And here
> http://drupal.org/node/101496
> 
> So users are urged to use the Drupal API, and not the PHP/MySQL API
> to access the database. If they do that, they are protected from themselves.
> 
> That is not fool proof though, they can bypass that layer and go to the PHP
> layer, but with some education, most people eventually use the Drupal API.

Yes, that's the kind of thing I'm talking about, thanks.  For a programmer
who knows SQL but not PHP, mysql_exec() is easier, but "bad".  If that
function didn't exist, then learning the good way would come first.

It would be better if the API above didn't need a warning at the top
of the web page asking users not to concat strings for their SQL, though.

For example, the ODBC API has two ways to access the database.  One is
string based, which is easy to get working, and the other is API based,
using column binding, which is much safer, much faster, and much harder
to use the first time.

ODBC (and PHP too) could be made much safer by removing the simple string
method, and adding exceptions if any data was found in the raw SQL
statements.  This would force users of the API to use the column binding
method, making SQL data access safe.  And since the API is hard to use,
it would likely encourage helper APIs to make column binding easier.

Eventually we'd have the best of both worlds: safe and easy.



> What do we have in common here? The human is the weakest link.
> Whether it is the programmer that introduced SQL injections, or the
> amateur web master who installs insecure software, and never updates
> it, or the guy who clicks the attachment that promises a saucy pictures.
> 
> Computers are tools, and if you use the tool to shoot yourself in the foot,
> then there is no way to protect people from that, other than by getting
> educated on them.

True.  But knowing that humans are the weakest link, we should
be using every tool we have to make those interface and API mistakes
harder to make.

Some of this has been discussed much better than I can present it.
Here's one presentation:

	http://lcsd05.cs.tamu.edu/slides/keynote.pdf

There was another one, more kernel-oriented, that had examples of
APIs from best to worst, but I can't seem to find it anymore.
It was pretty good, so if I find it, I'll post a link.

- Chris





More information about the kwlug-disc mailing list