Hacker News new | past | comments | ask | show | jobs | submit login
What should every programmer know about security? (stackoverflow.com)
162 points by napolux on May 7, 2012 | hide | past | favorite | 48 comments



Since this is my specialty, I figured I'd put my 2cents in on hacker news, and repost it on stack overflow later. So to begin some tools that you should use for testing your code:

Burp tool suite (Pen Testing) BackTrack Linux Distro (has all kinds of tools, wont go into them, but download and it can be used to really cause havoc on your apps)

These tools allow you point programs towards your application and see if they are vulnerable to any kind of attacks, including XSS and SQL Injection (among a lot of others)

Engineers should also read the OWASP site, which has the OWASP top ten. It also has other tips and tricks about how to secure against different attacks. If you ever have a security question, this site has a lot of secure examples for different code.

As the top comment on stack overflow says, never trust your users. That means never allow your users to do things that you don't want them to. If you allow them to deviate from the structure of your program in any sense, someone will find a way to abuse the privilege. This is the key to good security.

Some Tips I'll give you: 1 ) Validate all input 2 ) Control Access to everything 3 ) Use secure application keys to ensure that people can spoof requests from different browsers 4 ) Use Multi Factor Authentication whenever its possible 5 ) Never ever pass any values from the server that should leave to the client. Even if it is hashed, I can break it using tools. Valuable data = Server side Public Data = Client safe

If you have any other questions, feel free to post them and I'll try my best to answer them or find you an answer.


Information security is a topic that I'm very interested in, but it's such a large area that I don't know even where to start. In this field especially, "learning by doing" seems an extraordinarily bad idea. You say this is your speciality; how did you acquire it? Are there any online courses, good books, or useful (i.e. non-bullshit) certifications that you can recommend?


I acquired it by just doing it over the years I've been programming/engineering. When I was younger I wanted to be a "hacker" (the kind that does malicious stuff and ends up locked in federal prison), so I started using tools like backtrack to see if I could break websites, and it turned out I could. I just read things like OWASP, and I currently work for a security company that specializes in financial institutions (AKA banks, credit unions etc) so I acquire knowledge on the job as well. As for books, I found Security Strategy: From Requirements to Reality to be really good, but I haven't really read too many books on this subject to be honest. Certifications are usually cheap and no good, so I don't recommend those. I recommend learning about communication protocols though because if you understand those, you can figure out attacks that may happen just by knowing how they work. As well, there are applications like Webgoat that allow you to download them and they are full of security flaws so you can kind of learn from that. There are guides to teach you how to hack webgoat out there. The key to great info sec is thinking like a hacker, and you acquire by hacking websites (preferably webgoat/your own).


It has become a lot easier to "learn by doing" without breaking any rules.

If you are looking at web application security, there are a number of "simulation" games. The first that come to mind are Damn Vulnerable Web App (http://www.dvwa.co.uk/), The Hackme Bank (http://www.mcafee.com/us/downloads/free-tools/hacme-bank.asp...) or OWASPs WebGoat (https://www.owasp.org/index.php/Category:OWASP_WebGoat_Proje...)

DVWA is probably the best choice for somebody with no prior knowledge. A quick google search on "dvwa walkthrough" will get you started.


You can do a lot of learning-by-doing without actually exploiting vulnerabilities, or even doing anything illegal. Especially if you're on a college campus with an interesting computer network, and ubiquitous wireless networks (for relative anonymity). Do port scans (nmap) and explore interesting services you find (with netcat + google), dump DNS entries for campus and grep for interesting words, then do more port scans, etc.



I love WAHH.

I can't stand "Deadly Sins".

I'd replace it with _The Tangled Web_, Zalewski's new web security book; WAHH and _Tangled_ is a formidable amount of knowledge to keep on tap.


If don't want/unable to get, Tangled Web, similar useful information by same author at "Browser Security Handbook" http://code.google.com/p/browsersec/wiki/Main


I don't quite understand number 3? Can you elaborate number 3 a bit? How is that being used? Can SSL do the same thing? Or do you mean preventing CSRF kind of attack?


Multi Factor authentication is basically using multiple factors to authenticate a user, like texting a number to the person's cellphone to authenticate them if they are visiting from a IP that is not familiar with the system. Its basically using a second piece of information besides a password to ensure that a user is who they say they are. The sending a text message with a number is a real popular way of doing this. Think as well as a pin and a credit card at an ATM. Sure you have to use your ATM card at the ATM to prove your identity but you also have to use a PIN to add an extra layer of security. This significantly reduces the risk of a breach on someones account.


Parent was asking about No. 3, you just explained No. 4?


My previous reply was bad, and for that I apologize. Yes, use application keys for your services/controller to make sure that it indeed an app. This prevents session spoofing and CSRF. Rails does this automatically, so do a lot of other frameworks/languages so it isnt a big deal, but some people use services built on Scala or another language without frameworks, so they tend to be susceptible.


He's probably talking about session hijacking https://en.wikipedia.org/wiki/Session_hijacking


BackTrack is pretty overwhelming at the beginning. Do you have any suggestions on what programs/attacks will give you the most bang-for-your-buck?


I probably wouldn't recommend training team members on Backtrack. Backtrack is a go-to tool for network penetration testers, but if your concern is the security of your code, you're better served with a license for Burp Suite. Much of what's in Backtrack, including Metasploit, is probably not going to be useful in the "we'll need it every time through the dev cycle" sense.


The ones I use the most are:

Wireshark (to analyze traffic coming too and from my website), Metasploit (To make social engineering exploits to make sure my servers arent vulnerable), Mantra Security Framework, Cisco OCS Mass Scanner (For breaking Cisco Routers), SQL Inject, SQL Scanner (Both for finding injection errors). If you master these, you can do a lot of cool things with them. Wireshark is your best friend when things aren't over SSL.


wireshark just fine when things are over ssl. all you need is the private key. you'd be floored at how lazy some people are with their private keys.


Backtrack is used to install/host metasploit. If you find Metasploit daunting then you could use Armitage - a gui interface for metasploit.


I am wary of software security advice that leads with "don't trust user input", or revolves around "validate user input". That principle has been the core of software security strategy for going on 20 years, and has bought us very little. In the real world, we have to start by acknowledging that the verb "trust" is situational, and that in some circumstances virtually all user input is "trusted" somehow.

You could phrase this less tactfully as "Validate user input? No shit? Now what?"

Here's some software security advice I'd like to offer, as a software security practitioner to the startup stars and the Dr. Drew Pinsky of HN (ducks):

* Plan to update your platform software at inconvenient times. Dry-run your update process, so you know it will work on no notice. I personally believe you should also avoid your OS's packaged versions of things like Apache and nginx; having a known-working source build gives you control of when and how you'll apply patches; it's something you should be able to do easily.

* Put someone on your team in charge of tracking your dependencies (C libraries, Ruby gems, Python easy_install thingies) and have a process by which you periodically check to make sure you're capturing upstream security fixes. You should run your service aware of the fact that major vulnerabilities in third-party library code are often fixed without fanfare or advisories; when maintainers don't know exactly who's affected how, the whole announcement might happen in a git commit.

* Use TLS to encrypt data in motion and use GPG to encrypt data at rest, and don't do any other kind of crypto. GPG blobs are large and expensive looking, but getting custom crypto right is also very expensive.

* Stay on your platform's "golden path" for web security issues. Rails developers should default-whitelist ActiveRecord models, enable CSRF protection, and avoid "html_safe-ing" strings so that the maximum amount of code inherits default protections against mass assignment, XSS, and CSRF. Anything you customize will probably bite you in the ass. Keep your code boring.

* Triple check any piece of code that "shells out" to command line tools. By "triple check": have a process by which three signoffs are required to merge any such code into the deployment branch.

* Be extraordinarily wary of library code for web apps that includes "native" C/C++ code. Very popular C library code for modern web platforms has been found susceptible to basic memory corruption issues, because the kinds of people that look for memory corruption bugs don't usually think to troll Github for Ruby, Python, and PHP code with native backend code; terrible bugs can thus stay latent for years in code you can point a URL to and read.

* People will hate me for saying this but I'm here to offer honest advice: prefer almost any modern language to PHP or Perl. I don't know what to tell you other than that PHP and Perl apps fare worse on security assessments than everything else.

* I have more than once recommended that people who are very very concerned about platform security (ie, about the likelihood that there are memory corruption bugs in their language stack) use JVM languages.

* Do your admin stuff out-of-band. Write a separate admin app (bonus: the admin app can look shitty, and so is less expensive to maintain) that requires a VPN connection to access. Avoid special-privilege accounts in your normal apps. From years and years of experience working with startups: this is something you will mess up on.

* Triple-check code that handles direct file uploads and downloads. The filesystem introduces a new namespace, so upload/download code needs to juggle different privilege and authorization domains to handle it. We see fewer problems at companies that dump blobs with opaque names into S3 than we do with apps that have a file repository with named files.

* HAVE A SECURITY PAGE FOR YOUR APP. Have that page very cordially invite people to submit security flaws to an email address at your site; provide a PGP key for it. If I was maintaining a commercial app, I'd put a phone number on that page too. If you don't have this page, you should know that you are tacitly inviting people to report security flaws to Twitter.


>People will hate me for saying this...

Here comes the first pitchfork-bearer! Are there ready examples of what makes the usage of Perl a security liability?

By grouping PHP and Perl together, it seems like the security issue you're highlighting is websites made by inexperienced programmers. Perl is much worse than PHP in this regard owing to the fact that Perl's history of being used by people building their first website goes back further than PHP's does.

The last time that I recall Perl being in the news for security was in the first quarter of this year when they were patching up the DDoS vulnerability in Ruby and Python [1] whereas Perl and CRuby had addressed the vulnerability in question in 2004.

I would argue that at least since 2007 or 2008, that the Perl programming demographics have shifted significantly and that most restauranteurs and florists who are trying their hand at making a page for their SMB are using PHP. At this point I would venture that the fat part of the bell curve of the Perl web programming population would be systems administrators who venture outside the bounds of their automation scripting domain.

Given the stereotypical sysadmin, I would posit that they might tend to spend extra time and energy on security (in building some script-y spaghetti monstrosity).

1. http://arstechnica.com/business/news/2011/12/huge-portions-o...


> Are there ready examples of what makes the usage of Perl a security liability?

The `open` function used on untrusted input allows arbitrary code execution (I've gotten privilege execution via setuid perl scripts many times this way, as well as getting a shell on the box via web apps allowing this).

While there are many other common things I saw in real world apps, e.g. perl scripts using backticks for command execution and allowing me to run anything I wanted, the `open` one is by far the worst. It's insanely pervasive and incredibly easy to do.


The `open` function used on untrusted input allows arbitrary code execution...

... only if you use the insecure open form. The secure open form has been available and recommended since the release of Perl 5.6.0 in March 2000--twelve years ago.

People who write insecure code, when the language makes it just as easy to write secure code, are to blame for insecure code.


> People who write insecure code, when the language makes it just as easy to write secure code, are to blame for insecure code

We're not discussing who's to blame, we're discussing whether there's anything to assign blame for.


Can you name a practical language in which it's not possible, by default, to perform an unsafe operation with untrusted user input?

I can easily use Haskell's type system to disallow the use of UnsafeUserInput in my database abstraction layer, but that requires me to use my types pervasively and correctly.


The question is not whether it is POSSIBLE.


If your web application is opening and closing files based on user input, without checking them first, you have bigger issues. Blaming this on the language seems bizarre.


True but perl makes it amazingly easy to exploit.

Suppose that you know the source contains this line:

  open(file_handler, "$userinput");
How much work and what assumptions do you need to exploit this? In perl it's that easy:

  $userinput = "cat /etc/passwd |zenity --text-info |";
  open(file_handler, "$userinput");


> Suppose that you know the source contains this line

Then you have a massive damn problem, and you could set up the same strawman about almost any language - if you're starting from the premise that you are piping arbitrary user input to a system call unimpeded, all bets are off.

Shall we try some other examples? Let's say you accept input from a user, and dump it unchecked in to output shown to the user via Ruby. OH NOES! Ruby is insecure because it supports CSRF! Or, let's say you use Python and pass in input from a user unimpeded straight to the database without using the quoting mechanisms! OH NOES! Python is insecure because it enables SQL injections! etc etc etc

But wait! you say... Sensible programming languages have specific features to stop these kinds of attacks! And you're right. That's why Perl has taint mode... for when you're dumb enough to pass user input straight to open: http://perldoc.perl.org/perlsec.html#Taint-mode


I'm in no secret quest to stain Perl's reputation you know... Just illustrating how easy it is to exploit unchecked user input in the open() function. It just happens that this particular exploit is way easier in Perl than any other language I know.

Of course we should not extrapolate from this to make a judgment on the language. Of course it's nice that security mechanisms are available to alleviate this issue.


Do you usually try $UserInput $Userinput $userInput $user_input etc. when you do that?

It couldn't run your code if it had an uninitialized variable in it, right?


It's vulnerable because the user controls the content of $userinput, the variable name doesn't matter. Real code would look like this:

  #!/usr/bin/perl

  print "Enter filename: ";
  $filename = <STDIN>;
  open(file_handler, "$filename");
If you see this code, you know that you can execute any command by giving it at the filename prompt and appending a '|' character. For example giving cat /etc/passwd |zenity --text-info | will popup a dialog with the content of /etc/passwd.


Oh I see, I thought you were talking about something that would be caught by the interpreter if you put

    use strict;
and

    use warnings;
in there. Thank you for taking the time to put in an example, I understand you better now.


Those sound like two good leads, thank you!


"Use TLS to encrypt data in motion" It's also worth checking that whatever language/library you're using bothers to validate the cert (AND the hostname). Many (most even?) don't by default. You have to ask extra nice in order to get a secure connection that's actually secure.


> * People will hate me for saying this but I'm here to offer honest advice: prefer almost any modern language to PHP or Perl. I don't know what to tell you other than that PHP and Perl apps fare worse on security assessments than everything else.

If you're talking about copying and pasting formmail.php or .cgi from somewhere on the internet, sure. Beyond that, what exactly is the issue with Perl? Where are the security issues with Dancer? Catalyst? DBIx::Class?


Look: all things being equal, if

(a) you're just as happy in Python as you are in Perl and

(b) software security is very important to you,

I recommend you select Python. But: lots of people are much happier in Perl and should use Perl. In lots of companies, the best language safety net for security is not a key business asset, and this discussion shouldn't influence them.

I'm not saying that if you use Perl, you're doomed. If your best language is Perl, you're probably better off working in your best language, even where security is concerned.

That's all.


But you haven't said /why/, or given any examples, other than "Look! Perl! Security!", where other posters on this exact thread have shown a trend for Perl to have security holes fixed first.

If it's a hunch, or a gut feeling, or a prejudice, just say so. Otherwise, add content.


Not interested in adding more content about Perl to my original comment, sorry.


I'd also add: Remote timing attacks are practical[1, 2]. Twitter as target of it in the past[3].

[1] http://crypto.stanford.edu/~dabo/abstracts/ssl-timing.html

[2] http://codahale.com/a-lesson-in-timing-attacks/

[3] http://scforum.info/index.php?topic=4358.0


This is a great list.

I'd add some of the relevant things from security strategy over the past 20 years, like "log lots of stuff".

There are many things which help availability (backups, easy deployment, tests, etc.) which also help security. If it's relatively easy to push an update, it's a lot more likely that you'll be able to rapidly respond to a vulnerability, or will have pre-emptively updated away from a vulnerability.

The most interesting things I've found recently have been in the "we can't touch that because we both don't understand it and because it's not working" parts of a complete site.


The "stay on the golden path" rule is unrealistic except in corporate Java environments. It will conflict with other more important focus points than security: disruption, be faster than competition, do things thee hard way, etc. (All things well described in pg's essays).

I would require all devs to read OWASP and make sure they understand the core, then they can tweak in, hopefully knowing what they do.


"* I have more than once recommended that people who are very very concerned about platform security (ie, about the likelihood that there are memory corruption bugs in their language stack) use JVM languages."

I thought general consensus was to stay away from the JVM if you mind about security. Isn't that the case anymore? or never was?


There's a general consensus to avoid clientside Java.


I would add this to the suggested reading list:

https://wiki.mozilla.org/WebAppSec/Secure_Coding_Guidelines


I've found this list really valuable.

I believe that there are two main security objectives while designing a new system: one is to protect the system itself against attackers, another one is trying to limit damage (especially data exposure) in case an attack actually happens.

Nowadays I think the first one is a must... from this point of view I wouldn't say it's important to check user input... it's a must! (while building a system, I don't usually think how can I check user input, rather how can I assure that my system will always check user input).

But since we can fail, the second objective is really important too and many design choices should really be done with security coming before functionality.

A simple example is password storage. The guidelines are good in pointing to bcrypt (another fine solution is pkcs5), but often just a hash function is used (sometimes even md5 that we can no longer consider a robust hash) or the salt is replaced with something which is not random (e.g. timestamp). These bad design choices could lead to easier password recovery.

Another aspect that I try to enforce in my neighborhood is protecting sensitive user data at least with user password. Of course this requires the user to enter her password every time the data must be accessed, but often this is already the case (think to a payment, wouldn't you ask the user for her password before doing it? So why her payment data shouldn't be protected?)


I think it'd be interesting to highlight some vaguely security-related measures that might make it less simple for attackers to shut down your site just by using it normally. I'm not so sure it's relevant to the SO question, mind, as it's more in line with optimisation than anything.

This might include:

* Using a caching layer to store and re-use the results of complex, infrequently changing queries, instead of querying the database on every request.

* Using a message queue to handle the processing of certain things in the background. If you have an upload form that then manipulates or processes the file in some non-trivial manner, add it to the queue. The queue can drop messages or jobs if it gets too big.

I only say this having developed some projects where holding the refresh key down for a few seconds on pages with lots of queries (along with the hundreds Drupal makes anyway) could crash MySQL. As could using a separate form that sent emails and processed images on-the-fly.

Best not to present attackers prime opportunities to DOS your site.


Interesting! :)


http://www.behind-the-enemy-lines.com/2012/04/google-attack-...

Interesting post which showed how badly configured linkages between private google docs and S3 caused an accidental DoS.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: