This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Design

A secure solution begins with a good design! Much of the foundation for assessing whether a solution is secure comes from the design phase, where important trade-offs between cost, benefit, and risk must be made.

The articles you find under the topic design on this page will focus on the design process. Although this process may include much more than we have listed, we cover the essentials such as thorough documentation of what is to be built, critical clarifications, and the need for context.

1 - Security Requirements

How can one build security into a solution if there are no well-defined security requirements?

Some requirements are implicit, such as the use of HTTPS/TLS, while others will be explicit and defined by customers or third parties. Even if the customer has no specific requirements, it is still important for the delivery team to create a list of requirements to ensure that the project’s framework is documented.

Most projects must adhere to various requirements from Bouvet, the customer, and external parties. All development teams must have control over the requirements that apply to the delivery:

  • From Bouvet (where applicable)
  • From the customer
  • Legal requirements

Legal requirements can include general requirements related to privacy, but many industries operate with more specific regulations that impose additional requirements.

In many cases, it is clear to both Bouvet and the customer what applies, but it is important that the team verifies this before starting to develop the solution to avoid costly and time-consuming surprises. Regardless of what is defined and where, the team should document the requirements they adhere to so that this information is preserved for the future.

More Information

2 - System diagrams and drawings

It’s important to have a good foundation when building quality solutions, and drawings and diagrams showing the infrastructure, data flow, networks, and access control are crucial elements. Without this information, it is difficult to validate if the implementation matches the intended design.

When designing a solution, it’s essential to have clear and comprehensive drawings and diagrams that show the planned design. This is already done by many development teams without necessarily being a formal requirement, but it’s still worth mentioning here.

System diagrams should provide enough information to:

  • Validate that the implementation matches the design
  • Use them for threat modeling, pentesting, or similar activities
  • Be used by those managing the solution to get a good overview of components and data flow
  • Be used by the delivery team for onboarding new colleagues or handover to other teams

Although there is a lot that can be documented here, we focus on the most important aspects:

  • High-level system sketch with the main logical components
  • Detailed network diagram with resources, services, and networks
  • Data flow diagram showing how data flows between components in the solution
  • IAM diagram showing identities, accesses, and roles and where they are sourced from
  • Important dependencies – overview of other systems, services, resources, on-prem/cloud

Examples

Below are examples of the points listed above. The diagrams you produce do not need to be identical; the most important thing is that they contain enough information to be used for their intended purpose and are understandable to the team.

To easily get started with designing diagrams and sketches, tools like Miro or Draw.io can be used. The latter is free and offers storage of drawings in the browser, locally on the machine as XML, and much more.

Keep in mind:

The diagrams do not need to be perfect or contain every conceivable detail. Assess the need and work on gradual improvements over time.

High-level System Diagram

This diagram should be a high-level introduction to the solution, showing all the major components and interactions between them.

Overordnet skisse

Network Diagram

The goal of the network diagram is to show the network topology, with all the various virtual networks, subnets and resources or servers and firewall openings between them.

Nettverksdiagram
Keep in mind:

Network diagrams should be created for all environments, providing necessary information on all resources in all environments, as well as connections between them.

Data Flow Diagram

The data flow diagram shows the data flow of the solution. This should include all direct dependencies not part of the project, so that it is possible to understand where data originates and all the nodes it interacts with.

Dataflytdiagram

IAM Diagram

IAM-diagram

Dependencies

This can also be drawn, but often a simple list is enough. This should contain all direct dependencies of the solution being developed, with a brief summary containing descriptions of what the team depend on.

  • On-prem database server production-sql-01
    • Uses three views maintained by the team
    • Data is imported via ADF
  • Company’s data platform, datalake datalake-somedata-prod01
    • Consumes datasets in the container production-data-container
    • Lineage is visible in Purview
    • Uses only datasets approved by the data owner

More Information

3 - Segregation of Environments

Development projects use different environments for various purposes, such as testing deployments in a dedicated dev environment, exposing the test environment to product owners and other key personnel, and the production environment to end users. To avoid incidents in one environment affecting another, we must segregate them at a level that makes sense for the team and the context in which we work.

When we build solutions, we often set up multiple environments, typically for dev, test, and prod, so that we can develop while the product owner tests new functionality and end users use the system in prod. It is important to distinguish between these environments to avoid situations where changes in one environment affect the use of another.

When designing a new solution, we must consider how to separate the environments. For cloud services, a common approach is to use different subscriptions per environment where possible. One subscription cannot affect another unless explicitly configured, but there are other possibilities as well.

Brief Overview of the Most Common Solutions (Azure):

  • Separate subscriptions per environment:
    • Natural separation unless explicitly defined access
    • More overhead with managing multiple subscriptions
  • Use of separate resource groups:
    • Simplified administration
    • Resource groups share some limitations and access at the subscription level
  • Separate virtual networks:
    • Segregation at the network level
    • Often requires more admin to ensure there is an actual separation

There are other approaches to this as well, but regardless of the solution the team chooses, it is important to consider the overall cost/benefit against the requirements to be met.

More Information

4 - Authentication and Authorization

Authentication and authorization check respectively who you are and what you are allowed to do. These are important concepts that must be correctly implemented to ensure the security of a solution.

Authentication and authorization are crucial in all development projects. In short, authentication is about validating that a user represents the identity they claim to represent, typically by checking a username and corresponding password. Authorization is about checking that the user is allowed to do what they are trying to do. These are often abbreviated to authn for authentication and authz for authorization.

Authentication

When validating a user, the most important thing is to not create your own authentication solution! Ensuring that such solutions are actually secure is a huge task, and one should instead use established solutions for this!

Common approaches for handling authentication can be the use of third-party services or protocols that handle authentication against the customer’s AD/Entra. In many cases, we want to use Single Sign-On (SSO) to avoid the user having to enter username and password, especially for internal business applications.

Common solutions for handling login are to use libraries that take care of the entire flow, such as Microsoft.Identity.Web. Other alternatives can be the use of:

  • SAML
  • Oauth 2.0
  • OpenID Connect (OIDC)
  • Kerberos
  • LDAP

It is important to understand the needs of the solution and which authentication methods are available and possibly desirable.

Authorization

The distinction between authentication and authorization is that authentication confirms who you are, while authorization checks that you are allowed to perform an action.

Similar to authentication, there are several approaches to how authorization is handled, and one needs to understand the best practices for the language and framework used.

There are still some main principles that should always be brought into the development process:

Default access should always be no access

This is also known as default deny, and is used to ensure that, for example, an unauthorized user does not have access to anything beyond what is explicitly allowed.

Authorization should always be checked

If a user attempts to perform an action, it should always be checked whether the user actually has access to this. Remember that this check must be made against the authoritative source for access rights, and never against data that the user can manipulate!

Users should always be given the least possible access

Also known as the principle of least privilege. A user should never be given more access than is needed to perform a specific task. This is done to reduce the attack surface if a user is compromised, so that the scope of damage can be limited.

Role-Based User Access

Using roles, role based access control (RBAC), is a common approach to granting user access. The goal is to define standard roles for an application so that access can be based on these. A common way to handle this, for example, with Entra or AD is to have:

  • access groups with all users. The access groups are added as members in
  • role groups, which are given access in the application.

This provides a better overview of who has access to what compared to users with individual access.

More Information

5 - Network Concepts

Network is a fundamental component in everything we create, and it is important to have a basic understanding of how it works and how it can be exploited by others.

Proper configuration of the network is important for pure cloud solutions, hybrid networks, and on-prem solutions. Network is a vast field with significant variations in usage, security, and complexity. Below we cover basic concepts for communication to and from servers and network services.

Zero Trust Architecture

Zero trust is an important concept in network operations. In short, you should never trust anything coming from other systems, and you should assume that all communication will be compromised. Zero trust cannot be solved just by securing the network, but must be a goal in itself when designing solutions and the infrastructure around them. By implementing zero-trust, you will eliminate many potential attack vectors and thus protect the services that use the network.

Getting an Overview of the Network

Important

Keep track of which IP addresses and ports you expose, and which services are listening on the ports. Check firewall rules, look in logs, and scan your systems with nmap.

Keep an overview of which IP addresses, ports, and protocols an IT system exposes to the outside. This applies regardless of whether you are setting up a new system, changing an existing one, or just investigating what you already have. A targeted attacker will map open endpoints to find targets, and there have been several examples of data breaches starting with a forgotten, insecure service.

As developers and system managers, it is critical that we know exactly which services are open to whom and why.

When setting up new systems, you have good opportunities to control what is exposed. The main rule according to the Zero Trust architecture should be to start with everything closed, and then open only the ports and protocols that are needed. New components should be isolated from existing systems.

In existing systems, it can be difficult to get an overview of what is exposed, especially in hybrid or on-prem setups. Simply shutting down everything that is not documented can also be risky, as this can affect legitimate systems. If working in the customer’s infrastructure, feel free to contact the network department for help with mapping.

Network Scanning

To find open ports and services, you should scan both public and private IP ranges from different locations. Remember that internal networks can follow different routes than external traffic and thus see different openings. The same applies in situations where you have office networks, VPN, DMZ/guest networks, or other open networks.

There are tools and services that make mapping easier. nmap is the industry standard and FOSS, and it is excellent for scanning IP ranges and detecting open UDP, TCP, and SCTP ports. If you lack an overview, nmap is a good place to start.

Caution

The use of scanner tools like `nmap` must **always** be clarified with the owners of infrastructure and network. If you are at a Bouvet office and scanning a customer's Azure environment, you can easily trigger alarms at both Bouvet and the customer, as well as the ISP.

Service Isolation

Important

Use a firewall to restrict traffic within systems and between systems and the Internet. Use allowlist if possible. Filter traffic at the application layer if necessary.

Firewall is a common term for barriers in a network that stop unwanted traffic. In most contexts, the definition is a bit narrower, referring to barriers at the TCP/IP layer, but a firewall can also operate at the application layer.

To enforce a zero-trust architecture, all components must be isolated and only made available to the services that they themselves will consume or deliver data to. This makes it necessary to have a firewall between components in the same application, between applications, and between the application and the Internet. If you have an application with a database, a backend API, and a web API, it is advantageous if you can set firewall rules between the components that only allow the necessary traffic. See the diagram below for an example.

Firewalls should always drop all incoming and outgoing traffic by default and be explicitly opened for legitimate connections. Always limit port openings to specific ports and protocols where possible. Avoid using “Any” as the protocol!

Also use firewalls between all services within the network to ensure multiple layers of protection if one fails. Segmenting the network so that each function has its subnet will also help.

Avoid sending traffic over the internet even to your own cloud services, use private endpoints and VPN tunnels where possible. Services that must be exposed to other systems (both internal, external, and on the internet) should be placed behind security functions such as web application firewalls and/or API gateways, and you must ensure that these also protect against, for example, DDOS attacks.

Route all outgoing traffic through a dedicated proxy service that blocks everything by default, allowlisting as needed. Never expose services directly if you can avoid it. Exposing services on ports other than the standard ports is not a good idea; a network scan will quickly reveal this.

Configuration

Network configuration should be automated as much as possible, preferably using a CI/CD system.

  • Limit who can configure both the network and network rules directly
    • Set up Just-in-time (JIT) access where possible
    • Limit where the network can be edited from (e.g., only from inside an on-prem firewall)
  • Script all rules that can be scripted
    • Use source code control
      • Have extra security on repos containing the network source, protecting both reading and writing
    • Use tools like Snyk to run analysis of scripts
    • Scripts should be run regularly and automatically (at least daily)
      • If unknown rules are detected, alerts should be created
      • All unknown rules should be deleted or disabled
      • Alternatively, other methods can be used to detect deviations from the desired configuration
  • Back up or document all rules set up without scripting
    • Document all rules set up/handled by people outside your team

More Information

6 - Threat Modeling

Threat modeling is an exercise aimed at identifying threats so that the risk of these can be identified and assessed against the overall security of the solution. From a threat model, mitigating measures can be identified and implemented to reduce risk.

This is a brief introduction to threat modeling, data flow diagrams, STRIDE, and attack trees.

You may have already done simple threat modeling without realizing it. For example, have you ever thought about why the users of the system you’re creating need to log in with a username and password?

When these choices were made, you automatically performed simple threat modeling. You certainly don’t want unauthorized individuals to access data in your system, and you don’t want anyone to see the data transferred between your users and your website.

The whole point of threat modeling is to think like an attacker.

Identifying Threats

There are several ways to identify threats to a system. The simplest method, which doesn’t require much, is to gather the development team for a social evening or workshop and try to think about how to attack the system. This will likely result in many potential threats. Some are probably already addressed, while others may need to be tested and possibly investigated further. Once all threats have been addressed and it has been verified that countermeasures are implemented, the process is repeated. To get an overview of the process, it is often wise to draw a diagram of the system.

The process often starts with drawing a diagram/overview of the system, identifying threats, addressing the threats, and finally validating that countermeasures are implemented, then repeating the process.

If you want to use more formalized tools and processes, there are two widely used methods for threat modeling: attack trees and data flow diagrams + STRIDE.

Attack Trees

Using attack trees is a good way to identify threats if you are good at thinking like an attacker. If this doesn’t come naturally, using data flow diagrams is often a better method.

An attack tree consists of a main goal at the top of the tree, with various ways to achieve the main goal as nodes.

In this example, the main goal of an attacker is to access reports in a time tracking system. To achieve the main goal, the attacker can either use a valid password in the system or find a vulnerability in the solution that grants access. One way to obtain a valid password is to bribe an employee. This way, you add different ways to reach the main goal and subgoals. You then go through the identified threats and verify that countermeasures are in place or decide to accept that there are threats to the system that you will not protect against. The cost of countermeasures should always be weighed against the value of what is being protected.

More information and examples of attack trees can be found in the article Attack Trees by Bruce Schneier.

Data Flow Diagram + STRIDE

Start by creating a detailed data flow diagram of the system or part of the system you are threat modeling.

Once the data flow and trust boundaries of the system have been drawn, use STRIDE to identify threats. STRIDE is an acronym for:

  • Spoofing - Can you trust that the user is who they claim to be?
  • Tampering - Can someone modify data intentionally or unintentionally?
  • Repudiation - Can it be proven who performed a given action in the system?
  • Information disclosure - Can data be stolen or leaked?
  • Denial of Service - Can someone make services unavailable?
  • Elevation of privilege - Can someone gain elevated rights in the system?

Here is an example of a data flow diagram showing the data flow during login with username and password. The arrows between services represent calls. The SSL proxy is a security layer that encrypts information between services. HTTPS are calls where the information sent is encrypted, and HTTP are calls where the information sent is not encrypted.

In the data flow diagram above, you can see that there is a risk that someone with access to the network between the SSL proxy and the time tracking system can read and modify the username and password that are not encrypted over HTTP. By going through all data flows while thinking about possible attacks according to the STRIDE model, you can build a list of potential threats to the system.

Moving Forward

The threat model must be versioned and kept up to date. Once threats have been identified, countermeasures must be described, and their effectiveness assessed. A common approach is to give the threat a value indicating severity, for example, 1-10 where 10 is the worst. Countermeasures are assessed similarly but with the opposite scale where 1 has little effect and 10 (or up to criticality) has the highest effect. The sum of these gives a residual risk that indicates the remaining risk:

Identified Threats          Criticality     Countermeasures Residual Risk
Threat  1                   8               8               0
Threat  2                   2               0               2
Threat  3                   4               3               1
Total                       14              11              3

When a risk is identified, it is important that the risk owner is involved, as they are responsible for ensuring that the project delivers quality in line with expectations and requirements.

It is important that countermeasures are validated for them to be effective. The threat model should be reviewed regularly to see how the situation has changed, and if the total criticality or residual risk exceeds a threshold, consider measures to reduce them.

More Information

Tools

Courses and Lectures

Other Sources

7 - Competence Building

Having the right competence is crucial for all teams, especially when it comes to security. The team must identify any gaps they have, so that measures such as training can be implemented to cover these gaps.

Security is an unknown and perhaps somewhat intimidating area for many, where they don’t quite know where to start. Therefore, when a new project is initiated, it is important to assess the need for competence building among team members. Initially, this is aimed at topics related to security, but the use of new technology can also pose a risk if used incorrectly.

It is important that the team reviews the entire development process in all phases and evaluates each point against what the team knows, what is relevant for the project, and where assistance can be obtained.

We have many different security environments and individuals with high competence who can contribute within Bouvet; if your team needs help, feel free to bring it up in your local Security Champions channel on Bouvet-Slack, #sikkerhet or with your regional quality leader.

More Information