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
Hopefully the increased use of frameworks that write sql will decrease that problem
Never antropomorphize computers, they do not like that
That was a pure greed, a Wall Street/Main Street feeding frenzy that would seize on the flimsiest evidence to justify the conclusion that the boom would continue indefinitely, enriching those with the foresight to seize the day. Coupled with willful lack of regulation and oversight from Washington and New York.
Newsflash!
...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)
QA has always been considered the bastard children of software development. I've never worked on a project where they weren't treated like shit. I'm guilty too; which is really bad because I started out in QA/QC.
And on the business side, stop this horseshit of releasing code and having the customer find the bugs. Of course that won't happen. Some dipshit mgr is thinking, "Why have QA when the customers will find the bugs. We'll fix the first few and the charge them for a new and better release!" Now, this is the one time when blaming/bashing Microsoft is proper. They are the ones who made it the industry norm.
Only little people are capable of error, so it must have been a programming mistake.
Virtual destructor on base class.
"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
This data type/structure is big enough; why would I need more to store larger values than I can anticipate right now? Keeping It Simple Stupid saves some bytes, too. Why would we ever need to store a four-digit year, anyway? What could possibly go wrong?
Why not go to a good source from actual devs?
If an exploding ball of fire isn't dangerous, what is?
More Testers / QA is needed and stop the overtime working 80+ hour weeks just leads to more errors and bugs.
Also don't get me started on rush jobs that just become try to work around the bugs and not take the time to fix them.
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.
The Therac-25 had some "Dangerous Programming Mistakes".
I wonder if the nudie scanners have any similar mistakes.
Y3K will never happen.
Is this because programmers learned from Y2K and changed their ways? Well, not exactly. Before 2000, most programming languages did not have a built-in date type, so programmers had to make their own, using either numeric or text fields. They didn't want to write ALL the code necessary to do ALL kinds of date calculations, so they just wrote the ones they needed, and these often ignored the first two digits of the year.
NOW programmers in nearly every language have handy date variables they can use, that perform date arithmetic easily and reliably. Programmers naturally use these date variables, because it makes their lives easier.
Today, it is difficult to incorporate good security practices into software. This is because we largely have to roll our own. We therefore write just enough code to do what we think we need, and we don't consider all the possible ways security can be breached. ONLY when the tools improve to the point that security comes automatically, will software, as a rule, be secure.
tl;dr (yet)
But I do have something to say about the immediate response of "QA". These are design issues (as has been mentioned). QA is not where you test out that sort of thing. Up-front design (not necessarily Big) should be the first response. Now is not the time to slack off on design, just because a lot of the components have already been written.
To work around Slashdot's brokenness, did you try double right-click, then open in new tab? It appears to work for me in Firefox 5.
Of course mistakes are made when the tools are inadequate. For example, using SQL in a program by formatting a command and asking SQL to understand it. That is just crazy. Instead there should be a proper API which clearly tells SQL what is wanted. Then there would be no possibility of SQL injection.
So you're saying programmers are lazy fucks who don't consider the consequences of their actions, and can't be trusted to figure out anything for themselves. Or that's how it reads, any way. I'd like to disagree with that.
Your scope isn't nearly broad enough. Change programmers to "95% of people" and you've got it about right.
Canada: The US's more awesome sibling.
No, I'm not saying programmers are lazy. It's just that there is always tension between getting a job done, and getting EVERY detail right.
They ALSO are not always as knowledgeable as they should be. How many programmers know that in 1752, when the Julian calendar was replaced by the Gregorian calendar, September 2 was followed by September 14? How many programmers care? Why should they? Yet this arcane bit of knowledge could make a difference in some software that deals with antiquities.
Just as there are arcane bits of knowledge needed to make perfectly precise date calculations, the same is true of security considerations. Programmers should HAVE TO KNOW every possible arcane exploit in order to write good code. They framework/language should take care of this.
pretty much all frameworks today have an easy and built in way to prevent sql injection.
True, parameterized queries work in most cases. But I've found a few places where they're not ideal, and I wrote a bit of framework to implement other ways to pass strings to SQL safely.
A lot of SQL APIs don't support parameterizing a query that includes a table-valued parameter, such as the anonymous single-column table on the right side of an IN expression (e.g. username IN ('bluebear', 'chief', 'filbert')). So I wrote and tested a function mysqli_escape_list($connection, $array) to escape each item in an array and then format it as such a table expression, and then I use this function every time I need a variable number of literals on the right side of IN or VALUES. A web site called bobby-tables.com strongly recommends against this method, instead preferring code that constructs a string of question marks, a string of types, and an array of reference variables in parallel and then calling $stmt->bind_param() through call_user_func_array(). This appears hairier than the method that I use.
A lot of database search user interfaces are based on the general concept of query by example: present a form representing a blank record to the user, then find records whose values match the fields that the user specified and ignore fields that the user left blank. There are two ways to implement this search in SQL. One is to include two separate parameters in the query for each field (e.g. "name", "ignore name", "town", "ignore town"). The other is to generate a WHERE expression and make sure to escape it properly. The first way is good when all fields are known up front; the second way is probably needed when the list of fields will expand in the future.
The Mitre list does include "Use of a Broken or Risky Cryptographic Algorithm" but in my experience that's far less common than improper use of a perfectly good algorithm. Many algorithms and modes have known weaknesses that require specific generation/handling of keys and initialization vectors to maintain good security. Most algorithms and modes that are secure against unauthorized *reading* of data still require an extra MAC step to prevent unauthorized *modification* of that data (including targeted bit-flips). Developers often take shortcuts in these areas because doing all of "the right things" adds a lot of extra complexity and can absolutely kill performance. Look at recent events involving Dropbox and Jungledisk for examples. I don't think the Mitre list adequately conveys that cryptographic security requires not just good low-level algorithms like AES or Blowfish but also good higher-level (usually domain-specific) algorithms governing how the low-level algorithms and their inputs are used.
Slashdot - News for Herds. Stuff that Splatters.
The sort of developers who continue to make this mistake will make it even in that language -- how do you generate a SanitizedString?
The correct response is to make it easy to do right. A good ORM in pretty much any language should help with this -- there's plenty of support for parameterized SQL in Rails, but you can (and should) avoid even that problem entirely by not writing any SQL at all.
Strong typing might help, but even there, the solution is the same -- syntactic sugar on the Right Thing, syntactic vinegar on the Wrong Thing, and focus on making it easy to do right, rather than hard to do wrong, since people will find a way to do it wrong anyway.
Don't thank God, thank a doctor!
While TFS and TFA call them "programming" mistakes, the actual source refers to them as the "Top 25 Most Dangerous Software Errors".
No, that's a typographical error, not a programming mistake.
A programming mistake is when you incorrectly analyze the requirements and think you need to type x-1 to correctly implement them when in fact you need to type x+1.
But either one results in a "software error"; the list and the original source are fine, the fluff piece in between the original source and Slashdot (and, consequently, the Slashdot summary) is the only potential problem here.
While its fun to construct ways to point the finger somewhere else in an organization, or to pedantically categorize errors in to narrow boxes, what I'd say is that its a failure of each and every person who had sufficient contact with the product that they should have seen the relevant facts, and sufficient technical skill that they should have recognized the error, and who either did not recognize the error or who did recognize the error but did not take action to have it corrected [whether that was implementing a fix or providing notice up the line]. Plus all the people responsible for the process that produced the error.
And most of the errors on the list are things that, whether or not they should be explicitly foreseen in requirements, programmers are positioned to recognize and ought to be taking steps to prevent. Programming isn't narrowly constrained assembly-line work, at least in any organization that expects to produce quality software.
Not a shocker. I've heard time and time again from NoSQL fans that it's ok to put your database on the public internet over HTTP with no locks. In fact, early versions of CouchDB didn't have security.
Another problem is that many novice programmers forget to secure their AJAX endpoints.. when you have 20 calls happening all over returning json, you often forget to check session or ensure authentication + authorization.
During my computer science courses, very few times did security come up. I had one professor who cared enough to discuss input validation, authentication, etc. It's this magic thing that we'll just figure out right?
MidnightBSD: The BSD for Everyone
These days, someone writes the program specs and hands same to a programmer, who (rightfully) assumes that the spec writer knows what he is doing.
One certainly cannot fault the programmer for faulty specs. One can and should fault management for the problems of faulty specs. Of course, most IT
management I ever encountered was incompetent (to say the least), and some of it was downright criminally stupid.
Here is the the actual list.
CWE is about "weaknesses", i.e. security. Does anyone know of a similar group or research into classifying and ranking common software errors? For example:
- dereferencing null pointers
- memory leaks
- stack corruption via buffer overflow
- out-by-one errors
- errors in error handling code that is infrequently run
- deadlock/resource contention
- faults characteristic of concurrency
- use of globals and code with side-effects
etc. All the stuff you learnt about at university, and then went on to rediscover in your job.
I've always thought that anyone designing a new programming language should have a big list of these and consider in each case what the language/compiler/library provides to mitigate/avoid these (garbage collection, static analysis, etc).
Anyway - anyone know of such a list/research?
Only little people are capable of error
Mitigation: Quit buying Fisher-Price toys.
Mitigation 2: Don't hire people of short stature. Not advisable due to disability discrimination laws targeted at conditions such as heightism.
Had a friend who worked in the Mailing industry who liked to clean his own mailing lists (Rather than letting the experts in IT do it) in Access & Excel on one occasion accidentally sent 30,000 letters to the same man. As my friend put it "It was all right though because he was German!". Though the mailing house is now defunct and my friend now rides a motor bike it is somewhat reasuring to know that he is still a pratt!!!
You never have an excuse not to use parameterized queries.
Other than that one is trying to save money by not using a Windows server.
where (columnA is not null or columnA = :columnA and (columnB is not null or columnB = :columnB)
What is this :columnB syntax? MySQLi allows only a question mark as a placeholder. Did you mean "switch from MySQLi to something else"?
using the RDMS's data dictionary to get the column names.
For privacy and load reasons, we allow the public to search only on some columns and not others. So we'd store the column names in an ACL instead of the INFORMATION_SCHEMA. Is that OK?
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.
Another option is to generatea parameterized where clause.
If I generate parameterized SQL, how will I know the type and number of ?s in advance in order to do $stmt->bind_param('iss', $var1, $var2, $var3)? And if you say I should build three things (the statement, type string, and list of variables passed by reference) in parallel and then use call_user_func_array(), a mistake in keeping all three of those in the same order is no less likely than a mistake in $conn->escape_string($value). Or did you mean "switch from MySQLi to something else"?
The existence of things like mysql_real_escape_string vs mysql_escape_string in php shows how this sort of thing can be fucked up.
I understand that the reason for existence of the _real_ functions is that the correct escape varies based on the current SQL mode. This is why I always use the connection's escape method $conn->escape_string($value).
Cheat the moderation system - here's how they downmod others unjustly to troll and harass them, in detail.
This is where countertrolling explains what he's doing while he trolls others (to his fellow trolltalk.com friends):
http://slashdot.org/comments.pl?sid=2245866&cid=36491652
And, here's where countertrolling's "troll mechanics" for downmodding others is explained in detail by someone that got sick of it happening:
http://slashdot.org/comments.pl?sid=2271908&cid=36579618
As far as bogus up moderations, the trolltalk.com bunch (tomhudson, countertrolling, & others) collectively "team up" to upmod one another, in teams, as favors to one another.
(Talk about low, and bogus!)
---
In fact, here's what he says about it, why he does it, and to all of us here:
"What the skiddies here don't understand is that I don't give a shit about dumbass 'karma' on the internet.. I'm here for the jollies with nothing to lose or fight for.. watching them destroy their world.. They can go absolutely nuts as far as I'm concerned.. It's nothing but pure entertainment (and data points) for me and mine... Tragicomedy is probably the best word I can think of to describe it" - by countertrolling (1585477) on Thursday June 30, @10:26AM (#36622502) Journal
QUOTED VERBATIM FROM -> http://slashdot.org/comments.pl?sid=2281808&cid=36622502
Sounds like a sick individual to me.
I recently had a chat with a developer who decided his opinion on security was better than everyone else's. "It's media making a big deal out of nothing."
Developers, like all people, make up their minds first and look at reality only when they it bites them in the ***.
This won't get better until the enterprise forces them to follow good practices.
You just illistrated that you are too young to understand the Y2K issue. The issue was not the lack of date types or lazy programmers. The issue was storage and cost. Dropping 2 bytes over 10 million records, saved roughly 40 MB (that's meg) at a time when a 10 MB pc hard drive cost more than your laptop does now. Now take those 2 bytes for the DOB, date of death, injury, start and end dates, etc. That's 5 dates times 10 million records, or roughly 200 MB. How many dates you do have in current system? Bet it's a lot more than 5. If you consider mainframe storage, those original diskpacks cost more than your car. Now justify the cost of 2 cars just so you can storage a bunch of 19's or 20's.
Yep... I agreed. (Also mentioned in "The Clean Coder" by Robert C. Martin.)
How many care when the Gergorian calendar was created in 1582. I think there is a lost of four years somewhere in the calendar, but can remember where. The issue for antiquities can be more complicated when countries still rely on their original calendars, or when each country adapted the Gergorian calendar.
Most programmers don't think more than year/4 as a leap year conversion. Never mind the /100 or /400 calc. I still have to look up Pascals formula for calculating Easter.
While I do know a variety of issues and calculations, I still rely on the customer to tell me how to calculate something. If they say 2+2=5, then I make it happen. In 25 years, I have only disputed two calcs that made it to senior management and lawyers.
Back to the point, which is we can't know every exploit, but we can code for what we do know. How do you convey these issues to someone out of school or only a few years experience? This is stuff that gets learned by hard knocks.
The "Key Management" section of Foundations of Security (2007) doesn't say much either on where to store the private keys other than Smart Cards, HSMs or a Key-Store accessible by admin only. Is storing it on a DB (separate server) any good?
Inclusion of functionality from untrusted control sphere != missing authentication for critical function != input validation error?
Same fucking difference.
My favorite is attempting to prevent access by not printing the link / form control, and then doing no validation.
We may hit this one soon. I've found the following code in universe.h:
I skip a few lines here, to come to the relevant one.
It's obvious what will happen if we ever produce a Higgs particle at LHC.
I've already sent a bug report to god, but I haven't yet gotten an answer.
The Tao of math: The numbers you can count are not the real numbers.
http://it.slashdot.org/comments.pl?sid=2282088&cid=36639318
SanityInAnarchy?
Additionally - I really do NOT like you talking behind my back either... but, show up there, and we can discuss what I brought up (see you there).
APK
http://it.slashdot.org/comments.pl?sid=2282088&cid=36639318
SanityInAnarchy?
Additionally - I really do NOT like you talking behind my back either... but, show up there and we can discuss what I brought up (see you there).
APK
http://it.slashdot.org/comments.pl?sid=2282088&cid=36639318
SanityInAnarchy?
Additionally: I really do NOT like you talking behind my back either... but, show up there, and we can discuss what I brought up (see you there).
APK
The point is that there is no way to pass anything other than a SanitizedSQLString to the "raw" database layer. The only way to produce a SanitizedSQLString is via a strictly defined set of "safe constructors".
The DB access library defines the "safe constructors", not you, nor should there be any way to "convert" a String to a SanitizedSQLString without going through one of the "safe constructors" (which properly escapes or throws exceptions on "invalid" input).
A proper module system with real abstraction boundaries can enfore that restriction trivially. In languages with poor module support, say Java, judicious application of "final" (or your language's equivalent) would probably be enough for "practical" safety -- i.e. ensuring that you never accidentally circumvent the "safe constructors".
HAND.
Articles like this are bad. Not because there isn't a serious problem, but because the article doesn't address the problem with solutions. Writers like this don't help the situation any.
BeauHD. Worst editor since kdawson.
# Bind result columns with $sth->bind_col
I don't see any method called bind_col() in the left column of this page. All I see are bind_param() and bind_result(), both of which use a variable number of arguments passed by reference to the method rather than taking an array as an argument.
I think Bitfrost is supposed to do this? It was never clear to me how extensive or how granular it was, or how mature it has become. Or for that matter if it would be deemed "acceptable" by users or developers. The later should ideally suck it up and "do it right", but if the users walk away there's still a social problem that needs more engineering.