Syllabus Point
- Interpret and apply fundamental software development steps to develop secure code
Including:
- requirements definition
- determining specifications
- design
- development
- integration
- testing and debugging
- installation
- maintenance
Secure code development follows a staged process from defining requirements through to maintenance. Each step helps keep the software aligned to user needs while reducing vulnerabilities and supporting safe deployment.
Requirements Definition
Requirements definition is the process of gathering and analysing what the software must achieve and what users expect it to do. When security is considered at this stage, it is far cheaper and more effective to address than if it is added retrospectively after development has begun.
Functional Requirements
Functional requirements specify what the system should do in terms of features, operations, and observable behaviours. For example, a functional requirement might state that the system must allow users to create and manage groups, or that users must be able to reset their password via email verification.
Non-Functional Requirements
Non-functional requirements describe how the system should perform rather than what it should do. They cover qualities such as performance, usability, and security. For example, a non-functional requirement might state that user passwords must be stored securely using a hashing algorithm such as bcrypt, or that the system must respond to authentication requests within two seconds.
Security-Focused Requirements
- Encrypt sensitive information in transit and at rest
- Ensure integrity, authorisation, and authentication are enforced at every access point
- Prevent common vulnerabilities like SQL injection and XSS by validating all user inputs
- Example: only users with the admin role should be able to manage group finances and send invitations
Techniques
- Interviews with stakeholders to understand expectations and constraints
- Surveys and questionnaires to gather input from a broader user base
- Use case scenarios to map out how users will interact with the system
Threat Modelling
Threat modelling is conducted during requirements definition to identify potential threats to the system and define how the software will counter them. It involves thinking like an attacker - asking what could go wrong, who might try to exploit the system, and what the impact would be. Countermeasures are then built into the requirements.
| Threat | Countermeasure |
|---|---|
| Attacker tries to gain unauthorised access by guessing a password | Implement password policies, add account locking after repeated failed attempts, and use secure authentication controls |
Determining Specifications
Specifications translate broad requirements into detailed, clear, and actionable instructions for developers. They describe exactly how the system will function, how it will meet user needs, and how security will be enforced. Good specifications consider how data is handled at every point, who can access which features, and how the system will defend against known attack vectors.
Examples of Specifications
- Authentication protocols such as MFA and password hashing with a minimum of bcrypt or Argon2
- Data security standards for encryption, storage, and handling of personally identifiable information
- Access control policies that limit data and feature access to authorised users based on their role
Design
Design turns the specifications into a secure architecture, establishing clear structure for components, data flow, and user interaction. Security is not added as an afterthought at this stage - it is woven into the structure of the system from the beginning.
Secure Design Principles
The principle of least privilege means that every user, process, or component should only have access to the resources it needs to perform its function and nothing more. This limits the potential damage if a component is compromised. Fail-safe defaults means that the system should default to a secure state - for example, denying access unless it is explicitly granted, rather than allowing access unless it is explicitly denied.
Architectural Considerations
A layered architecture separates the presentation layer, business logic, and data layer, so that a breach in one layer does not automatically expose the others. The Model-View-Controller (MVC) pattern separates data management from presentation and user input handling, making secure systems easier to maintain and audit. Wireframes and interface sketches help plan secure layouts and user flows during the design phase, identifying potential usability and security issues before any code is written.
Development
During development, secure coding standards must be followed to avoid introducing common vulnerabilities. Developers should use well-tested, trusted libraries and frameworks with strong security track records rather than writing low-level implementations from scratch. Regular code reviews and peer audits are a critical practice at this stage - having another developer examine the code helps catch security flaws, logic errors, and poor practices before they are merged into the codebase.
Integration
Integration brings separate modules and services together safely without introducing new vulnerabilities. When combining components, it is important to assess the existing system architecture and identify any vulnerabilities that the integration might expose. New requirements must be aligned with existing security protocols to avoid inconsistencies.
- Build features as modular components to limit the blast radius of any single vulnerability
- Secure API and database integration by enforcing authentication, authorisation, and input validation at every interface
- Test that the combined interface remains intuitive and secure after integration
- Monitor after deployment to confirm stability and that no new vulnerabilities have been introduced
| Steps | Description |
|---|---|
| Assessment of existing system | Assess the existing software system to understand the architecture, components, security vulnerabilities and impact of integrating new changes. |
| Requirements alignment | Align requirements with existing software, and ensure the new security measures do not conflict with any existing security protocols. |
| Modular development | Develop new features as separate modules that can be easily integrated and configured within the existing system. |
| API integration | Ensure APIs are well documented, secure and compatible. |
| Database integration | Implement input field sanitisation processes within the database queries to prevent SQL injection. |
| User interface integration | Update user interface, and ensure changes are intuitive and easy to navigate. |
| Testing and validation | Verify functionality, security compliance, and interoperability. Perform regression testing to ensure changes don't impact the overall performance and stability of the system. |
| Deployment and monitoring | Implement monitoring tools to track performance, security metrics, and user feedback. |
Testing and Debugging
Testing and debugging confirm that the software works as expected and that security controls are effective. Security testing goes beyond checking that features function correctly - it actively attempts to find ways to break or bypass the security of the system.
- Unit testing for individual components to verify they handle valid and invalid inputs correctly
- Black box testing (DAST - Dynamic Application Security Testing) from the perspective of an external user with no knowledge of the internal code
- White box testing (SAST - Static Application Security Testing) with full access to the source code to analyse logic paths and identify vulnerabilities
- Penetration testing by ethical hackers simulating real attack scenarios to find exploitable weaknesses before deployment
Installation
Installation is the process of setting up the application so it can be used securely in development, testing, and production environments. A system that is correctly coded but poorly deployed can still be vulnerable, so installation procedures must follow security best practices.
- Use HTTPS for all connections to encrypt data in transit
- Keep development, testing, and production environments isolated to prevent test data from exposing production systems
- Configure databases with strong credentials and restrict access to only the services that require it
- Apply file and directory permissions following the principle of least privilege
- Provide secure installation guides and user documentation to support safe onboarding
Maintenance
Maintenance is an ongoing process that continues long after deployment. New vulnerabilities are discovered regularly in software and its dependencies, so applying updates and patches promptly is essential to keeping the system secure. System logs should be monitored for unusual activity that could indicate an attack or unauthorised access attempt. Users should also be educated about secure behaviour - for example, recognising phishing attempts, avoiding suspicious links, and updating their passwords regularly.
Related Resources
Keep Progressing
Use the lesson navigation below to move through the module sequence.