For those of you who have to review unusual platforms, here are my notes for reviewing apps coded in Apex and Visual Force. As I learn more, I might add some additional entries, but I’ve been so constrained with time for so long, don’t hold your breath.
Terminology and Basics
Force.com is Sales Force’s SAAS API for ISVs and customers to write custom CRM apps atop the Sales Force platform. To provide some serious platform lock in, they use a new strongly typed language called Apex. Apex is sort of Java based. Java programmers will be somewhat familiar with its capabilities, but it has some surprising differences. As a reviewer, there’s nothing really head hurty when reading the code, but it’s important to realize it’s not grandpa’s Java you’re looking at.
Some things you’ll come across:
Meta data. You’ll see code with associated XML files. This XML data has a lot of stuff going on that describes it and allows Force.com to correctly handle it, particularly static resources. You can’t just ignore meta data – you need to inspect it.
Visual Force is a MVC based framework. It appears to act like a tag library with the <apex:… prefix, used inside files with a .page extension. These mimic the traditional type 1 JSP model. I think most of you will be familiar with this model and will not have too many difficulties in reviewing it. However, there are some asynchronous AJAX helpers (timers, future events, etc) that you will need to be aware of, particularly in relation to race conditions.
Objects. Sales Force have defined an object interface over their CRM data model. This has some interesting gotchyas, in particular, queries across these objects is called SOQL, and is pretty much a semi-injection proof sub-dialect of SQL 99. There will be an entire blog post for those issues primarily as there’s several ways code can be written to be unsafe.
Triggers. Triggers are executed after users undertake actions within the public site / sand box application. I need to learn more about them before I write about them, but they are the start of the flow of execution after the user does things within the application. If you have custom classes, they are generally called by triggers.
Bulk importer and Batch Apex. ETL support. I need to learn more about this functionality before I comment.
Flash and Flex support. Just in case some of the options weren’t scary enough, you can implement your presentation and business logic in a client side language. Sweet. I will not document Flash / Flex support as a) I hate Flash and have it disabled b) I have yet to see such code in action and I hate slamming or praising things I’ve not used. c) I don’t have any Flash or Flex tools to build test cases, so it’s going to be hard to nail this one down. Feel free to steal my thunder here if you so desire.
Web Services. These are traditional SOAP web services. Instead of using WS-Security, Sales Force have implemented their own session manager. Probably a good idea since no one besides Gunnar Petersen understands WS-Security. However, we all know that web services can be a mine field, so I will experiment with them and see how things work in a much later article.
Some things they did right
Please don’t take my tone for disparagement, for it is not. There are some cool things Sales Force did right:
- Everything is escaped by default. You have to add code or an attribute to get this wrong.
- CSRF protection in every form. You have to do the wrong thing to be CSRFable.
- The easiest way to do SOQL is sorta magically injection proof. There are injectable ways, but again, you have to work at it.
- Many defaults chosen by Sales Force are good – SSL by default. Yay. SAML by default for SSO. Yay. GET and POST only. Yay. UTF-8 only. Yay. UCS-2 only. Yay. Illegally encoded Unicode characters are replaced. Yay. Content Type is safe unless you do the wrong thing. Yay.
- Sending cookies or headers are escaped. I’m not sure they’re properly escaped yet, but they are escaped.
- To promote code into production out the sand pit requires at least 75% test coverage. O.M.G. YAY! Tests are also not counted towards billing. There’s exactly zero reasons not to test your code.
This is but a part of the overall list of goodness. But that doesn’t help you figure out how to secure code review things yet.
The trouble for secure code reviews is several fold:
- There are no static code review tools to review Apex code. This is a serious deficiency that will only get worse if others try to emulate Sales Force’s success in crafting an entirely new language and API for their SAAS offerings.
- The security documentation is relatively sparse, and only gives hints as to how to shoot yourself with XSS, CSRF, SOQL, fine grained access control and other issues. This series is an effort to break through that and provide more documentation.
- There is a tight coupling between the code in your IDE and the sand box / public site. If you break this nexus, you do not have configuration data. With Sales Force’s “No code” logo, they hide some code and configuration from you. So expect to ask for the login and hope it’s not production.
- Sales Force have given a lot of thought to security, and many common Java issues are “fixed” or safe by default. But as Apex is a serious systems language, it allows you to shoot yourself in the foot. I don’t know yet as to the extent of it, but I will find out with some luck.
If you’re from Sales Force, please don’t worry. I’m not about to give away 0days – I am not a weak minded moron who delights in creating grief with no solutions. This series will be primarily about how to review Force.com code, followed by advice on recommendations for “fixing” it. Which is most likely to be “Do it how Force.com told you to do it in the manuals”.
4 thoughts on “Force.com secure code review howto Part 1”
If you haven’t seen it yet, please check out http://developer.force.com/security. It contains a myriad of Force.com Secure Cloud Development resources, including secure coding guidelines, the force.com esapi library, training, quizzes, etc.
Additionally, you’ll see we offer a free on demand source code analysis tool for all of our partners and developers. It has been a great success at identifying potential security and code quality issues.
We look forward to any feedback from you on how we can improve.
I realise that APEX does not use sigils for variables, which makes it very hard to write decent rules for it, but I feel that one of graudit’s strong points is how quickly you can create a signature set for a custom language be it API, templating or something else.
It’s no replacement for a real in-depth static analysis tool, but it might be a place to start.
I’m hoping you will approve the comment above as I want to ensure the developers on our platform know these resources are available to them.