What is OWASP?
Let’s start with who OWASP are. The Open Web Application Security Project (OWASP) is a nonprofit organisation dedicated to improving software security. One of its main contributions to the community is the OWASP Top 10, a regularly updated report outlining the most critical web application security risks. The OWASP Top 10 serves as a standard list for developers, and security professionals, helping them prioritise and mitigate the most prevalent threats faced by web applications. Here’s how OWASP introduce themselves
“We are an open community dedicated to enabling organizations to conceive, develop, acquire, operate, and maintain applications that can be trusted. All of our projects, tools, documents, forums, and chapters are free and open to anyone interested in improving application security.”
Why should we care?
I imagine if you are here reading this on Skrift then you likely work on web projects, so this list of web security risks is relevant to you. No matter your role in delivering software products or digital customer experiences - as developers, designers, testers, project managers or any other role on a project, it’s important to consider security in everything we do. A failure on security can lead to risk of exposing data as well potential reputational damage.
The “Top 10”
The “OWASP Top 10” is a list of most critical security risks to web applications from several perspectives including prevalence and severity in real world scenarios. First released in 2003, there have now been 7 updates, with the most recent being released in late 2021.
“The OWASP Top 10 is a standard awareness document for developers and web application security. It represents a broad consensus about the most critical security risks to web applications.”
Let’s have a look at the top 10 in more detail. Where possible I have sprinkled in some Umbraco and .NET specific examples and additional reading to learn more.
Broken Access Control
At its most simple, broken access control means users cannot act outside the permissions you intend to give them. For example, a user being able to access data or functions they shouldn’t be able to.
There are several ways to build to defined your site against this:
- Ensure users can’t manipulate the URL to directly access pages or APIs they shouldn’t be able to.
- Ensure users can’t change an id in the URL to view someone else’s data.
- Ensure CORS is configured to only allow access from trusted origins.
- If using Umbraco Membership for login, use the AuthorizeAttribute to limit access by member group if required.
Check out this video from Umbraco on Role Based Protection in Umbraco for an example of role based access with Umbraco membership.
In the previous Top 10, this was in 5th place. Now in the most recent edition it’s 1st, showing the importance of getting access control right.
The first activity here is to understand data you will be capturing, processing and storing. Then you can decide the requirements to protect this data, considering relevant regulations for your location and purpose, for example: PCI DSS and GDPR. Here are some things to think about:
- Don’t store or process data unnecessarily.
- If you are storing sensitive data, encrypt it at rest.
- Avoid deprecated cryptographic functions.
- If using Umbraco membership, consider which of your custom fields hold sensitive data and mark those as sensitive. This will limit who in the CMS backoffice can see this data. See documentation.
Make sure all traffic is via HTTPS with SSL certificate. Check out this .NET specific article on Enforcing HTTPS.
An application is vulnerable to injection if user input isn’t validated or sanitised before being processed due the system.
A common example you may have heard of is SQL Injection, where the user input fields are used to manipulate data using SQL commands… I find myself referencing the “little bobby tables” xkcd cartoon way more than is normal.
This was a new item on the 2021 list and is quite a broad category as it’s to cover risks of the architecture and design of the application. The recommendation here is to consider security from the beginning of a project, from gathering your functional and nonfunctional requirements, through your development lifecycle and to launch.
This can feel like a bit of a vague one, but let’s look at some practical advice:
- Threat modelling and review of user journeys, specifically those including authentication or processing sensitive data. See the “identification and authentication” item further in the Top 10.
- Capture security considerations in your non functional requirements, these should be in mind throughout the design, build and testing of your software and always considered.
- Consider security in your user stories and document these in your acceptance criteria.
- Include time for unit and integration testing of critical paths in your project scope.
- Segregate tiers of your architecture and ensure only appropriate access to each relevant layer as needed. Implement the principle of least privilege between resources in your architecture. For example, only relevant services have access to the database and only has the minimal amount of access it needs to do its job.
“Secure design is a culture and methodology that constantly evaluates threats and ensures that code is robustly designed and tested to prevent known attack methods. Threat modeling should be integrated into refinement sessions (or similar activities); look for changes in data flows and access control or other security controls.”
Security misconfiguration can cover so many different areas of your architecture, from hosting right through to the application and its databases. It can really depend on your specific architecture and infrastructure set up, but here are some examples:
- Ensure only the features you need are enabled and only necessary access available, for example ports on servers.
- Remove any default accounts or passwords.
- Implement custom error pages so we don’t give users access to information that may give away detail on the underlying system like stack traces. See Umbraco docs on implementing custom error pages.
- Check out this page for developer documentation on Umbraco security configuration.
- Implement appropriate security hardening on your chosen infrastructure.
Software is out of date or doesn’t have the latest security patches. See Umbraco’s Trust Centre, if you use Umbraco and maintain solutions I’d recommend signing up for the security advisories so you are alerted to any known vulnerabilities and patches.
Vulnerable and Outdated Components
Speaking of vulnerabilities… the next item on the list is to be aware of vulnerable or outdated components in your system. We all use dependencies in our applications, for example we install Umbraco CMS and several other dependencies when setting up a new Umbraco project. These dependencies also have dependencies of their own that could also have vulnerabilities, so keeping these up to date may seem like a never ending task but there are processes and tools to help with this.
Firstly, as a rule, only obtain components from official sources over secure link and install via a package manager such as NuGet so you can easily audit and see which dependencies may have an update available.
In .NET projects you can run dotnet list package command to get a list of packages with available updates.
dotnet list package --outdated
There are similar checks available for other technologies too such as npm audit command that checks the dependencies configured in your project lists a report of known vulnerabilities.
These tools individually are useful but you may not always remember or you may not be working with that project for a while, so automated vulnerability checks can be incredibly useful. These can be integrated in to your CI/CD pipeline and be scheduled to run, some examples include:
Identification and Authentication Failures
In previous OWASP Top 10, this issue was known as Broken Authentication and comes with a set of recommended do’s and don’ts when it comes to identity and authentication.
Verifying a user's identity, authentication, and session management is critical to protect against authentication-related attacks, some go to things to think about listed in the OWASP docs are:
- If possible, implement multi factor authentication.
- Ensure to delete default usernames and passwords - yes I have mentioned this previously but many of the top 10 overlap and this one is super important!
- Have validation to ensure strong passwords during registration and password reset.
- Consider repeated login attempts and lockout scenarios for user stories.
- Ensure a unique, random session id.
In any project with authentication, I will verify the approach taken against the OWASP Authentication Cheatsheet. I highly recommend sharing this resource with other project team mates and stakeholders too.
Software and Data Integrity Failures
A new item for OWASP Top 10, this covers risks of “making assumptions related to software updates, critical data, and CI/CD pipelines without verifying integrity”. Very much related to the “Vulnerable and Outdated Components” item above where we can have automated tools for alerting us to the out of date dependency, we need to ensure the patch is verified and any changes to the solution should go through the usual development life cycle of a code review before being merged and tested ahead of being promoted to production. Tools mentioned earlier like Snyk and Dependabot can automatically create a pull request for code review but these should still be verified by developers on the project.
Security Logging and Monitoring Failures
If you have ever had to troubleshoot an issue on live, you will know the value of logging! Being able to search the logs and infer what happened based on this information lets us understand the issue, recreate it ourselves and work towards implementing a fix.
This can be particularly vital if there is an issue or attempted breach of security.
Umbraco CMS has an in built log viewer where we can see events like failed login attempts and errors. We can also utilise the logger to add our own logs from our custom code to then be shown in the log viewer.
As mentioned in earlier points, only provide log access to those who should have permissions to see the log entries. It is also important to consider what you should be logging, think back to the item on sensitive data, let’s make sure we don’t have sensitive data output to logs.
Server-Side Request Forgery (SSRF)
“SSRF flaws occur whenever a web application is fetching a remote resource without validating the user-supplied URL. It allows an attacker to coerce the application to send a crafted request to an unexpected destination, even when protected by a firewall, VPN, or another type of network access control list (ACL).”
Like several of the others, this item covers not just the application layer but also network layer configuration. Some of the advice to mitigate includes implementing a deny by default set of firewall policies and network access control rules. Like with earlier items, assume a minimal amount of access until confirmed otherwise.
From the application side, it’s good practice to disallow HTTP redirects and always sanitising and validating user provided data from the client side.
Check out the SSRF cheatsheet for detailed, specific steps you can take to mitigate.
Hey, You said there were 10!
I know the clue is in the title “top 10” that there can be only 10… but there are 3 “on the cusp” risks considered by OWASP for inclusion but not quite making the top 10. Namely: Memory Management Errors, Denial of Service, Code Quality issues. I won’t go into the info here, but find them as some further reading here.
Well done if you made it this far, this is a lot of information to take in all at once! I hope this gave an overview of the OWASP Top 10 and gave some motivation to use some of these tips and tools in your own day to day projects.
Interested in learning more or contributing to the OWASP community? Check out their events page, showing meetups throughout the world. The Top 10 project is Open Source on GitHub, which includes a guide to contributing translations for languages - a brilliant way to contribute to OSS!