In my web agency, we had several projects where we had to perform codebase audits. It can be tricky to audit a codebase and each entity produce customised answer to their problem. It can be troublesome to find a tool which give good results in all cases. A large part of each audit is tailored to suit the need. But here is some common rules I found…
We can look at the codebase from two points of view which can be really different:
- from the technical perspective: use of development best practices with a particular sensitivity to performance, security and quality issues
- from the functionnal perspective: correct implementation of the features and according business practices
These two aspects can be analysed by different tools and we will get back to it shortly. Note that they are not necessarily correlated. Beware not to spend all your energy on solely one of this two points or you could miss critical parts.
Before analysing the first line of code, you need to inspect the context in which the application has been built and in what purpose.
You need to answer these questions:
- What is the context of this audit?
- What is the context of this app/website/software etc?
- What is the context of the technical team in charge? How about their technical knowledge? Can you assess it?
- What is the company culture?
- What are their constraints? (security, high volume traffic, short deadlines)
- What is the technical stack used?
Having answers for all these questions, you should be aware of what you are looking for and maybe where you should be extra cautious.
Before testing/analysing your code, you also need to ask yourself what is their workflow:
- Is this an individual work or a team work?
- How do individual/team communicate?
- At what speed the code is delivered?
- Do they have a particular workflow to deliver code (versionning, CI/CD)?
- How are the team organised?
- With what methods?
In some cases, these answers could be pointless but they can raise some interesting facts and give hints on places where you’re more likely to find flaws.
Enough about context and questions, let’s look at the code.
I like to give the code a first quick look. Just a sniff to get its smell. I look for a README
, INSTALL
, docs/
, I looked at how the code is organized and what seems to be the main parts.
From this glance, I try to answer the following:
- Is the installation easy to do and reproduce? Is the process easy to find and understand? Is it even documented?
- Does the project provide documentation? Does it need some more?
- Is the code documented via comments?
- Are they any tests? (unit, integration, end to end…)
- Is it easy enough to quickstart and use it right away?
- Is it easy to modify?
- How would I rate the complexity of the application?
The first feeling you get with 5 minutes spent on a code can answer most of these questions. I try to spend some more time then to confirm or answer more precisely these questions.
Before going deeper, you can check some security concerns:
- What are the dependencies of the projects? Which versions? Do they have known security issues? Is it up to date? If not, is it on purpose? documented?
- Are good practices followed (classic ex: a flawed authentication or a missing https)
Once you’ve done that, you already know quite well what you’re dealing with and you may want to check some particular features, modules or part of the code yourself a la mano.
To give metrics and provide a summary without leaking any emotional judgement, a lot of tools can make your life easier. Let’s list some of them:
- Static code analysis (format, technical debt, complexity, code duplication, accessibility) can be achieved with sonarQube, OWASP
- Stress tests (example: locust)
- Performance analysis (you can check the number of queries, the TTL, the size of the app etc..)
- Dependency and legacy analysis
It would not make any sense in an audit report to argue for one format use against an other. But if no format can be found in the documentation or in the tooling and is inconsistent through the code you need to audit, it is fair to assume you can expect regular format or standard suggestion to be respected. (ex: pep8 with python)
Sometimes, we fall into a rabbit hole reading heaps of lines of code. If that’s the case, it can be a good thing to try to do or answer the following:
- Focus on high level questions first
- Spot the core business feature and/or the most used features
- If it should be rewrite from scratch, how should it be done?
- Split maintenance and code rewrite/refactor
- If no test is provided, what should be tested first?
- Define a plan to migrate to a new solution if need be
- Test the documentation
- Be aware of the technical sacrifice you may need to perform to achieve any recommandation you may have. Sometimes, you need to find a balance between quality, performance, readability, ease to maintain, time to produce etc…
Following all these advices and with the correct set of tools, you can quickly get a small report with a good overview of the code. If no flaw can be found, it’s a good first sign. More work could be needed to confirm this feeling or to find some nasty bugs.
If you have any tools to recommend or different methods to audit code, I’m all ears!