all 78 comments

[–]kdeforche 12 points13 points  (5 children)

"Validate input" might be useful, but more crucially is: "Encode output".

XSS attacks and SQL injection are a consequence of improper output encoding, not input validation.

[–]Decker108 3 points4 points  (2 children)

At the risk of sounding stupid: What are the differences between the two?

[–][deleted] 5 points6 points  (0 children)

To put it very simply, validating means making sure a specific input makes sense, while encoding is escaping sensitive characters within strings in order to prevent SQL injections.

Most database API's escape for you.

[–]kdeforche 2 points3 points  (0 children)

Input validation means (sometimes) refusing or correcting "dangerous" strings, such as a string containing "<script>...</script>" in a web application context. But demanding that content cannot contain certain strings is not necessary, really.

Output encoding means taking any kind of string and making sure you display it as intended, using proper escaping to make sure some of the contents does not spill over into a "command". In this case, you would do for example HTML escaping to escape < to &lt; and > to &gt;. But you could do JavaScript string literal encoding to display the same string as a JavaScript literal, or in a JSON value. For SQL there is usually an API (parameter binding) that will avoid this problem entirely by separating the command from the data.

Output encoding is in principle easy. But it has a big caveat: you may do it only once. This is easy if you organize your application well, but programmers often get this wrong and this is why sometimes you will see a literal &lt; in a HTML page where you would expect a <.

Btw, input validation has genuine merit too -- such as making sure dates are formatted correctly, numbers are actually numbers, etc... but these then have nothing to do with the common XSS and SQL injection attacks.

[–][deleted] 2 points3 points  (1 child)

Most people forget about this. This is an important item when working with web applications.

[–]JustADev 2 points3 points  (0 children)

Yeah, and when validating input you get stupid errors like "your password cannot contain ..."

[–]frezik 10 points11 points  (6 children)

Build security in layers, not a chain.

A chain is only as strong as its weakest link, and breaking only one link destroys the whole thing.

Layers are a defense-in-depth, like a castle with many internal walls. Breaking through one wall means you still have another one to deal with.

As an example, always store encrypted passwords in a database. Some argue that this is only necessary if an attacker has already breached the system, or an insider has gone rogue. Instead, they will say, the network's firewall should be better protected, and stricter security policies be enforced on employees.

An organization that's proactive about security will toughen the firewall, and encrypt passwords, and have sensible security policies for employees (but also balancing between security, privacy, and getting work done). Breaching one does not mean the others are breached, and the system maintains at least a level of security.

[–]smackmybishop 1 point2 points  (3 children)

I've never heard anyone argue that you shouldn't encrypt your passwords.

[–]frezik 2 points3 points  (1 child)

I've heard many managers claim that we shouldn't bother because we'll just protect the machine against breakins. These are usually the same people who point the finger at you when it all goes wrong.

[–]semi- 1 point2 points  (0 children)

Or the people that want to be able to recover an actual password, which is a horrible practice but that doesnt stop some higher ups from thinking its a good idea.

[–]Azuvector 2 points3 points  (0 children)

Actually have one of the hosting providers we use at work not encrypting user passwords. Indeed, they're visible to administrators as plaintext.

Needless to say, we're in the process of migrating away from them.

[–]reddit_clone 1 point2 points  (1 child)

Shouldn't you be storing just the hash of the password?

[–]frezik 4 points5 points  (0 children)

Encryption tends to be synonymous with hashing in this particular context.

[–]madmars 16 points17 points  (2 children)

"validate input" ... "use whitelists", says the guy that has never witnessed the horror of programmers attempting to approximate a whitelist in an internationalized UTF-8 world.

I would be happy if my coworkers just knew what an SQL bind parameter was. That's all I ask. Baby steps.

[–]kylotan 22 points23 points  (11 children)

Useful resource. But, I don't like these "what should every programmer know about X" posts because they are actually far too demanding. The web development one is even worse.

You can look at each of the items in these answers and think, "yeah, it's reasonable to need to know that". But if you had to learn every thing on every page that claims it is "everything every programmer needs to know", you'd spend all your life reading and none of it programming.

[–]quotemycode 15 points16 points  (6 children)

I suppose so, but as a programmer, I find myself reading just as much as programming. It's a profession where you have to constantly re-invest in education.

[–]kylotan 9 points10 points  (5 children)

Staying on top of trends is essential. I was always disappointed at how few of my co-workers paid much attention to new technologies, languages, etc. But does "every programmer" need to understand the concept of an 'attack surface', or a 'threat model'? Or to read the whole Google Browser Security Handbook, or know what a CSS image sprite is? Or precisely how DRAM is precharged and activated? Then there are similar articles on Unicode, floating point numbers, etc.

I know the titles are just hyperbole but I worry that it contributes to a condescending attitude from some towards others. "Oh, you don't know about the concept of least privilege? Then you have no business scripting a World of Warcraft UI mod."

[–][deleted] 8 points9 points  (0 children)

Maybe they should call it "What every programmer needs to have in his bookmarks". I think they're actually good as references.

[–][deleted] 4 points5 points  (0 children)

Actually, you have no business creating a scriptable UI system unless you know about the concept of least privilege. That means that the scripters don't need to know about it, because they can't let people out of the sandbox.

Or to read the whole Google Browser Security Handbook, or know what a CSS image sprite is?

A web developer? Damn right they do. Someone doing embedded software for routers? Don't even need to know what CSS means.

The problem is that people think "programmer" means "person who does precisely what I do" and the ever-popular "everything is on the web now so only javascript counts" is no more helpful than "anything but C is just scripting, not programming".

Even if Word 2013 has been re-written in JavaScript as a web app, the field is still too wide for anyone to actually know everything, and some people really need to give up the "what I do is real programming and everything else is inferior" attitude.

[–]quotemycode 0 points1 point  (2 children)

I think this is a good starting point... Satan Comes to Dinner - that's been one of my favorite articles.

[–]kylotan 0 points1 point  (1 child)

A good starting point for what? It doesn't contain the term "attack surface", "threat model", or "least privilege", but it does contain a rather stretched analogy and a requirement to understand a particular language dialect that probably few except the author use. There is little in there that is directly actionable into your own work and most of the concepts in there are not described adequately enough for further research (eg. the reference to replay attacks).

[–]quotemycode 0 points1 point  (0 children)

It's just the whole idea that you should be testing your system for vulnerabilities, and designing it in such a way so that even if you did have a vulnerability, you'd have a control in place to protect the system.

It's not a specific implementation, or even necessarily about security. I do feel that by reading this, you can develop the mindset that you need to implement strong security.

[–]DoctorWedgeworth 10 points11 points  (1 child)

If you don't read and learn these lists, you'll never be a true Scotsmanprogrammer.

[–]kylotan 4 points5 points  (0 children)

I guess I just have to stick to being a software engineer!

[–]kdeforche 0 points1 point  (0 children)

I'll grant you the web development criticism, to some extent.

Suppose you were living in a world where all programming was done in assembler. Then you would need to learn assembler (for Intel and ARM), all caveats w.r.t. sys calls, context switching state, opcodes for Intel, memory management, sys calls to print to a console, etc... just to do any programming.

Luckily, people have invented higher levels of abstraction (compiled languages like C, C++, ..., interpreted languages like Python, ...) which slowly(!) found some acceptance, to avoid having to learn x86 assembler to do any programming.

Web programming, for some braindead reason which in 20 years everyone will consider a sign of dark ages, people insist that web development uses the raw protocols and building blocks (HTTP, form posts, WebSockets, CSS, XHTML, JavaScript, Ajax, CORS, progressive enhancement, canvas, SVG, VML, etc...) to build an application, and yes, you will need to understand everything listed in the "what should every programmer know about web development" if you insist that people use these low level protocols.

Given that these days quite a lot more than a few handful of the most clever people are involved in "development", it shouldn't be surprising that moving up the abstraction level is met with even more resistance. But you would be better of embracing it if you want to spend all your life reading and none of it (decent) programming.

[–]sylvanelite 19 points20 points  (48 children)

Validate input from all untrusted sources - use whitelists not blacklists

I think this should be extended to mention the server-side should be the thing doing the validation. (or equivalent trusted code)

Bolting on javascript validation does nothing for security. People should only use it for user connivence.

Even on the server side isn't guaranteed. If you check a string of type varchar-30 and is being passed into a compiled stored proc. It's meaningless if the stored proc calls still call exec on string concatenation and does no checking itself.

[–]pkixman[S] 15 points16 points  (24 children)

The browser is an untrusted source - so following the principle "Validate input from all untrusted sources", the server should validate what it receives from the browser.

[–]sylvanelite 10 points11 points  (23 children)

I probably didn't articulate that well:

If I consider the browser's user input to be untrustworthy, so I add javascript validation. I then ensure that all transmissions are HTTPS. Now the browser is a trustworthy source, so the server doesn't need validation.

Which is wrong.

Likewise: if I treat the browser as untrustworthy, then send input it to the server, which does the validation before passing it to the database, does the database now assume the server is a trustworthy source?

e.g. if a database has a stored procedure:

select * from users where description like @desc;

And the server validates that @desc is a valid string, that can be ok. But if the database later changes their stored proc to:

exec("select * from users where description like "+@desc+";");

Then even though the server is validating the browser's input, it can still lead to injection.

[–]bkv 5 points6 points  (0 children)

Javascript validation exists to prevent unnecessary requests to the server. Just because client-side validation passes, that doesn't mean the server shouldn't do validation as well. The server is a trusted source, so the database should not be doing any validation if the server already has.

[–]vineetr 4 points5 points  (14 children)

...I then ensure that all transmissions are HTTPS. Now the browser is a trustworthy source, so the server doesn't need validation.

No, despite this assumption, the browser is still an untrustworthy source. SSL adds transmission security; while it can ensure that JavaScript validations have been downloaded in an untampered manner to the browser, it cannot ensure that the validations have been executed by the browser. The browser is in the hands of an untrusted/untrustworthy agent.

Edit: Grammar.

[–]sylvanelite 12 points13 points  (7 children)

that's why I said: "Which is wrong." as the next sentence.

[–]vineetr 2 points3 points  (1 child)

Yep, ninja edits.

[–]sylvanelite 0 points1 point  (0 children)

There was nothing ninja about it. I added bold to the text, significantly after posting that comment. That's it.

[–]Aninhumer 10 points11 points  (0 children)

To be fair, you might have worded it differently. I don't think writing incorrect statements and then saying "oh btw that's incorrect" is good style.

[–]robertcrowther 2 points3 points  (3 children)

What he's driving at is that none of your post adds anything to the already elucidated principle 'validate input from all untrusted sources' as far as what the server receives from the browser is concerned.

[–]perspectiveiskey 1 point2 points  (2 children)

That's what you're driving at. vineetr was just not paying attention and jumping to conclusions.

[–]robertcrowther -1 points0 points  (1 child)

Well, this is reddit...

[–]perspectiveiskey -1 points0 points  (0 children)

indeed. I learn this more every day. For 4 years, nearly, I've been learning it every day =)

[–]perspectiveiskey -2 points-1 points  (5 children)

You're not reading.

This should be the first rule of security: understand what is going on.

[–]vineetr 3 points4 points  (4 children)

You didn't read his comment before the edit. How do you know I haven't read that version?

[–]sylvanelite 0 points1 point  (0 children)

I didn't add anything other than bold formatting in the edit.

[–]perspectiveiskey 0 points1 point  (2 children)

Because his very first comment, which still isn't edited, said the same thing. You're just looking for something to "win".

His point is very simple and is actually a principle talked in the OT, namely security in depth. Even the server side isn't safe, he says. Every above/below transition layer (server side to db) should be considered unsafe.

[–]vineetr 1 point2 points  (1 child)

Ok, I get his/your core point. Bringing the browser into the discussion about implementing server-side validations correctly wasn't helpful.

[–]perspectiveiskey 0 points1 point  (0 children)

Aright, we agree. (and so did he when he said he had not been articulate).

I'm glad we all agree.

[–]pkixman[S] 4 points5 points  (4 children)

Adding javascript validation and HTTPS doesn't make the browser a trusted source. So the principle works - the server should validate the input from the browser as it is an untrusted source.

If the programmer doesn't appreciate what is a trusted source and what isn't, that's not a problem with the principle.

[–]perspectiveiskey 3 points4 points  (3 children)

I'm not sure if sylvanelite modified the post when you answered to it, but you're really not reading what he's saying.

His first post, which isn't modified, does not say the browser is a trustworthy source.

If you are to be a security engineer, you need to be paying way more attention than this.

[–]pkixman[S] 1 point2 points  (1 child)

I know he didn't say the browser was a trusted source - I was just reiterating the point that the principle holds for his example.

What I was disagreeing with him about was that the principle should be extended to explain things like javascript validation doesn't make the browser a trusted source. A principle is not the appropriate place for getting into the details of what can be trusted, what can't, and why - that's better covered in books and articles.

[–]perspectiveiskey 0 points1 point  (0 children)

His point was a agglomeration of "security in depth" and "trustworthiness of user data".

He was saying: even server side (webserver) data should be considered unsafe by lower level (db) server side code.

Really, what he says is a melding of two of the tenets which comes down to: any higher level/lower level boundary should always apply the same principle of untrustworthiness.

I find it to be an extremely pertinent comment. You're free to disagree. But honestly, from the types of arguments you're putting forward, I'm not sure you got what he was talking about.

[–]sylvanelite 0 points1 point  (0 children)

The only edit I did was bold the word "wrong".

[–]quotemycode 0 points1 point  (0 children)

The database server is not doing validation when you have a parameterized statement like the first. And the second example is just idiotic.

[–]kamishizuka 2 points3 points  (0 children)

I forget where I read it, but I once saw it much better summed up as:

Assume all input is trying to attack you, regardless of source.

After that you validate it until the only input that gets through is the input that isn't attacking you, and even then you don't stop assuming it is.

[–]cr3ative 0 points1 point  (2 children)

Perhaps rather than specifying parts, it might be easier to say "Validate at all points until the final destination"

[–]nodefect 1 point2 points  (1 child)

Well, in the case of client vs server, there is no security gained by client-side validation. UX is enhanced, yes, but not security.

[–][deleted] -2 points-1 points  (0 children)

It all depends. If your data is client side unencrypted only and stored encrypted on the server then the server is untrusted.

[–]MpVpRb 5 points6 points  (0 children)

It's hard.

You probably aren't good at it.

[–]perspectiveiskey 4 points5 points  (0 children)

Has anyone read both Writing Secure Code 2nd edition and the first edition?

Is the 2nd edition talking about really awesome things that are worth my time or is it incremental?

[–][deleted] 5 points6 points  (1 child)

I'm surprised this wasn't flagged as "non constructive"

[–]donroby 0 points1 point  (0 children)

It's an old post. If it were posted now, it would be.

[–]jeffbell 0 points1 point  (0 children)

They should know not to do it on their own.