This all depends on how you view PCI compliance. If you view it from "check the box and be done" viewpoint which many companies do but I highly disagree with then a Web application firewall is suitable for PCI compliance. It's easy to install -- set in watch mode and check the box and move on. If you actually care about security and doing what I would call the "right thing," then in the best setup both WAFs and code review are the answer.
Code review is by far the most comprehensive solution, but is also the most tedious and difficult to apply. Solving the problem at the code level solves the issue at its core. Vulnerabilities are really code defects with a higher impact. Solve these issues like you do with defects and your application will become more functional and secure.
What I recommend for WAFs is that they are a great example of "defense in depth." WAFs usually work very well for small websites that are static. However, they start running into problems when you're dealing with large, complex, changing Web applications that run a lot of dynamic code (Web 2.0 or 3.0 -- whatever it is).
If your code is secure then applying a WAF on the front is a nice boundary of protection that helps battle the majority of simple Web hacks. And since you also fixed your vulnerabilities in your code...if the hacker finds a way past that WAF they run right into a dead end.
So, it's hard for me to tell you what is best as I don't know enough about your company. I will assume that small is 50-100 people and since you are worried about PCI you must be running a website that accepts credit card numbers. If this is the case my recommendation is to do a few things:
- Identify where your risks are. Knowing where your problems are is top priority. Use a product like WebInspect or a source code analysis tool such as those from Fortify or Ounce.
- Measure out where your top three critical risks are. Figure out how best to remediate these (code, configuration, WAF) and implement ASAP.
- Implement a WAF (get the checkbox) and have it start protecting...
- Start working with your development organization to figure out a way to implement security throughout the software development lifecycle (DO IT EARLY! While you are small). This does not have to be that complicated. Make it simple for them at first. For example, policy development rule number one is "You must validate all input with a whitelist." Leave it at that and get them used to the new rules.
- Start assessing your Web app on a regular basis so that you can see if all your hard work is actually paying off. Do you see vulnerability counts dropping over time? If not, you have more work to do.
This may sound like a lot, but remember that the Web app is your front door and this is where all the risk is these days. Network security is the 90's. The Web app is today.