The Most Dangerous Programming Mistakes
snydeq writes "Fatal Exception's Neil McAllister discusses the most dangerous programming mistakes, and what can be done to avoid them. 'Even more than input validation errors, this year's list is rife with application security blunders of all kinds. Some of them sound fairly esoteric, such as "inclusion of functionality from untrusted control sphere." But of all such errors, the highest-ranking one on the list is "missing authentication for critical function" — in other words, the attacker was able to gain access because there was no lock on the door to begin with,' McAllister writes. 'With the pace of Internet attacks accelerating, now is not the time to cut QA staff or skimp on testing and code review.'"
If you'd like to read what the mistakes *are*, instead of a fluff piece that amounts to "oh, they're so awful! And people make them all the time, too!", here's the actual original article: http://cwe.mitre.org/top25/index.html
Is one of the mistakes "Not being able to click on a link"? I would check myself, but I can't click on the link.
...Those are system design mistakes.
A programming mistake is one where you meant to type x+1 and instead you write x-1. Missing something like authentication or checking is a requirements or design problem, not a programming problem.
If software was a car, you wouldn't say it's a manufacturing problem if the car didn't have a place to install a lock - you'd say it's a design problem. It would only be a "programming" issue if it had a place for a lock but it was left uninstalled.
(Yes, I don't consider "programming" to include the design aspects; I consider "programming" to mean "conversion of requirements into computer code." The errors about which this article talks are mostly requirements problems, not implementation problems.
"There are a dozen opinions on a matter until you know the truth. Then there is only one." - CS Lewis (paraprhase)
"Java and C# are better than PHP" wrapped in buzzwords and it mentions "SQL Injection attacks" (yawn).
The whole thing is insulting to read for everyone more competent than management. As usual.
0/10
it's-probably-fine,-we'll-test-it-live
Could describe every "upgrade" to slashdot that has happened since ... well probably ever.
Damn_registrars has no butt-hole. Damn_registrars has no use for a butt-hole.
Switch back to the Classic Discussion System.
Dear Web Developers,
Stop using toy languages. A strongly typed language that only accepts type "SanitizedString" as an SQL function parameter will end this problem forever.
No sig today...
Where possible, avoid implementing custom authentication routines and consider using authentication capabilities as provided by the surrounding framework, operating system, or environment.
This can prove cost prohibitive when the authentication capabilities provided by the surrounding operating system are marketed for use only by privileged employees, not by the public. Consider the case of an operating system that charges per user account. (Microsoft calls this the "client access license" model.) One might be tempted to use or create an authentication and authorization library that runs independently of the operating system's own auth facility, so that one needs to buy a system user account for only the web server, not for each member of the public who creates a user account on the web site.
For outbound authentication: store passwords, keys, and other credentials outside of the code in a strongly-protected, encrypted configuration file or database that is protected from access by all outsiders
Say I encrypt the keys that a web server uses to communicate with other web services, such as the key used to communicate with a payment processor. Now how do I store the key to decrypt those keys?
For inbound authentication: Rather than hard-code a default username and password, key, or other authentication credentials for first time logins, utilize a "first login" mode that requires the user to enter a unique strong password or key.
So how do we prevent an attacker from attacking a system while it is still in "first login" mode?
Clearly specify which data or resources are valuable enough that they should be protected by encryption.
Firesheep shows that this includes users' passwords and cookies containing authenticated session tokens. But with StartSSL having suspended operations and Internet Explorer on Windows XP still not supporting Server Name Indication, how can hobbyist web developers get the certificate and dedicated IPv4 address needed to host an SSL site?
If possible, create isolated accounts with limited privileges that are only used for a single task.
Please see my comment above about the CAL pricing model.
Generate a unique nonce for each form, place the nonce into the form, and verify the nonce upon receipt of the form.
If you've ever seen errors about a "form key" on Slashdot, Slashdot is doing exactly this.
Do not use the GET method for any request that triggers a state change.
Is a hit counter a state change?
Use a built-in path canonicalization function (such as realpath() in C)
According to this page: "The realpath() function is not described in the C Standard." It's available only in UNIX, not in Windows.
Avoid inconsistent messaging that might accidentally tip off an attacker about internal state, such as whether a username is valid or not.
Does this mean don't bounce messages to nonexistent users but instead treat them as delivered and discard them? That would provide a bad user experience for people attempting to contact these users.
Use code signing technologies such as Authenticode.
How does a hobbyist afford the certificate for Authenticode?
For all configuration files, executables, and libraries, make sure that they are only readable and writable by the software's administrator.
Writable I agree with, but readable I'm not so sure. If configuration files are readable only by the adm
Using a system where the program has to be trusted to do its job correctly is the bigger mistake. When you hand your car keys to a valet, you don't also give him power of attorney to sell your house, liquidate your stocks, savings, etc... but every operating system out there does something like that when you tell it to run a program. The program you run can do anything you are authorized to do. The default assumption is that it should have permission to do anything, no matter how stupid, dangerous, or downright evil.
This practice needs to end, about 10 years ago it should have ended... and we'll probably have to wait 10 more years because it's so freaking hard to get this idea across, nobody seems to be ready for it yet, by the way things seem to be going.
A user should be able to decide exactly which and how much of the resources they are authorized to use will be allowed to be accessed by a program they choose to run. If you want to run a program with read/write access to /sandbox, and the ability to read from the internet using a filtered http driver (one that doesn't allow puts, for example), you should be able to do so, without having to do any fancy footwork.
If put in to place, this type of system, which explicitly states what access things get, make it almost trivial to never get a virus or worm ever again. It's time to stop trusting programs, and only have to trust the hardware and OS to enforce our wishes.
I impatiently await the arrival of capability based security.
Bull. 2 out of those three examples make it easy to do the right thing.
Perl has DBI, which does parametrised queries very well, and in fact makes quoting a pain, because all the nice functions like binding variables to query results do not work well (if at all) with quoted queries. And if DBI is too low-level, there is always the DBIx::Class ORM.
Python's DB-API 2.0 is the standard to do databases in Python, and it too makes parametrised queries a lot simpler than quoting. And on top of that you can use SQLAlchemy.
I agree with PHP being bad. Sure it has parametrised query support in various libraries, but the default is still to use MySQL as backend and use the various mysql_yes_really_quote_it_correctly_this_time() functions. Given that until recently even the maintainers of the language didn't have clue as to how to do security right, PHP is by far the most unsuitable language to do secure web programming in.
Mart
"I know I will be modded down for this": where's the option '-1, Asking for it'?
In Perl this is easy. Let's say that @args holds your argument list. Then it goes like this:
my $query = "select * from table where column in (";
# Use $#args to get the index value of the last member of the array @args. This gives us a loop that's one iteration shorter than the lenght of the argument list.
for (1..$#args) { $query .= ' ?, '}
$query .= '? )';
my $sth = $dbh->prepare($query);
$sth->execute(@args);
# Bind result columns with $sth->bind_col
while ($sth->fetch) {
# Do something with the results.
}
Mart
"I know I will be modded down for this": where's the option '-1, Asking for it'?