Kaminsky Offers Injection Antidote 244
ancientribe passes along this excerpt from DarkReading.com: "Life's too short to defend broken code. That's the reason renowned researcher Dan Kaminsky says he came up with a brand-new way to prevent pervasive SQL injection, cross-site scripting, and other injection-type flaws in software — a framework that lets developers continue to write code the way they always have, but with a tool that helps prevent them from inadvertently leaving these flaws in their apps. The tool, which he released today for input from the development and security community, basically takes the security responsibility off the shoulders of developers. Putting the onus on them hasn't worked well thus far, he says. Kaminsky's new tool is part of his new startup, Recursive Ventures."
Parameterized SQL (Score:5, Informative)
Parameterized SQL, or prepared statements, completely prevent SQL injection attacks. They might also speed things up in some circumstances. Why not simply use them exclusively?
Fans of functional programming (Score:1, Informative)
might like what formal verification guru Adam Chlipala (http://adam.chlipala.net/) has been doing: http://impredicative.com/ur/
This is a very cool special purpose language that generates fast native code for web pages, and statically guarantees
the absence of injection and xsrf attacks, and also of broken links and other sorts of errors that plague lots of web sites.
Well (Score:3, Informative)
the essence is this:
Which means he enforces a convention on developers that aims to improve code security. Sounds smart.
Re:this is just taint mode (Score:3, Informative)
It also looks like an implementation of what Joel Spolsky recommended a while back (search for the stuff about hungarian notation):
http://www.joelonsoftware.com/articles/Wrong.html [joelonsoftware.com]
Re:Parameterized SQL (Score:3, Informative)
but you can't rewrite the decades of bad advice still out there
At this point I'd settle for people not writing SQL in all caps with the vowels removed. It's like the 'convention' is to make SQL as unreadable as possible. The 70's are over folks, toss your caps-lock key and buy a vowel. SQL can be readable.
code review (Score:5, Informative)
I can't even think of writing code without checks for every condition imaginable simply because when I started coding, I was learning among peers whose favorite thing to do was poke holes in your code in some way or another. I guess that's known today as "peer review" but it was more like peer pressure review when I was in school. The last thing I wanted was to have embarrassing or code that may be ridiculed. And I think that's what TRULY missing in today's development environments -- shame and ridicule.
At DEC we had a formal process known as “code review”. A bunch of us got copies of some code to review. We then all met together and went over the code line-by-line describing the flaws that we found. There was also statistics gathering and reporting, but the greatest value of the process was to the coder, who got feedback on his code. I had thought it would be hard to avoid getting upset at what were perceived as personal attacks (“that's my baby you're criticizing”) but, at least in the code reviews that I was involved in, that never happened. The whole thing was handled very professionally.
Re:This is advertisement, not a story (Score:3, Informative)
What's the point of this article?
From TFA: "Dan Kaminsky today went public with the launch of a new venture"
That was the point of the article. He wants you to buy his "product". Me, I'm sticking to good old fashioned Eau de Snake.
mysqli_stmt_bind_param() (Score:3, Informative)
99.9% of the time if you cannot parameterized a query, you're doing wrong.
In that case, all the 0.1% of the queries appeared to fall on me. Try using operator IN with parameters, and then see why it doesn't always work [pineight.com].
There's nothing stopping you from building a dynamic SQL string with parameters
That doesn't work if the parameter interface in your database's client API expects there to be a constant number of parameters in each statement. For example, how does one pass a variable number of parameters to mysqli_stmt_bind_param() in PHP?
Re:Well (Score:3, Informative)
hungarian notation is best used not to store actual datatype of the variable, but additional information beyond the raw datatype. So "strTitle" is worthless in a statically typed language, and at best questionable in a dynamically type language.
But "uTitle" to indicate an unsafe (unescped) title and "sTitle" to indicate an title that is safe (has been escaped) is a coding convention that makes plenty of sense. It is very possible to then automatically scan code to find violations of safety, such as any assignment of the form "sFirstName=uFirstName".
Extend the convention to functions, and one can automatically detect the problem with "sAddress=uGetAddress", or passing "sLastName" to a function with the prototype "int HashString(std::string uString)", which clearly wants an unescaped string.
One can also detect other unsafe or undesirable actions like escaping an already escaped string, or concatenating a safe and an unsafe string, etc.
Now when Charles Simonyi described the system initially he had not yet made the full distinction between type information the compiler already knows, and additional type information. Many, but not quite all of his examples in the original paper gave additional information. His lack of a full distinction is what led to many of the uses where Hungarian notation is not giving anybody any useful information.
Of course the best way to handle the whole thing is to have each semantic data-type be a distinct data-type to the compiler. So I would have both an "UnsafeString" and a "SafeString" data-type, and doing something unsafe like assigning one to the other directly would result in a compiler error. For dynamic languages, having a compile-time error is not feasible, but having two data-types and having unsafe operations result in a run-time error is still possible, and should be preferable to a successful injection attack.
Re:so educate me (Score:2, Informative)
CREATE PROC QueryWithParams
@a1 varchar(100),
@a2 varchar(100),
@a3 bigint,
@a4 bit,
@a5 varchar(50)
AS
BEGIN
SELECT field1, field2, field3, field4
FROM tables
WHERE
(@a1 IS NULL or fieldtest1 = @a1) AND
(@a2 IS NULL or fieldtest2 = @a2) AND
(@a3 IS NULL or fieldtest3 = @a3) AND
(@a4 IS NULL or fieldtest4 = @a4) AND
(@a5 IS NULL or fieldtest5 = @a5)
END
Not as elegant and just building the query you want, but is almost always safe and "pre-compiled" by the query engine. Also, I can control which fields are going to be filtered.
Re:Parameterized SQL (Score:4, Informative)
The developer culture around SQL, where the majority of tutorials, cookbook methods, forum support groups, "expert" examples, etc. reinforce doing SQL the insecure way.
It's easy enough to straighten out, though. At my current job, committing non-parameterized SQL strings into production is a firing offense and everyone is told that from the beginning. It's right up there with "don't stab the boss" and "don't smoke crack at your desk".
I laugh here, but it really is that serious. There's not a single legitimate reason for ever using anything other than parameterized queries. They're easier to write ("How many quotes do I need to put here?"), easier to maintain (because you don't ever have to mix SQL and code), always as fast as constructed queries and usually faster, and generally superior in every single way.
Re:code review (Score:3, Informative)
So you were working on DEC. I have been waiting to ask this question to some DEC for long long time. The default behavior in DEC for any violation seems to be to crash the executable, without warning, without stack trace, nothing. Have to laboriously insert debug/print statements and find the location of the crash. It was a nightmare of a platform to work with. We were basically using DEC as our hardware bounds checker. If it runs on DEC, you don't have to run bounds checker, purify etc. But very painful to develop in that platform.
The behavior depends on the platform. My experience was with the PDP-10 and VAX systems. The PDP-10-based machines generally were very good for debugging, since the early software was written in assembler. There was no stack trace, since stack handling was an application convention, but there was a good debugger.
On the VAX systems the assembler-level debugger was not as good, probably because we were developing in a high-level (for the time) language by then. Exception handling was much better, though. An access violation got you a good message.
Were you using a PDP-8 or PDP-11 system? They were relatively primitive compared to the PDP-10 and the VAX.
I was told that people used the VAX Ada compiler, even when they did not intend to run the application on the VAX, because its compile-time diagnostics were so good. If I remember correctly, when it reported an error it described what was wrong in great detail, including quoting from the Ada standard by chapter and verse.