Fundamental software design security concepts
CI4A
‘Security by design’
Similar to privacy by design, security by design is an approach to software development that incorporates security principles from the start of a project.
Examples:
- Validate input and sanitise data
- By default, deny or grant the minimum level of access
Includes the use of cryptography and sandboxing.
Cryptography
The process of hiding information. Includes hashing, encrypting, digital signatures, etc.
Sandboxing
A security practice in which a program is run in an isolated environment (sandbox). Any errors or vulnerabilities will be restricted and cannot affect the wider system. Can be used for:
- Testing (software, updates)
- Ongoing protection (Some applications always run in a sandbox e.g. mobile apps often use sandboxing to limit their access to system resources)
- Threat containment (Suspicious files or programs can be opened for analysis)
Privacy by Design
This approach integrates privacy considerations into every stage of software development. This means including privacy in the design specifications of new systems rather than treating privacy as an afterthought or addressing issues only after they occur.
Key concepts:
- proactive not reactive approach
- embed privacy into design (Collecting or sharing personal information should require users to opt in not out)
- respect for user privacy (incl. anonymisation of user data for research purposes, data minimisation, right to be forgotten)
Roles for software security in a business.
Steps of handling a security breach
Disaster Recovery Plan
A detailed set of guidelines that outline a business’ critical assets and explain how the organisation will respond to unplanned incidents.
Maintaining business continuity
Ensuring essential services continue to run after a security incident.
- Risk assessment
- Redundancy and backup (e.g. cloud backup, alternate communication channels)
- Incident response plan: establishing clear roles and procedures for employees during disruptions.
- Testing and drills: regularly simulating attacks to improve responses
Strategies used by developers to ensure security.
Code review
Code Review: Identify security flaws and logic errors through manual inspection during development (before merging code). Done by developers and security teams.
SAST
Static application security testing: Automatically (automated) detect known security vulnerabilities in source code before execution by security engineers. SAST is a quick solution to complex vulnerabilities (solved early on) which also identifies the exact location of errors, however, is liable to false positives, and is blind to runtime errors.
DAST
Dynamic Application Security testing: Mostly automated process to test a running application for vulnerabilities by automatically simulating attacks after deployment on a running application. Best used for detecting runtime errors and authentication issues, however doesn’t identify errors sources, and is also done after code development (more costly fixes)
Vulnerability assessment
Periodically monitor, identify and prioritize security weaknesses in applications, networks, and systems. Conducted by security teams and automated tools often also after major updates.
Penetration testing / pentesting
Simulate real-world attacks to find exploitable vulnerabilities in an organisation’s entire environment, including networks and human vulnerabilities. Conducted periodically and before deployment by specialised penetration testers (ethical hackers). As it can also be detected by testers with little knowledge of the system’s security measures, penetration testing is extremely effective for simulating real-world attacks/exploits before they happen.
Input validation
check that the data entered meets expected formats so that it is appropriate for intended process. e.g. DOB
Sanitisation
Potentially harmful inputs are altered. e.g. escaping special characters (e.g. script tags)
Error handling
Messages should be generic for users but detailed for developers (e.g. do not give users specific database error codes, which might expose details about the database). But also don’t have sensitive information in error logs.
Instead of allowing the application to crash, handle errors properly with try-catch blocks.
API
An application programming interface is a set of rules that allows two different pieces of software to communicate with each other (An API is a broader concept that uses HTTP calls but also includes the standards, protocols, and conventions for those HTTP calls).
Keys: When sending requests, the most common HTTP method is GET, which asks for data, while others like POST, PUT, and DELETE allow you to send new data, update existing data, or remove data. These almost always require an API key in order to authenticate the request.
Rate limits: restrict how many requests a single user can make in a given time period, so the system doesn’t get overloaded and can serve all users fairly.
REST + endpoints
Many APIs used on the web today are called REST (Representational State Transfer) APIs.
These follow clear principles: they use standard web addresses (URLs) to identify resources, they return data in a consistent format such as JSON, and they use simple web methods like GET or POST.
An endpoint is a URL that provides a particular function or piece of data. e.g. can be ‘/countries’ or ‘/countries/australia’
Memory management (life cycle, garbage collection, memory leaks)
The process of efficiently allocating, using and freeing memory in a program. The memory life cycle refers to three stages that all variables, objects and functions experience.
1. Allocate: Memory is allocated when variables, objects, or functions are created.
2. Use: memory is accessed
3. Release: Memory should be released for future assignments. In lower-level languages objects have to be manually deleted.
Many modern languages use automatic garbage collection. Two common methods:
1. Reference accounting: An object is removed when there are no more references to it
2. Mark-and-sweep
Periodically scans the memory and removes unreachable objects.
Memory leaks occur when:
1. Global variables: not released until the program terminates; AVOID globals
2. Forgotten DOM references: Event listeners are added to elements that are subsequently removed; the memory allocated to the listener’s referenced function remains unusable (and won’t be deleted by garbage collection since its referenced)
3. Circular references - When 2+ objects refer to each other, they cannot be released individually.
Session management:
1. session storage
2. local storage
3. cookies
4. session id
Exception Management
The process of handling errors so that a program doesn’t crash, and instead detects, logs, and responds to errors appropriately.
Most languages have a try-catch block which, if an exception is raised during the try block, the program diverts instead to the catch block . A finally block is always executed, whether or not an error occurred.
Types of errors