NSA Says Its Secure Dev Methods Are Publicly Known
Trailrunner7 writes "Despite its reputation for secrecy and technical expertise, the National Security Agency doesn't have a set of secret coding practices or testing methods that magically make their applications and systems bulletproof. In fact, one of the agency's top technical experts said that virtually all of the methods the NSA uses for development and information assurance are publicly known. 'Most of what we do in terms of app development and assurance is in the open literature now. Those things are known publicly now,' Neil Ziring, technical director of the NSA's Information Assurance Directorate, said in his keynote at the OWASP AppSec conference in Washington Wednesday. 'It used to be that we had some methods and practices that weren't well-known, but over time that's changed as industry has focused more on application security.'"
...it is definitely possible to write secure software if you just simply follow sound and smart development methods and practices... and don't write half-assed, slipshod, thrown-together-in-a-hurry code.
the nsa is pants
security doesn't come from obscurity
If the NSA has something that really is Schneier-proof, they wouldn't tell the public. And understandably so, since part of their job is in part to ensure signal security for US agencies that deal in classified information.
I am officially gone from
...that's what they WANT us to think...
It's that word most in "Most of what we do..." that may be important here. Most doesn't mean all. Also note he did not mention their cryptographic techniques, which is where I would expect them to be especially advanced.
Security, especially in software development, doesn't suffer from the "we don't know how to do it" problem. It suffers from the "we don't have time/budget/patience/interest in doing what we know we should be doing" issue.
Assorted stuff I do sometimes: Lemuria.org
Despite its reputation for secrecy and technical expertise, ... virtually all of the methods the NSA uses for development and information assurance are publicly known.
Secrecy doesn't have to extend to every single thing. I'm sure NSA uses regular toilets too, not the top secret kind. As for reputation for technical expertise, how does using tried and tested development methods goes against that?
Negative moral value of force outweighs the positive value of good intentions.
Ziring said that even within the NSA, the problems of application security remain maddeningly difficult to solve.
"Very few applications start from a clean slate. They're built on the existing code bases and they have to work with other existing apps and they have to be updated frequently."
And thats exactly what they want you to think...
My page.
What about all this "Setec Astronomy" business then?
The Soviets almost never used to crack codes. They just social-engineered (blackmail, sex, gifts, schmoozed, etc) to get all the information they wanted.
It's how Mitnick did most of his work as well.
Writing bulletproof code isn't really all that hard, but it does take discipline. Discipline to use only those constucts which have been verified with both the compiler and linker.
Some simple things that coders can do:
- avoid the use of pointers.
- Initialize all variables to known values.
- Perform comparisons with the LHS using a static variable, so you don't accidentally get an assignment instead of a comparison
- When you are done with a value, reset it to a "known" value. Zero is usually good.
- Keep functions less than 1 page long. If you can't see the entire function on a single editor page, it is too long.
Simple.
BTW, I wrote code for real-time space vehicle flight control systems. When I look at OSS and see variables not set to initial values, I cringe. Sure, it is probably ok, but there isn't any cost to initializing the variables. This is a compile-time decision. Without knowing it, many programmers are counting on memory being zero'ed as the program gets loaded. Not all OSes do this, so if you are writing cross platform code, don't trust it will happen. Do it yourself.
Oh, and if you want secure programs, loosely typed languages are scary.
One cornerstone of secure software development is the application of formal methods. The NSA Tokeneer project has been made completely open-source, demonstrating the feasability of applying formal methods to secure development problems.
Initialize all variables to known values
And remember to reset them to known values as soon as they are no longer necessary. Not only is it good practice, whether or not the compiler has a job, but it encourages the programmer to keep his variables in mind.
the NPG electrode was replaced with carbon blac
They're using Agile practices! They just developed them before anyone else, about twenty years ago!
Incidentally, this also explains why they haven't done any groundbreaking work in twenty years... ~~~~
This won't do anything to convince all the people who believe that the NSA can zoom in and enhance bad quality photos to a 10000 times. Despite it not being possible, the government probably has secret technology. Sigh.
If you ignore ACs because they are anonymous - you're an idiot.
really piss me off.
For large sets, this will be our guide even unto death, for the LORD will work for each type of data it is applied to...
No, you cannot. You can prove that it should do so, but you cannot prove that it will always do so. For example, your assumption is that the interpreter or compiler behaves the way you think it does, when you in fact have operated on numerous unproved assumptions.
Guns don't kill people; Physics kills people! - John Lithgow as Dick Solomon on Third Rock From The Sun
"Most"
"It is a good thing for an uneducated man to read books of quotations..." -Winston Churchill
Introductory programming advice is now informative on Slashdot? This place really has declined...
For anyone who's read security posts on this site - all too often NSA folks pop up and respond :)
(and are frequently very helpful)
That only applies when you're using an inferior language. Variables should initialize to zero by themselves and go out of scope when I'm done with them.
Perform comparisons with the LHS using a static variable, so you don't accidentally get an assignment instead of a comparison
Static variable? You probably mean put a constant or expression on the left of the ==. That's awkward to read. How hard can it be to distinguish = from == from ===? I'd say if you have trouble keeping those apart, you should switch to COBOL.
if you believe this tripe, you're clearly a fool.
the article is just a fluff piece for the so called war on cyber-terrorism (which is in itself just an excuse to exert greater control over the interwebs) -- "hey guys all our secrets are in books, please stop looking to see if we have any more! 'cause we really don't! honest!"
Writing bulletproof code isn't really all that hard, but it does take discipline. Discipline to use only those constucts which have been verified with both the compiler and linker.
Some simple things that coders can do: - avoid the use of pointers.
Pointers aren't themselves bad; they just add some layers of complication to the otherwise stack-oriented game. The only reason the stack is nicer than pointers is because they're implicitly managed for you.
Rather than avoid pointers, what you need is good code structure. Design functions that either manage the lifecycle of a pointer or are explicitly clear about how and what the pointer is going to be used as. Use const aggressively, and avoid typecasting as much as possible. Using good pointer naming techniques and management functions also dissipate the burden. Pointers are too useful to avoid religiously ... rather, build pointer security and management techniques into your coding style from the ground up. Choose descriptive names and try and constrain each pointer to its specific type (this lets the compiler help you keep your pointers straight).
Initialize all variables to known values.
Meh, I'm divided on this one. It's one thing to explicitly initialize global variables to either zero (which costs nothing, since they just end up in BSS sections) or non-zero (which puts them statically in the data segment). Stack variables, on the other hand, only really need to be initialized before they're used the first time. Pre-initializing them could lead to wasted instructions initializing them multiple times or cause them to be initialized in all code paths when they're only used in a few. My general rule of thumb is to be smart about it and, once again, naming conventions.
Perform comparisons with the LHS using a static variable, so you don't accidentally get an assignment instead of a comparison
Great tip; it's weird at first writing "if( NULL != p )", and you get a few funny stares, but after seeing enough "if( i = 10 )"s lying within seemingly-functional code, it's an easy selling point to make.
- When you are done with a value, reset it to a "known" value. Zero is usually good.
Definitely do this with pointers, descriptors, and other handle types. It also makes cleanup and pointer management easier. Less important to do with things like iterators and intermediate variables.
- Keep functions less than 1 page long. If you can't see the entire function on a single editor page, it is too long.
It's a good rule of thumb. I would like to add "any time you can't do this, make absolutely certain that you're not doing it for a good reason."
Good tips, though. One thing I'd like to add: -Wall -Wextra -Werror (or your language's equivalent). If your code can't compile without a single warning, then you need to re-write your code and either manually disarm situations (e.g., override the compiler's common-sense with an assurance that you know what you're doing) or fix the warnings, which are actually bugs and errors. It's always fun to take someone's "bulletproof" code and turn on these flags and watch the crap spill out. Warnings are amazing, and they are absolutely your friend when it comes to writing bug-free and secure code.
Some simple things that languages can do:
- Have all variables initialize to known values. I mostly program in C++/Qt and QString, QByteArray etc. don't need initialization. All numbers should initialize to 0, all pointers to NULL.
- Don't make the difference between assignment and comparison be a simple typo. If I were to design a language, "=" would not be a valid operator. ":=" for assignment, "==" for comparison. (You could keep all the "+=" etc. but not plain "=")
- Smarter scoping hints, like letting you call a function and *pass* the variable, which ends its scope.
Keep functions less than 1 page long. If you can't see the entire function on a single editor page, it is too long.
In my experience that is not practical and leads to too many artificial functions. But you should try reducing the complexity of how many different variables get involved. It's easy to read a three page function if only things are scoped out properly so only the important variables stay in scope. E.g.
void longFunction() // 10 lines of code to calculate foo, some various temp variables etc. // Here only foo is left in scope
{
int foo = 0;
{
}
}
Live today, because you never know what tomorrow brings
Without knowing it, many programmers are counting on memory being zero'ed as the program gets loaded
Any compliant C compiler will initialise all statics to 0 (stack values are different - they are not automatically initialised). From the C99 spec, 5.1.2:
All objects with static storage duration shall be initialized (set to their initial values) before program startup.
From 6.7.8.10:
If an object that has static storage duration is not initialized explicitly, then:
You can guarantee that any standards-compliant C implementation will do this. You can't guarantee anything about an implementation that doesn't comply with the standard - it may deviate from it in other ways.
I am TheRaven on Soylent News
Stack variables, on the other hand, only really need to be initialized before they're used the first time. Pre-initializing them could lead to wasted instructions initializing them multiple times or cause them to be initialized in all code paths when they're only used in a few.
Unless your compiler really sucks, it will perform some trivial dataflow analysis and not generate code for the initialisation if the value is never used. Even really simply C compilers do this. If the value is used uninitialised on any code paths, then the initialisation will be used (although it may be moved to those code paths), and you don't want the compiler to remove it.
From the flags you recommend, I'm guessing that you use gcc, which not only does this analysis it will even tell you if the value is used uninitialised.
I am TheRaven on Soylent News
Bullshit. The fact that you admit that you start with unproved assumptions is an admission that you cannot prove the correctness. The fact that you are posting as an AC, but still following up with what is tantamount to a troll would be proof that you are a troll, were I not operating on the unproven assumption that you are in fact the same poster as you imply. ;-)
Guns don't kill people; Physics kills people! - John Lithgow as Dick Solomon on Third Rock From The Sun
I'm strongly against this. I use a compiler so I can write clear code, rather than assembly language. A compiler can catch all unintented assignments like this, by giving a warning whenever the result of an assignment is used as the condition, without any further comparison.
I find that it's much clearer to me to put the changing value on the left, and the thing it should equal on the right. So let's say I've got a loop that steps i through various values, and if i matches j, I do something. I'd write that as if(i==j), not if(j==i), even though they are equivalent. Mentally asking if "the value I'm looking for matches the value of i" is just backwards. Again, the compiler's job is to allow me to express things clearly. It can warn of assignments in if conditions, so I enable that and get on with coding for clarity.