Hashrocket has a thorough and well-structured code audit process. We evaluate code history, bootstrapping, architecture, value of tests, code clarity, security risks, and any area of concern a developer might encounter. Depending on project size, it could last from a couple of days to a week – and the client will come away with invaluable insights into their product.
We gather information about historical development of the application by the structure of classes and modules. From this we can get an idea of the developer's intent.
We comb the project's Git history (if available) and check for:
- Concise and descriptive commit messages
- Large unrelated commits
- Commented-out code
- Unnecessary blocks of comments
During the lifetime of an application, new developers are brought onboard and they will need to set up the project. The first thing we try to do is start the project, even before we try to run the tests. If it's difficult for our team of experienced Rocketeers, it could seem impossible for a green developer. Large projects have many moving parts that need to be configured for a development environment.
Here are some questions we ask:
Are there instructions in the README? This is basic, but you'd be surprised how often the answer is 'no'.
Do any of the following need to be configured to run the application, and how difficult was it to set up the following?
- Database connection
- Worker processes
- Full-text search server
- Redis (computed property cache & counters)
- Creating a development user account
- API keys
- Deployment keys & configuration
Ideally, there should be an example database configuration and instructions in the README about how to create the database, run migrations, and populate seed data. Additionally, we look for configured Foreman or Rake tasks to start external processes and include instructions. Really awesome projects have a bootstrapping script to quickly get up and running.
When all of this is accounted for, we ask ourselves: how confident we are that the development environment is set up successfully? Smoke tests are a great way to know that all dependencies are working and that the application is running correctly. However, they are rarely seen in even very mature products.
Code Climate offers excellent information about the quality of your code. Sometimes it's hard to know what to do with those stats. Hashrocket does more than just code metrics – we suggest solutions on how bad code may be refactored, and how those solutions effect the overall architecture of your application.
You'd be hard-pressed to find an area so poorly defined as security. Furthermore, you'd find it equally difficult to find an area so important. There is no portion of the code audit process that has implications so directly tied to risk and loss. Problems here carry weight that directly effects your wallet – and more importantly, your users' wallets.
Web applications by nature touch myriad technologies that have exposures at different rates. The best thing we can advocate is that you keep your dependencies up to date as much as possible.
We also look into the following troublesome areas:
- Cross Site Scripting (XSS)
- Cross Site Request Forgery (CSRF)
- Unsanitized user inputs (database injection, evals, etc)
- Plain text passwords
- Tracked production configuration (Environment variables)
- Insecure API actions
- Tracked private keys
The above areas are typically more the result of programmer oversight than the result of the framework being out of date.
(You can view a more detailed list of potential security vectors on the rails security page.)
Do the tests actually test the behavior of the system? Tests (integration and unit) should test the behavior of the system without testing implementation. In many projects, it's easy to find a unit test that tests a private method that is never used. Test like these are useless. Also, tests that check an implementation of a method are also useless. Good tests treat the system like a black box: for input A, expect result B. This allows the system to be changed easily without changing tests.
Proceeding with development
Given the information we obtain during a code audit, we can advise on the development process, testing and code quality – and we can also give time estimates for rewriting vs. refactoring problem areas. Clients come away with a comprehensive document that shows them where their project currently stands, and helps them find a way forward.
photo credit: ondral on Flickr