SY0-701Chapter 131 of 212Objective 3.2

Secure Software Design Principles

This chapter covers secure software design principles, a critical topic for the CompTIA Security+ SY0-701 exam under Domain 3: Security Architecture (Objective 3.2). You'll learn how to integrate security into the software development lifecycle (SDLC) from the start, rather than as an afterthought. Understanding these principles helps you identify vulnerabilities in applications and recommend secure design alternatives, which is essential for both the exam and real-world practice. Mastery of this topic enables you to answer scenario-based questions about secure coding, threat modeling, and architectural risk analysis.

25 min read
Intermediate
Updated May 31, 2026

Building a Fortress: Secure Software Design Principles

Imagine you are an architect designing a fortress. The fortress must withstand sieges, prevent intruders from entering, and ensure that even if a section is breached, the damage is contained. Secure software design is like building that fortress. You don't just throw up walls; you plan the entire structure with defense in mind. The foundation is like secure coding standards—without it, the whole building is weak. The walls are like authentication and authorization controls—they keep unauthorized people out. The moat is like input validation—it stops attackers from using clever tricks to bypass defenses. The inner keep is like the principle of least privilege—even if someone gets past the outer walls, they can't access the treasure room. Drawbridges and portcullises are like session management—they control who enters and when. Watchtowers are like logging and monitoring—they let you see what's happening. Secret passages are like error handling—they should be hidden and not reveal information to attackers. Just as a fortress must be designed before construction, software must be designed securely from the start. Retrofitting security after the fact is like adding walls after a siege has begun—ineffective and costly. Each design decision—from the thickness of walls to the placement of arrow slits—has a parallel in software design, such as choosing encryption algorithms, setting permissions, and implementing secure APIs. The fortress analogy makes abstract principles concrete: defense in depth, least privilege, fail-safe defaults, and economy of mechanism all have direct architectural counterparts.

How It Actually Works

What Are Secure Software Design Principles?

Secure software design principles are a set of guidelines that, when followed, help developers create applications that are resistant to attack. They are not specific coding techniques but rather high-level concepts that shape how software is architected. The goal is to reduce the number of vulnerabilities and limit the impact of those that do exist. These principles are derived from decades of experience in building secure systems and are codified in standards like OWASP, NIST SP 800-53, and ISO 27001.

Why They Matter for Security+

The SY0-701 exam tests your ability to apply these principles in scenario-based questions. You may be asked to identify which principle is being violated or which one should be used to mitigate a specific threat. For example, a question might describe a web application that runs with root privileges—this violates the principle of least privilege. Another might describe an application that crashes and reveals stack traces to users—this violates fail-safe defaults and secure error handling.

Core Principles

#### 1. Defense in Depth (Layered Security) Defense in depth means using multiple layers of security controls so that if one fails, another is in place to stop the attack. In software design, this translates to having multiple checks: input validation, authentication, authorization, encryption, and logging. For example, a web application might validate user input at the client side, then again at the server side, then check the user's role before processing a request, and finally log the action. If an attacker bypasses client-side validation, server-side validation catches it. If they bypass that, authorization checks prevent privilege escalation.

#### 2. Principle of Least Privilege Every user, process, or system component should have only the minimum permissions necessary to perform its function. This limits the damage from a compromise. For example, a web server process should run as a low-privileged user, not as root or SYSTEM. If an attacker exploits a vulnerability in the web server, they gain only limited access. Similarly, database accounts used by applications should have only the required CRUD operations on specific tables, not full admin rights.

#### 3. Secure by Default The default configuration of a system should be secure. This means that out-of-the-box settings should minimize attack surface. For example, unnecessary services should be disabled, default passwords should not exist, and encryption should be enabled by default. A common violation is software that ships with debug mode enabled or with sample accounts that have known passwords.

#### 4. Fail-Safe Defaults When a system fails, it should fail in a secure state. For example, if an authentication server crashes, the system should deny access rather than grant it. In code, this means that exception handlers should not accidentally leak sensitive information or leave the system in an inconsistent state. A classic example is a firewall that defaults to blocking all traffic when it fails, rather than allowing all.

#### 5. Economy of Mechanism (Keep It Simple) Security mechanisms should be as simple as possible. Complexity introduces the potential for errors and hidden vulnerabilities. Simple designs are easier to understand, test, and verify. For example, a simple access control list (ACL) is preferable to a complex rule-based system that may have unintended interactions.

#### 6. Complete Mediation Every access to every object must be checked for authorization. This means that the system must verify permissions on every request, not just the first one. For example, after a user logs in, every subsequent request to access a file or perform an action must be re-authorized. Failure to do so can lead to privilege escalation or unauthorized access.

#### 7. Open Design (Kerckhoffs's Principle) The security of a system should not rely on the secrecy of its design. Instead, it should rely on the secrecy of keys or passwords. This principle encourages using well-vetted, public algorithms and protocols rather than proprietary, secret ones. For example, using AES encryption is better than a custom cipher because AES has been extensively analyzed by the cryptographic community.

#### 8. Separation of Duties No single person or process should have the ability to perform all critical actions. In software, this means that different functions should be divided among different components or users. For example, a system that handles financial transactions might require two separate approvals for large transfers. In code, this means that the code that validates input should be separate from the code that executes database queries.

#### 9. Least Common Mechanism Minimize the amount of mechanism common to more than one user and depended on by all users. Shared resources can be a channel for information leakage or denial of service. For example, a shared temporary directory might be used by an attacker to exploit a race condition. Each user should have their own isolated resources where possible.

#### 10. Psychological Acceptability Security mechanisms should be easy to use and not hinder productivity. If security is too burdensome, users will find workarounds that undermine it. For example, password policies that require extremely complex passwords might lead users to write them down. The design should balance security with usability.

How Attackers Exploit Poor Design

Attackers look for violations of these principles. For example, if an application runs with high privileges (violation of least privilege), an attacker can exploit a bug to gain those privileges. If error messages reveal stack traces (violation of fail-safe defaults), an attacker can learn about the system. If authentication isn't checked on every request (violation of complete mediation), an attacker can access resources by directly manipulating URLs. Understanding these principles helps you anticipate where vulnerabilities might exist.

Real-World Application: Threat Modeling

Threat modeling is a structured approach to identifying and mitigating design flaws. It involves creating a data flow diagram (DFD) of the application, identifying threats (using STRIDE: Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege), and applying design principles to counter them. For example, if a DFD shows that user input flows directly to a database query, you would apply input validation (defense in depth) and parameterized queries (least privilege).

Tools and Standards

OWASP Application Security Verification Standard (ASVS) provides a checklist for secure design.

Microsoft SDL (Security Development Lifecycle) includes design phase requirements.

NIST SP 800-160 addresses systems security engineering.

CWE (Common Weakness Enumeration) categorizes design weaknesses, e.g., CWE-250: Execution with Unnecessary Privileges.

Command and Code Examples

While design principles are not about specific commands, you might see examples in the exam that illustrate violations. For instance, a Python script that runs with root privileges:

import os
# Running a web server as root (violation of least privilege)
os.setuid(0)  # This would set user ID to root

A better approach would be to run as a dedicated user:

# Create a low-privileged user and run the server
sudo useradd -r webapp
sudo -u webapp python server.py

Another example: an error handler that reveals too much:

try:
    result = database.query(sql)
except Exception as e:
    # Violation of fail-safe defaults: reveals internal error
    return f"Error: {e}"

Secure version:

try:
    result = database.query(sql)
except Exception:
    # Log the error internally, return generic message
    logging.exception("Database query failed")
    return "An error occurred. Please try again."

Walk-Through

1

Identify Security Requirements

Begin by gathering security requirements from stakeholders, compliance standards (e.g., GDPR, PCI-DSS), and threat models. This step defines what you need to protect and from whom. For example, if the application handles credit card data, you must comply with PCI-DSS requirements for encryption and access control. Document these requirements in a security requirements specification. This becomes the foundation for all design decisions.

2

Create a Data Flow Diagram

Map out how data moves through the system: from user input, through processing, to storage. Identify trust boundaries (e.g., between the internet and internal network) and data stores. Use standard DFD notation. This visual representation helps you see where threats can occur. For example, if user input crosses a trust boundary without validation, that's a potential injection point. Tools like Microsoft Threat Modeling Tool can automate this.

3

Perform Threat Modeling (STRIDE)

Apply the STRIDE model to each element in the DFD. For each interaction, ask: Can an attacker spoof identity? Tamper with data? Repudiate actions? Disclose information? Cause denial of service? Elevate privilege? For example, an API endpoint that accepts user input without authentication is vulnerable to spoofing. Document each threat and its risk level using DREAD or CVSS scores. This step prioritizes which threats to address.

4

Apply Design Principles to Mitigate Threats

For each identified threat, select one or more design principles to counter it. For example, to mitigate injection attacks, apply defense in depth (input validation + parameterized queries) and least privilege (database account with limited permissions). To mitigate information disclosure, apply fail-safe defaults (generic error messages) and complete mediation (authorization checks on every request). Document the design decisions and rationale.

5

Review and Validate the Design

Conduct a design review with security experts and developers. Use a checklist based on OWASP ASVS or similar. Verify that each principle is correctly applied. For example, ensure that all trust boundaries have authentication and authorization checks. Validate that default configurations are secure. This step may involve peer review or automated analysis tools. The output is a security design document that guides implementation.

What This Looks Like on the Job

Scenario 1: E-commerce Application with Privilege Escalation An online retailer's application had a vulnerability where a regular user could access admin functions by manipulating the URL (e.g., changing /user/profile to /admin/users). This violated the principle of complete mediation: the application only checked authentication at login, not on subsequent requests. The SOC analyst saw logs showing 404 errors from a single IP, but the attacker was actually getting 200 responses on admin pages. The correct response was to implement authorization checks on every request (e.g., using middleware that verifies the user's role). A common mistake was to assume that if the user was logged in, they were allowed to access any page. The fix involved adding a role-based access control (RBAC) check in the web server configuration or application code.

Scenario 2: Healthcare App with Information Disclosure A healthcare mobile app crashed and displayed a detailed error message including database table names and SQL queries. This violated fail-safe defaults and economy of mechanism. The SOC engineer discovered this during a penetration test. The logs showed the same error repeatedly from a single device, indicating the user was intentionally causing crashes to gather information. The correct response was to implement a global exception handler that logs the error internally and returns a generic message to the user. The developer's mistake was to use the default ASP.NET error page, which reveals stack traces. The fix involved custom error pages and disabling debug mode in production.

Scenario 3: Financial Service with Insecure Defaults A financial software suite shipped with default credentials (admin/admin) and all services enabled. This violated secure by default and least common mechanism. An attacker scanned the internet and found thousands of instances with the default configuration. The SOC team saw a spike in login attempts from unusual IPs. The correct response was to force password change on first login and disable unnecessary services. The vendor's mistake was prioritizing ease of installation over security. The fix involved a configuration script that enforces secure defaults during setup.

How SY0-701 Actually Tests This

What SY0-701 Tests Objective 3.2 expects you to understand and apply secure software design principles. You'll see scenario-based questions where you must identify which principle is being violated or which principle should be applied. Key sub-objectives include:

Recognize violations of least privilege, defense in depth, and fail-safe defaults.

Understand how threat modeling (STRIDE) relates to design principles.

Identify secure coding practices that implement these principles (e.g., input validation, parameterized queries).

Common Wrong Answers 1. Choosing 'Encryption' as a design principle – Encryption is a control, not a design principle. The exam tests principles like defense in depth, least privilege, etc. Candidates often confuse controls with principles. 2. Selecting 'Security through obscurity' as a valid principle – The exam explicitly rejects this. Open design (Kerckhoffs's principle) is the correct one. Candidates might think hiding code is secure. 3. Confusing 'separation of duties' with 'least privilege' – Both limit access, but separation of duties divides critical functions among multiple parties, while least privilege limits permissions per entity. For example, requiring two signatures for a check is separation of duties; giving a user read-only access is least privilege. 4. Believing that 'defense in depth' means using the same control multiple times – It means using different types of controls (e.g., firewall + IDS + encryption), not the same control replicated.

Key Terms on Exam - STRIDE: Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege. - Least Privilege: Minimum permissions necessary. - Defense in Depth: Layered security. - Fail-Safe Defaults: Deny by default on failure. - Complete Mediation: Check authorization on every access. - Separation of Duties: Divide critical actions. - Economy of Mechanism: Keep it simple. - Open Design: Security relies on keys, not secrecy of design. - Psychological Acceptability: Usable security. - Least Common Mechanism: Minimize shared resources.

Decision Rule for Scenario Questions When asked which principle is violated, look for clues:

If the scenario mentions 'running as root' or 'overly broad permissions' → Least Privilege.

If it mentions 'single point of failure' or 'no backup control' → Defense in Depth.

If it mentions 'error messages revealing details' or 'system crashes open' → Fail-Safe Defaults.

If it mentions 'no re-authentication for sensitive actions' → Complete Mediation.

If it mentions 'one person can approve and execute a transaction' → Separation of Duties.

If it mentions 'complex, hard-to-maintain security logic' → Economy of Mechanism.

If it mentions 'default passwords' or 'services enabled by default' → Secure by Default.

If it mentions 'custom encryption algorithm' → Open Design violation (should use public algorithms).

Key Takeaways

Secure design principles include least privilege, defense in depth, fail-safe defaults, complete mediation, economy of mechanism, open design, separation of duties, least common mechanism, and psychological acceptability.

Threat modeling using STRIDE (Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege) is a systematic way to identify design flaws.

Fail-safe defaults mean that when a system fails, it should deny access (fail closed), not grant access.

Open design (Kerckhoffs's principle) states that security should not rely on secrecy of the design or algorithm, only on keys.

Least privilege is implemented by using low-privileged service accounts and role-based access control (RBAC).

Defense in depth uses multiple, diverse layers of security controls so that if one fails, another provides protection.

Complete mediation requires authorization checks on every access attempt, not just at login.

Separation of duties prevents any single individual from having too much power, reducing fraud risk.

Economy of mechanism encourages simple, easily verifiable security designs.

Psychological acceptability ensures security measures do not hinder usability, reducing workarounds.

Easy to Mix Up

These come up on the exam all the time. Here's how to tell them apart.

Least Privilege

Limits permissions to the minimum necessary for a task.

Applies to users, processes, and system components.

Example: a database user has only SELECT privileges on one table.

Violation: running a web server as root.

Mitigates damage from a compromised account.

Separation of Duties

Divides critical actions among multiple parties.

Requires collusion to subvert security.

Example: a payment system requires two different people to initiate and approve a transfer.

Violation: one person can create a user and assign roles.

Mitigates insider threats and fraud.

Watch Out for These

Mistake

Secure software design principles are only for developers, not for security professionals.

Correct

Security professionals must understand these principles to evaluate design documents, conduct threat modeling, and recommend mitigations. The exam tests your ability to apply them, not just code them.

Mistake

Defense in depth means using multiple firewalls.

Correct

Defense in depth means using diverse controls (e.g., firewall, IDS, encryption, access controls). Using the same type of control multiple times does not provide depth; it's just redundancy.

Mistake

Security through obscurity is a valid design principle.

Correct

Obscurity (hiding code or design) is not considered a secure principle. The open design principle states that security should rely on the secrecy of keys, not the algorithm or design.

Mistake

Least privilege and separation of duties are the same thing.

Correct

Least privilege limits permissions per entity (e.g., a user has read-only access). Separation of duties divides critical actions among multiple entities (e.g., one person requests a payment, another approves it). They are complementary but distinct.

Mistake

Fail-safe defaults mean the system should always be available.

Correct

Fail-safe defaults mean that when a failure occurs, the system defaults to a secure state (usually denying access). Availability may be sacrificed for security. For example, a firewall that fails closed blocks all traffic.

Frequently Asked Questions

What is the difference between security principles and security controls?

Security principles are high-level guidelines (e.g., least privilege) that shape the design. Controls are specific implementations (e.g., a firewall, encryption, access control lists). For the exam, you need to identify which principle is being applied or violated in a scenario. For example, if a system uses multiple layers of firewalls, IDS, and encryption, that's defense in depth (principle). The firewall itself is a control.

How do I apply the principle of least privilege in a web application?

Run the web server process as a low-privileged user (e.g., 'www-data' on Linux) instead of root. Database accounts used by the application should have only the necessary permissions (e.g., SELECT, INSERT on specific tables). Use role-based access control (RBAC) to assign users the minimum roles needed. Avoid using generic admin accounts. In code, drop privileges after initialization if higher privileges are temporarily needed.

What is STRIDE and how is it used in threat modeling?

STRIDE is an acronym for six threat categories: Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, and Elevation of Privilege. It is used to systematically identify threats in a data flow diagram. For each interaction, ask if the threat applies. For example, an API endpoint without authentication is vulnerable to spoofing. STRIDE helps you apply design principles to mitigate each threat.

Why is security through obscurity not considered a valid principle?

Security through obscurity relies on keeping the design or implementation secret to prevent attacks. However, once the secret is revealed (e.g., source code leak), all security is lost. The open design principle (Kerckhoffs's principle) states that a system should be secure even if the attacker knows everything about the design except the secret keys. Using well-vetted public algorithms is more secure than custom, secret ones.

What does 'fail-safe defaults' mean in software design?

Fail-safe defaults mean that when a system component fails or encounters an error, it should default to a secure state. For example, if an authentication server is unreachable, the application should deny access rather than grant it. In code, exception handlers should not reveal sensitive information; they should log the error and return a generic message. This principle prevents attackers from exploiting failures to gain unauthorized access.

How does complete mediation differ from authentication?

Authentication verifies who the user is (e.g., login). Complete mediation ensures that every access to an object is checked for authorization, not just the first one. For example, after logging in, a user should be re-authorized each time they try to access a file or perform an action. A violation occurs if the system checks permissions only at login and then allows any subsequent action based on that initial check.

What is the relationship between threat modeling and secure design principles?

Threat modeling identifies potential threats to the system. Secure design principles provide the strategies to mitigate those threats. For example, if threat modeling reveals a risk of SQL injection (tampering), you apply defense in depth (input validation + parameterized queries) and least privilege (database account with limited permissions). Principles are the 'how' to address the 'what' found in threat modeling.

Terms Worth Knowing

Ready to put this to the test?

You've just covered Secure Software Design Principles — now see how well it sticks with free SY0-701 practice questions. Full explanations included, no account needed.

Done with this chapter?