Intelligence is not the ability to store information but to know where to find it.Albert Einstein
Information is everything. In times when face to face interactions are reduced to minimal, all that is needed to verify identities is information like date of birth, place of birth, public health card number, details of emergency contact, phone banking pin etc. Such information can be obtained through unprotected systems and unsuspecting users.
Which is why we need to focus on the privacy of the users that visit/use your applications.
Once it is on the internet it’s there forever, it is a very popular saying because it is very true. So with that we need to realise the importance of securing our solutions/architectures.
But what are we protecting?
- The contents within your solutions like privileged content for a subscription based service.
- Copyright/Licensed Data like images, videos, Intellectual property that you pay for or produce.
- Personally Identifiable Information (PII) of your users can result in identity theft. If you are providing a service on the internet, you are responsible for making sure that your viewers/customers/clients have a secure experience and can trust you!
- Banking and payment information. Do you guys shop online? Of course you do. What is the one thing you check before making a payment using your banking or credit card information? Would you pay for products on an insecure site?
- Credentials and login information. Most people on the internet use the same login credentials for most of the websites they use. If your application is not securing that information or has vulnerabilities which can result in third-parties obtaining that information then you are putting your users at risk that they aren’t even aware of.
The above list is just a subset of the information that goes on the internet.
Be security aware, Make informed choices.
The options and approaches listed here are not exhaustive, but they would help you get started on your journey to building secure development and deployment practices.
Principle of Least Privilege
Never run as root user! Web server, application server, database server, containers nothing.
While building services, it is very important to define interactions between services. This can translate into building private methods, not exposing attributes of objects if they are not needed.
Application Level Access Control.
Define access levels and build an access control mechanism in your workloads. Interface segregation as best practice.
- As a best practice use interfaces to enable interaction between services rather than direct interaction between components.
- You can use an authorization mechanism between services to ensure that the level of interaction and data access between services is restricted to what they need to function.
- You can either choose to build an authorization mechanism or use third party vendors. I’ve seen JWT (JSON Web Tokens) being used fairly extensively.
Database Level Control.
Ensure only the application interacts with the database. Remove human intervention with the database based on long lived credentials completely.
- In terms of protecting your database ensure all the interaction comes via the application layer. Reduce human interaction with the database to the minimal, or even remove it altogether.
- How do you run deployments/migrations, you ask? Use the connectivity from your application layer. Create context specific users with proper privileges using GRANTS with a relational database model. For NoSQL databases you have the capability to add plugins that can help in identity and access management.
- For deployments, ensure your deployment user has restricted privileges as well to only perform the tasks relevant to their role.
With access control mechanisms its very important to ascertain that the level of access that is intended for the systems is what the system has in reality as well. So make sure you test your access control as well.
There are multiple ways to provide passwords to applications.
- File based password storage. Use file permissions to control access to the password file. Encrypt the password before you put it in the file, you could even encrypt the file as well. Configure the application user to be able to read the file, decrypt the file and the contents.
- Centralised password management. Use password management tools like
AWS Secrets Manageretc. You can self host a vault server or
container-iseit or use a managed service.
- Rotate your credentials. Make sure you use short lived credentials. Set a rotation cadence.
Who can interact with what and how?
The WHO is the requesting application/user/IP range.
The WHAT is the type of request - GET/POST.
The HOW is over network interaction - TLS/HTTP.
- Host/Resource Level Firewalls. Using
firewalldyou can regulate network level traffic for the hosts where your applications and/or data based are hosted.
- Controlled access to third party vendors. Its very easy to be able to inject vulnerabilities in your system if you do not define which third party vendors are trusted and use proxy services like squid to ensure opening traffic only to trusted vendors from within your network.
- Secure Transport Layer. Make sure your endpoints are secure. Use TLS certificates to secure data in transit. Redirect all traffic to TLS enabled endpoints rather than HTTP. Consider encryption at rest for data stored on disk like virtual machine disk, database server, backend in-memory cache etc.
Change Review and Testing
The first element of change is awareness. You can’t change something unless you know it exists.
T. Harv Eker
The journey of a change from commit to production should not be without peer reviews and tests, preferably automated.
Peer Review/Code Review/Pairing. Ensure a change is a brain child of more than one individual contributor.
It brings diverse perspectives to the solution and also helps avoid creation of knowledge silos during events. It also helps mitigate a single malicious actor type scenarios where a single human can instrument a change on purpose to enable a breach/data loss.
Testing. Impartial assessment of the application.
Testing frameworks (used properly) and testing scenarios (written properly) ensure detection of variants from defined application posture. When such tests are injected in the change management workflow like your continuous integration/deployment pipeline, you are able to measure the security stance of your application through test pass and fail metrics. You can also track code coverage to make sure you are testing all business logic and integration for your application. Various levels of testing assert various components like integration testing for third party components, unit testing for code level coverage, smoke testing to ensure the application is reporting healthy etc.
What is a vulnerability?
It is a weakness in the system’s security construct, architecture, network or software that can be misused by a third party to gain control over your system by crossing a privilege boundary. This can result in unintended information exposure.
The below articles serve as a reference of the ever increasing number of vulnerabilities.
According to the above article, more security vulnerabilities were disclosed in 2020 (18,103) than in any other year to date – at an average rate of 50 CVEs (Common Vulnerabilities and Exposures) per day.
* 57% of those were classified as being ‘critical’ or ‘high severity’ (10,342).
* Low complexity CVEs are on the rise, representing 63% of vulnerabilities disclosed in 2020.
* 70% of vulnerabilities expose a network-based attack vector.
* Vulnerabilities which require no user interaction to exploit are also growing in number, representing 68% of all CVEs recorded in 2020.
According to the above article, the attack was approximately a 44% larger volume than previously detected events. The attack was carried out using Connection-less Lightweight Directory Access Protocol (CLDAP) servers that are known to amplify DDoS traffic by 56 to 70 times its initial size. The prior record of
1.7 Tbpsoccurred nearly two years prior.
This data highlights the need to keep your workloads up to date with package versions and vulnerability free.
- Create a regular patching cadence.
- Use vulnerability scanner tools to find CVEs and remediate them.
- Treat servers as
cattle not pets, consider not running long lived servers.
Some Tools That Can Help
Retire.js: The goal of
Retire.jsis to help you detect use of versions with known vulnerabilities.
Drek: A static-code-analysis tool that can be used to perform security-focused code reviews. It enables an auditor to swiftly map the attack-surface of a large application, with an emphasis on identifying development anti-patterns and footguns.
Bandit: Bandit is a tool designed to find common security issues in Python code. To do this Bandit processes each file, builds an AST from it, and runs appropriate plugins against the AST nodes.
Safety and Safety DB: Safety checks your installed dependencies for known security vulnerabilities. Safety DB is a database of known security vulnerabilities in Python packages. The data is made available by pyup.io and synced with this repository once per month. Most of the entries are found by filtering CVEs and changelogs for certain keywords and then manually reviewing them.
Third Party Libraries
npm-audit: The audit command submits a description of the dependencies configured in your project to your default registry and asks for a report of known vulnerabilities. If any vulnerabilities are found, then the impact and appropriate remediation will be calculated.
Dependabot: You can can enable
Dependabotalerts by enabling the dependency graph and
Dependabotalerts for their repositories. It’ll then alert you on vulnerabilities.
Synk: Detailed information and remediation guidance for known vulnerabilities.
There are many more based on your language of choice and framework. Choose wisely!