I know SQL Injection is one... what are the others...
Buffer overflows are the classic if you're writing C, as they often allow the execution of arbitrary code by an attacker.
This is for web stuff but since you left it open ended...
JavaScript injection. If you allow any input from any source that's being outputting somewhere JavaScript could be typed in the input and then when it's outputting (unless properly encoded/decoded) it will output the raw javascript.
Never store plaintext passwords, either. (I can't tell you how many commercial packages I've evaluated for my company which did -- and then acted nonchalant about it when I called them out. My favorite excuse, from a CRM vendor: "Will your end users typically have Enterprise Manager or Query Analyzer on their desktops?")
how about verifying user input? For example, you're expecting a 10 digit phone number, but you get "800OHNOES!"
Here is a list of Top 10 Secure Coding practices. It is as good a start as any. Consider #8, Defense in Depth, in particular.
Massage and filter ALL input to your program before processing.
Never process input without filtering and truncating.
-R
You could consider the chapters of this book to be a pretty good checklist...
this is a vast topic, these are blogs/forums to watch
http://www.testingsecurity.com/
http://www.gnucitizen.org/categories/blog/
http://blog.watchfire.com/wfblog/
Simply program defensively. For each function/method/procedure/subroutine consider "What is the expected input? What do I do when the input deviates from that? How can I most easily ensure that the input will not deviate from that." Know your input; know your output. Don't go overboard, but also understand that data in a database might have been compromised. If a particular set of data can be constrained in some particular way then select your data types and variables to play to that. Keep numeric things numeric.
Whenever I see a String object in a program I facetiously ask "What would happen if this string contained the lyrics to Gilbert and Sullivan songs?" Simple if-else checks and premature return statements at the beginning of a function can prevent that sort of thing from wreaking havoc later.
Others have said this, but...
Essentially all security vulnerabilities come from data. If your program doesn't process any data it's likely to be secure. It's also likely to be pretty useless :).
That leads to what I think is the core concept of making code secure:
Don't trust your data. Ever.
Sanitize everything you possibly can. You can rely on the security guarantees of your platform (for instance, it's highly unlikely that you'll see a classic string based buffer overflow in a managed language like Java or C#), but otherwise you need to validate everything that comes into your application.
In addition to the wonderful guidance on OWASP, also check out the SANS/CWE.
I like to model my system with Threat Modeling Tools. This particular one lets you model different applications and gives you all types of information about what types of threats are applicable based on the model as well as some mitigations and their risks. It also let's you track these risks throughout the dev. life cycle to come up with mitigation plans. It's pretty cool. :)
I second the recommendation for: 19 Deadly Sins of Software Security
It isn't just a checklist, read it to understand many of the aspects of software security. Some are broad items, that let you understand the reasoning behind many of the different security issues.