Your startup finally managed to win a big client, but they ask you to go through a security audit first?
How a security audit works
For most big corporates, making sure their suppliers fulfill basic security best-practices is mandatory. After all, if their suppliers work with personally identifiable information of potentially thousands of employees, or might get to know their trade secrets, not accidentally leaking this data to anyone is very important.
This is why most corporates have a standardized audit they do before new suppliers are allowed to deliver their services. Normally, these audits start right after winning a new deal — you would get a good old Excel spreadsheet with 100+ general questions to first assess what kind of company you have (e.g. cloud-based or not, type of service, country, and much more) and what kind of data you deal with (e.g. personally identifiable information, like names of employees, email addresses, or even just IP addresses).
Most of the time, these spreadsheets contain just general questions to first determine what the necessary steps in the following audit process are. For instance, if you are not hosting anything in the cloud, there is no point in making a Cloud Risk Assessment; and as your customer is paying for the whole and costly audit process themselves, they are keen on not doing useless checks.
Questions asked during an initial interview
- Where is your business located, your mother company, your investors?
- Who are your suppliers that may have access to your code and data, and where are they?
- What service do you provide?
- Where do you host your services, e.g. in a Swiss data center, a cloud service of a US-American company, …
- What kind of data do you work with, e.g. do you require social security numbers, bank accounts and a user’s religion, or do you need email addresses?
- Do you have backups of your data and plans for recovery?
- Which certificates do you and your suppliers already have, such as ISO 27001, HIPAA?
- Are data related to a tenant separated from other tenants, e.g. in a separate database?
- Do you do background checks on your employees?
- Do you use MFA for your administrators?
- Do you ensure that changes to your app are reviewed and can only be done by a limited number of people?
- Do you keep audit logs of logins and actions done by administrators?
As you may already be able to see, the questions start very generically and then drill down, so that auditors can get a brief overview of what your company is doing and hence what kind of data your company would potentially deal with.
A messaging service where employees could potentially leak trade secrets would get a much closer audit on its data flow and storage facilities than a service that is used to show the company’s news from an existing PR feed.
The longer the sheet gets, the more specific the questions become; and often, you will find questions tailored to development and operations processes, such as who can make app changes (and whether they are reviewed), and how you ensure that the number of people with access to the production database is limited and audited.
Often, you are granted a couple of weeks to answer the questions, but are also asked to add further documentation and diagrams — such as an architectural diagram showing the data flows and resources needed (e.g. to figure out whether your data is encrypted in transit, stored in S3 or not, …).
Depending on your client, they then might follow up with at least an interview to clarify your answers, and potentially ask for external penetration tests or reviews of your code.
How to make sure you pass an audit
1. Don’t lie, and be concise
Lets start with what should hopefully be obvious — don’t lie and try to answer every question as honestly as possible. As most auditors do security audits on a full-time basis, they can easily spot when you are making things up; either because they learned to be good at reading people or because they will just be checking if you said the truth (e.g. by doing pen tests).
Some people do not lie during an audit, but tend to not stick to the point — to steer auditors away from ‚bad‘ answers, or because the anxiety makes them feel like they have to say a lot.
Instead, just keep in mind: Not having something properly set up is not canceled out by something else, and there are no bonus points for overachievements in one area, just follow-up questions, confusion or a lengthier process because somebody has to read all your answers.
If you are unsure about an answer during an interview, just say so and get in touch with your developers; and if the auditor asks about something you don’t (yet) have implemented, it’s also perfectly fine to say so. It might even speed up the whole process and give you more time to fix things (or the client might not even care about what you think is an issue).
Security audit results are not black and white and not passing everything flying colors doesn’t mean you failed and will lose the client — getting caught in a lie however greatly increases your chances of damaging your reputation for the next years or even becoming blacklisted.
2. Have ‚big picture‘ diagrams handy
Unlike when being certified, most auditors don’t expect you to have or create formal process diagrams; however, there will be three key elements auditors will want to understand, ideally by looking at nice diagrams.
To get acquainted with what you are doing, they will first try and see an overview of your app’s stack. You should take the time and could even use a free service like draw.io to create a simple overview of your app’s services and how they are connected, (e.g. a few boxes for your frontend(s), backend(s) / services, data storage services like MySQL/ElasticSearch, CI tool, IDE).
It doesn’t need to be overly detailed; but there should be enough services and tools depicted to be able to describe how new code find its way onto production, as well as what services are in play when a customer or administrator uses your app. This will help greatly during an interview, should one become necessary.
Aside from the stack, an overview of the actual infrastructure will come in handy. Often, auditors try to determine where in the world specific databases are located, which cloud resources are being used, and whether data is stored redundantly. This is best determined by simply making a diagram of your cloud or data center resources; here too it’s not about being overly detailed, but about helping to understanding the main concepts, resources used, and being able to go into further detail if being asked to do so.
Lastly, auditors will try to understand the data flow of your application, and will potentially even themselves create a diagram or sheet explaining how the data flows through the application (as this is often an artifact required by the auditor’s customer). This will be just a spreadsheet listing who the users are, what data they are entering, where the data is processed, where the data is stored, and who accesses the data; for every use case they can think of or for whatever use case the audit is being created.
These documents will then be the basis to just go through all possible workflows (depending on how thorough the auditor is) and try to understand what systems are affected on your end, so that the right questions can be asked (e.g. no point in asking about your VPN if you do not have systems other than a S3 bucket).
3. Use VPN, SSL, private keys, audit logs, don’t share user accounts, manage secrets properly
One of the very basic but key elements of an audit is to ensure you have a full audit trail of who accessed or changed what on a per-user basis, and that there is no way around it. This applies to both your app’s code, as well as the production data.
If you do not share (admin/dev) user accounts, have a Git repository, a deployment pipeline, and its logs, you already have covered most of what is needed.
Just make sure you are also using a VPN, SSL everywhere, and do not share your secrets but use tools like Ansible Vault or AWS Secrets Manager. This ensures your audit logs do not become useless because everybody could log in as anybody else or become a victim of simple man-in-the-middle attacks.
Ideally, your administrators and developers also use two-factor authentication, and changes to user roles or settings are audited, so that even if somebody gives somebody else too much access, it can be reviewed.
4. Check for vulnerabilities in your images, containers, dependencies, code, and double-check
Nowadays there are quite a few tools to automatically check for vulnerabilities in your dependencies or code, so there is little reason to not have them implemented.
Auditors will want to see at least static audits of your code, ideally even dynamic audits (e.g. XSS vulnerability checks, CSRF). The static audits can be implemented easily in most programming languages, and should be accompanied by audits of your code’s dependencies in your CI.
But aside from auditing the dependencies of your code, you also need to think of all other dependencies your app has; for instance, if your app is Docker-based, then likely you will want to implement something like Claire.
Finally, you may want to think of using intrusion detection software, like aide, for your operating system, to make sure the system you are checking is actually the system you have deployed and not changed by an attacker.
To make an auditor and your customers very happy, make sure these tools are all part of your CI pipeline so that they are not run manually every full moon, but instead are a mandatory part of your workflow.
5. Keep your OS, software and dependencies up-to-date
To make sure your stack doesn’t just accumulate security issues over time, it’s essential to keep it updated. This starts with the OS of your docker host, the OS inside your containers, any dependency you install there, as well as dependencies installed by your package manager, as well as any development tool you are using.
Nowadays, keeping everything up to date is quite straightforward thanks to tools such as Greenkeeper, Renovate or other tools, depending on where you host your repository. The tools are checking your code against docker hub, npm registry, etc. and can open a new pull request for every update found, making it simple and straightforward to test and release an update.
6. Don’t implement password hashing, encryption and other security-related tools yourself
Unless it is your business, do not implement security-related features such as the hashing of passwords in your database, or the encryption of files yourself, but use existing, battle-tested, open-sourced tools to do that, or the built-in functionality of your programming language.
More often than not, security issues stem from not covering all edge cases, not thinking about memory overflows, not worrying about the compiler’s quirks, or other non-intuitive issues that have all been solved in existing libraries and are hard to re-implement on your own, especially as there likely is no reason to.
When hashing passwords, most security auditors will be happy to hear that your passwords are hashed with a salt, which most programming languages can do out-of-the-box (e.g. password_hash() in PHP) using one of the safer hashing algorithms like bcrypt.
Ideally, to also tick off boxes related to password policies or brute force attacks, try and use an existing user registration and authentication service, such as Firebase, Auth0 or AWS Cognito.
Auditors will ask you about how often users (and your employees!) need to change their passwords, the minimum password strength, and the number of failed attempts allowed, so to make sure you don’t have to develop all of this yourself, try to use an existing library.
7. Encrypt at rest and in transit
All of your services should redirect to HTTPS and not allow any HTTP traffic; additionally, you should make sure that every storage is encrypted also.
Depending on your needs, this doesn’t even have to be very complex — most managed Cloud services already offer basic encryption that can simply be enabled without changing anything on your platform (which is then using a Cloud account-specific encryption key), such as AWS Aurora or AWS S3.
For more complex scenarios, you can use your own keys and still have a solution implemented quite easily without decreasing your performance / increasing your bill too much.
8. Keep in mind you also have offices, paperwork, and server locations that need to be safe
Last but not least it is worth mentioning that audits are often not limited to the digitial world. Most audits cover whether you have a clean desk policy to ensure no important paperwork is laying around after office hours for anyone to see; whether you are storing important documents locked away; whether only a limited list of people can physically access your servers (if, at all) and offices and so on.