Secure Software Engineering: Applied Cybersecurity from Threat Modeling to Penetration Testing

Secure Software Engineering: Applied Cybersecurity from Threat Modeling to Penetration Testing

Applied secure software engineering covering threat modeling, identity, web/API and network security, supply chains, security testing, and trust boundaries in AI-enabled applications.

Securing a system is not a matter of running a few scanners at the end of development. Security means removing unnecessary trust, making boundaries explicit, reducing the paths an attacker can traverse, and verifying the remaining paths in measurable ways.

Unit 1: Security Foundations, Threat Modeling, and Secure Lifecycle

Threat modeling begins with assets, trust boundaries, and plausible entry points. Test an attack path against the adversary's initial privileges and required preconditions. Prioritize findings by exploitability, impact, and existing controls rather than count alone. After implementing a mitigation, retest the path to establish where the attack is now blocked.

Introduction: Who Reaches the Flag First?

Attack tools are easy to remember in cybersecurity training. Nmap scans ports, Wireshark captures packets, Burp Suite modifies HTTP requests, BloodHound turns relationships in an Active Directory environment into a graph, and Metasploit demonstrates how a vulnerability can be exploited. Concrete output is valuable for learning; the first sense of success often comes from seeing a tool produce a result. Yet securing software requires us to look behind the tool and ask a more important question: which of our assumptions did the attacker exploit?

After working with different offensive and defensive techniques for long enough, apparently unrelated vulnerabilities begin to converge on a small set of recurring design failures. SQL injection and operating-system command injection target different interpreters, but both lose the boundary between data and command. IDOR/BOLA and unsafe file access target different resources, but both fail to verify authorization on the object being accessed. Kerberoasting, an overprivileged service account, and a weak password may initially appear to be three separate problems; in an attack chain they become one architectural failure in which the same identity is both easy to compromise and excessively powerful. XSS is more than a JavaScript problem; it is the movement of untrusted data into an executable context. Unsafe deserialization follows the same pattern by granting data the ability to construct object graphs and, in some environments, trigger code execution.

This study approaches security by tracing these common causes rather than memorizing attack names. The objective is not to build a catalogue of exploits. It is to combine the perspective of an ethical hacker with software and cybersecurity engineering so that a system becomes defensible from design through operation.

In CTF terminology, there is a flag. This time, however, the goal is not to help the attacker capture it. The goal is to prove where the system breaks the attack chain. Consider a fictional but realistic architecture:

Internet
   |
Reverse Proxy / API Gateway
   |
Web / Mobile Client ------- Identity Provider
   |                              |
Application API ------------- Authorization
   |
Database ---- File Storage ---- Messaging / External Services
   |
Operating System / Container / Virtual Machine
   |
Corporate Network ---- Active Directory / DNS / SIEM

There is no single "security wall" in this architecture. Every arrow is a data flow, every component an asset, every identity a set of privileges, every protocol a trust boundary, and every external dependency another attack surface. The quality of the defense is determined less by the price of the most expensive security product than by how correctly these boundaries are designed.

This approach is consistent with current security frameworks. OWASP Top 10:2025 covers not only classic injection and authentication failures but also broken access control, security misconfiguration, software supply-chain failures, insecure design, integrity failures, insufficient security logging and alerting, and mishandling of exceptional conditions. The NIST Secure Software Development Framework (SSDF) treats security not as a final gate added to the software development life cycle but as an engineering practice embedded throughout it. NIST Cybersecurity Framework 2.0 extends the view from governance through recovery. I will use these frameworks not as checklists to be completed mechanically, but as structured descriptions of problems that become visible in real systems.

1. Security Is Not a Feature; It Is System Behavior

A lock icon, TLS, multi-factor authentication, a firewall, EDR, WAF or SIEM says little about overall security when viewed in isolation. Each control answers a particular threat model under particular assumptions; the useful question is how those controls behave together across the system's trust boundaries.

It is more useful to define security as system behavior. While performing its intended function, can the system prevent an unauthorized actor from producing an outcome we do not want? Can it detect behavior it cannot prevent early enough? If a compromise occurs, can it constrain the damage and return to a trusted state?

The classical confidentiality, integrity, and availability triad remains a useful starting point:

  • Confidentiality requires information to be visible only to authorized parties.
  • Integrity requires data and operations to resist unauthorized modification.
  • Availability requires authorized users to reach the service when they need it.

Real systems may add authenticity, non-repudiation, accountability, privacy, safety, and other properties. The relevant point is that these terms must not remain abstract. "Customer data must remain confidential" is not directly testable. "User A must not be able to retrieve user B's record by changing the object identifier" is testable. Engineering begins when a security requirement can be verified.

1.1 Asset, threat, vulnerability, and risk

Confusing these concepts leads to poor prioritization.

An asset is something worth protecting: data, an account, a key, source code, computing capacity, reputation, service continuity, or even a physical process. A threat is an actor or condition capable of harming that asset. A vulnerability is a weakness that a threat can exploit. Risk evaluates likelihood and impact in context.

The same vulnerability does not represent the same risk in two systems. A service isolated from the Internet, running on a separate network, and holding only low-value test data has a different operational risk from an Internet-facing service with access to critical identity data, even if the vulnerable component has the same CVSS score. Managing security exclusively from scanner scores discards system context.

1.2 Attack chains and compound risk

The most damaging production incidents often do not begin with a single finding labeled "critical." Several moderate weaknesses can compose into a path:

Unnecessary information disclosure
        -> usernames become known
        -> target list for password spraying
        -> compromise of a low-privileged account
        -> excessive file-share permissions
        -> service password recovered from configuration
        -> overprivileged service account
        -> lateral movement in the domain

No individual step necessarily means "the system is compromised." The attacker, however, searches for a path through a graph. This is precisely why BloodHound is powerful in Active Directory environments: it exposes relationships, not merely isolated objects. Secure design therefore aims not only to reduce the number of vulnerabilities but to cut the paths from an attacker's initial position to a critical asset.

We will apply that graph-oriented reasoning to the entire application.

2. Draw the Boundary First: What Are We Testing and Protecting?

The first serious failure in penetration testing is often not technical; it is a scope failure. The line between authorized testing and unauthorized attack is not defined by intent alone. Scope, timing, data, methods, and stop conditions must be explicit. In a CTF laboratory every target may be fair game. Production systems do not offer that freedom.

Before a security assessment begins, at least the following should be defined:

  • Asset: Which systems, data, and services are being protected?
  • Ownership: Who owns the system technically and from the business side?
  • Scope: Which IP addresses, domains, applications, APIs, clients, and accounts are in scope?
  • Exclusions: Which systems must not be disrupted?
  • Data: May real data be used, or is masking required?
  • Test type: Code review, architecture review, penetration test, red-team exercise, configuration audit?
  • Timing: When may tests that can create load or interruption be executed?
  • Evidence: Which logs, screenshots, or sample records may be retained?
  • Stop condition: What happens if there is data loss, performance degradation, or unexpected propagation?
  • Communication: Who is notified in case of a critical finding or outage?

This discipline does more than establish legal authorization. It improves the technical result. If scope is unknown, the asset inventory remains incomplete. If inventory is incomplete, the attack surface cannot be known. If the attack surface is unknown, risk assessment is largely guesswork.

3. Asset Inventory: You Cannot Protect a System You Do Not Know Exists

A server invisible to the security team is not invisible to an attacker. Forgotten subdomains, old test services, Internet-exposed administration panels, obsolete VPN accounts, legacy mobile API versions, and abandoned object-storage buckets are common entry points.

The first technical step in a hardening process is therefore inventory. It is not accidental that CIS Controls v8.1 begins with inventories of enterprise assets and software assets.

3.1 Inventory is more than a list of servers

Each of the following is a distinct asset class:

  • physical and virtual servers,
  • workstations and mobile devices,
  • network devices and wireless access points,
  • domains, subdomains, DNS records, and certificates,
  • APIs and their versions,
  • databases and datasets,
  • service accounts, users, groups, and roles,
  • cryptographic keys, certificates, and other secrets,
  • source-code repositories,
  • build systems and CI/CD runners,
  • third-party libraries and operating-system packages,
  • container images,
  • log sources,
  • backups,
  • SaaS or external-service integrations,
  • Active Directory objects and trust relationships.

Service-account and machine-identity inventories are often weaker than human-user inventories even though they can be more attractive to an attacker. A service account whose password has not changed for years, does not support MFA, and belongs to an administrative group can become a more valuable target than an ordinary user.

Inventory must also have ownership. An asset with no responsible owner tends to accumulate stale configuration, unnecessary exposure, and delayed patching.

3.2 Data classification

Not all records justify the same controls. Public documentation, internal operational information, credentials, personal data, cryptographic keys, forensic evidence, and security telemetry have different consequences if disclosed or modified.

A useful classification should answer operational questions:

  • Who may read the data?
  • Who may modify it?
  • May it leave the production environment?
  • May it be copied into development or test systems?
  • How long must it be retained?
  • Does it require encryption at rest?
  • Which access events must be logged?
  • How must it be destroyed?

Classification that changes no engineering decision is documentation, not a control.

4. The Attacker's First Task: Map the Visible Surface

The first view of an application should not come from its source tree. It should come from what an external actor can observe. DNS, TLS certificates, HTTP headers, service banners, JavaScript bundles, robots directives, error responses, public repositories, package metadata, exposed APIs, mobile applications, and employee-facing portals can reveal architecture before authentication ever occurs.

This is where OSINT and active discovery meet. Passive information gathering asks what is already publicly observable. Active discovery asks what the target answers when probed. Both are valuable in authorized assessment because a defender should know what the system reveals before an attacker does.

4.1 Small information disclosures grow inside a chain

A verbose error message may expose a framework version. A JavaScript source map may reveal internal endpoint names. A public repository may expose a naming convention for service accounts. A certificate may reveal subdomains. A forgotten status endpoint may disclose build numbers and hostnames.

None of these necessarily produces immediate compromise, but attack chains are built from such fragments. The defensive question is not simply "is this secret?" but "what does this information enable when combined with what is already known?"

Error handling requires special care. Returning a stack trace to the client may disclose SQL text, file paths, class names, framework versions, or internal topology. Replacing every error with a meaningless generic message, however, can make operations impossible. The better pattern is two-channel reporting:

  • a stable, limited, actionable error identifier for the user,
  • detailed technical context only in an authorized observability system.

OWASP Top 10:2025's explicit category for mishandling exceptional conditions reinforces this point: failure paths deserve design attention equal to normal paths.

4.2 Network discovery tells us what the architecture actually is

It is dangerous to assume that the architecture diagram and the running network are identical. Port and service discovery routinely expose facts missing from documentation: an old administration port, a database listener exposed externally, an obsolete SSH service, a temporary HTTP endpoint left behind, or a device placed in the wrong VLAN.

Nmap is useful here not because "running Nmap equals penetration testing" but because it helps compare intended exposure with actual exposure. The question is whether every reachable service has a justified owner, protocol, source network, authentication mechanism, and patch lifecycle.

5. Threat Modeling: Search for Attack Paths Before Writing Code

Threat modeling becomes valuable when it is treated as an engineering activity rather than a document produced for an audit. Its purpose is to expose assumptions while changing the design is still inexpensive.

A practical model begins with four things:

  1. assets,
  2. data flows,
  3. trust boundaries,
  4. attacker capabilities.

If one of these is vague, the resulting threat list tends to be vague as well.

5.1 Data-flow diagrams and trust boundaries

Trust boundary and data-flow diagram
Trust boundary and data-flow diagram

Consider an upload path:

Browser
   |
   | HTTPS
   v
API Gateway
   |
   v
Upload Service
   |
   +------> Object Storage
   |
   +------> Antivirus / Content Analysis
   |
   +------> Metadata Database

Each transition asks a security question. Can the browser choose the physical object name? Does the gateway enforce body-size limits? Can the upload service write outside its assigned bucket? Does the content analyzer process the file with dangerous privileges? Is metadata trusted merely because it came from another internal component? Can a file become downloadable before scanning completes?

Drawing the flow reveals controls that a list of endpoint names will not.

5.2 STRIDE as a thinking tool

STRIDE remains useful when applied to concrete flows rather than as a ritual acronym:

  • Spoofing: can an attacker impersonate another identity?
  • Tampering: can data or a request be modified without authorization?
  • Repudiation: can a critical action occur without reliable attribution?
  • Information Disclosure: can protected information leak?
  • Denial of Service: can an actor exhaust the service or a dependency?
  • Elevation of Privilege: can an actor gain more authority than intended?

The point is not to generate six findings for every component. The point is to force review from distinct failure perspectives.

5.3 Attack trees and graph reasoning

For a critical objective such as "read another tenant's confidential document," a tree may look like this:

Read another tenant's document
 |
 +-- obtain a privileged account
 |     +-- password spraying
 |     +-- phishing
 |     +-- credential reuse
 |
 +-- bypass authorization
 |     +-- BOLA / IDOR
 |     +-- mass-assignment role change
 |     +-- alternate export endpoint
 |
 +-- reach storage directly
       +-- leaked storage credential
       +-- public bucket/container
       +-- SSRF through internal metadata or storage endpoint

This representation changes remediation priorities. A finding may be moderate in isolation but strategically important because it joins two otherwise disconnected parts of the graph.

6. Risk Prioritization: Close the Most Dangerous Path, Not the Largest Number of Findings

Scanner output can contain hundreds of findings. Treating them as a queue sorted exclusively by severity produces poor engineering decisions.

Risk should include at least:

  • exploitability,
  • required attacker position,
  • privilege required,
  • user interaction,
  • asset value,
  • confidentiality/integrity/availability impact,
  • blast radius,
  • detectability,
  • compensating controls,
  • exposure duration,
  • whether the weakness composes with other weaknesses.

A remotely exploitable issue on a public identity service deserves different priority from the same weakness on a laboratory host that contains no production data. Conversely, an apparently low-severity credential leak may deserve immediate action if it exposes a highly privileged service account.

CVSS, CWE, OWASP, MITRE ATT&CK, and an organization's own risk model solve different problems. CVSS standardizes technical severity; CWE describes weakness classes; ATT&CK organizes adversary behavior into tactics and techniques; OWASP groups application-security risks; business impact is known only in the context of the organization operating the system.

7. Secure Architecture: Make the Attack Difficult Before It Reaches the Code

The security advantage of good architecture is that it does not assume every developer will write every line perfectly. People make mistakes. Secure architecture limits the ability of one mistake to become a system-wide compromise.

7.1 Least privilege

Least privilege database and application boundary
Least privilege boundary

A service that reads three tables and writes one table does not need DDL permission across the entire schema. A background job that writes to one object store should not have access to all storage. A container that does not require root privileges should not run as root. A user who only reads reports should not reach administrative endpoints.

Least privilege is not a vague instruction to "reduce permissions." It is the engineering task of defining the smallest privilege set required for the function.

Violating this principle turns small vulnerabilities into large incidents. SQL injection that could otherwise read a limited set of rows may reach administrative operations because the application database account is overprivileged. Remote code execution in an application process becomes an operating-system compromise if that process runs as root. Compromise of a domain service account becomes lateral movement if that account has unnecessary administrative membership.

7.2 Separation of duties and privileges

Using one account for development, deployment, database administration, and production operations may look efficient, but it turns one identity into the master key of the system.

Separation can be established at several levels:

  • developer and production-operations roles,
  • application and database-administration identities,
  • read and write services,
  • release signing and artifact production,
  • daily-use and privileged administration accounts,
  • dual control or step-up authentication for critical operations.

Separation is not only a defense against attackers. It also limits the effect of an incorrect command, faulty automation, and insider risk.

7.3 Defense in depth

Defense in depth does not mean deploying the same control five times. It means using controls that fail for different reasons.

For an API, for example:

Network access restriction
    + strong authentication
    + object-level authorization
    + input validation
    + parameterized queries
    + least-privileged database account
    + security logging and alerting

If an SQL injection flaw is introduced accidentally, the limited database account reduces impact; anomalous query behavior may still be visible; backups and incident response provide recovery options. The value of the layers comes from their independence from the same assumption.

7.4 Secure defaults

One of the important ideas in CISA's Secure by Design work is that the burden of basic security should not be transferred to the customer. A product that installs with a default password, an open administration port, or MFA disabled until the customer discovers an obscure setting does not provide a secure default.

The easiest path should be the secure path. When security becomes a paid add-on or a feature activated only through dozens of hidden settings, a significant fraction of real deployments will remain insecure.

7.5 Fail securely

If an authorization service becomes unavailable and the application grants access so that "work can continue," it has failed open. Some high-availability designs may deliberately accept controlled exceptions, but that must be an explicit risk decision.

Failure paths should answer questions such as:

  • What happens when the identity provider is unavailable?
  • Does a connection continue if a certificate cannot be validated?
  • If the authorization service times out, is the result allow or deny?
  • If the logging disk fills, does the application stop or silently skip logs?
  • If the rate-limit store fails, does the rate limit disappear?
  • If a signature-verification key cannot be found, is the token accepted?

Attackers do not use only the happy path. Failure conditions are part of the attack surface.

8. Secure Development Life Cycle: Do Not Leave Security Until the End

When a completed application is handed to a security team with the instruction "find the vulnerabilities," security is already at its most expensive point. If the finding is architectural, remediation may affect not only code but the API contract, data model, clients, and deployment topology.

NIST SSDF 1.1 groups secure-development practices into four broad areas: prepare the organization, protect the software, produce well-secured software, and respond to vulnerabilities. Translated into day-to-day engineering, the flow becomes:

Requirement
   -> threat modeling
   -> security acceptance criteria
   -> architectural decision
   -> secure coding
   -> code review
   -> automated analysis
   -> security testing
   -> trustworthy build
   -> controlled deployment
   -> observability
   -> vulnerability management
   -> root-cause analysis
   -> new requirement

The final arrow matters. If the same weakness class appears for the third time, the organization has not merely closed three bugs; it has exposed a systematic defect in its development process.

8.1 Security acceptance criteria

A user story is not complete merely because the intended feature works. It needs security acceptance criteria as well.

Example: "A user can download their own document."

Security criteria may include:

  • changing the object identifier must not return another user's document,
  • identity must not be derived from a client-supplied userId,
  • authorization must occur before the file is read,
  • the physical file path must not be constructed directly from user input,
  • the access event must be recorded in an auditable form,
  • the error response must not unnecessarily reveal whether an unauthorized file exists.

When these criteria are written before penetration testing, security stops being a hidden property that we wait for a tester to discover.

Unit 2: Identity, Authorization, Sessions, and Cryptography

9. Authentication: A Larger Problem Than a Password Field

An early-exit string comparison leaking the matching prefix length through timing so that an 8-byte secret falls to about 2048 guesses while a constant-time comparison avoids the leak
Timing side channel in comparison

Authentication is not only the question "are the username and password correct?" Enrollment, identity proofing, authenticator binding, sign-in, MFA, session creation, recovery, password reset, device loss, and account termination form a single life cycle.

A strong login screen can still be bypassed through a weak password-reset flow. If the answer to a security question can be recovered from social media, the "recover account" link next to MFA becomes the attacker's preferred path.

9.1 Password policy: from complexity theatre to a cost model

For years password policies were built around uppercase letters, lowercase letters, digits, symbols, and periodic rotation. Current NIST SP 800-63B-4 guidance moves away from that model. For passwords used as a single authentication factor it requires a minimum of 15 characters; when a password is used as part of MFA it permits a minimum of 8, recommends support for at least 64 characters, rejects arbitrary composition rules and forced periodic changes without evidence of compromise, and calls for blocking commonly used, expected, or compromised passwords together with rate limiting against online guessing.

This reflects the attacker's real cost. Password1! may satisfy a composition rule and still be weak. A long and unique password, a password manager, a breached-password blocklist, secure storage, and appropriate rate limiting are more meaningful together.

9.2 Password storage

A password is not data that should be encrypted so that it can later be decrypted. Verification should use a one-way, tunably expensive password hashing/KDF algorithm. Fast general-purpose hashes such as SHA-256 are unsuitable for password storage because they allow an attacker to make too many guesses per second.

OWASP's Password Storage Cheat Sheet currently recommends Argon2id as a primary choice. Its parameters should be measured on production-class hardware. The objective is to keep legitimate authentication latency acceptable while raising the cost of offline guessing.

password
   + unique salt
   + cost parameters
   -> Argon2id / suitable password KDF
   -> stored verifier

If a pepper is used, it belongs in a secret-management system separate from the database. Storing the database password and the pepper in the same configuration file defeats the intended separation.

9.3 The limits of MFA

MFA does not solve every authentication threat. SMS factors can be affected by SIM-swap and telecommunications attacks. TOTP codes can be stolen through real-time phishing proxies. Push notifications can be abused through notification fatigue. Phishing-resistant authenticators are more valuable precisely because they change these attack conditions.

The correct question is not "is MFA enabled?" but which authenticator is being used against which threat, and does the recovery path preserve the same assurance?

9.4 Password spraying and account lockout

Password spraying, familiar from Active Directory and CrackMapExec-style exercises, differs from classical brute force. Instead of trying many passwords against one account, the attacker tries a small number of likely passwords across many users. A simple per-account lockout policy does not always detect this pattern because the attacker can remain below the threshold.

Defensive analysis should therefore correlate failed logins by source, target population, time window, and behavior pattern rather than only by individual account. MFA, compromised-password blocklists, disabling obsolete authentication protocols, and correct service-account management further reduce the available attack surface.

10. Authorization: Being Authenticated Does Not Mean Being Allowed

One of the most persistent application-security failures is treating authentication and authorization as if they were the same thing. Knowing who a user is does not prove that the user may perform a particular operation on a particular object.

Assume an API receives:

GET /api/documents/73152
Authorization: Bearer <token>

The token may be valid and the user may be legitimately authenticated. If document 73152 does not belong to that user, the request must still be denied. Hiding a Documents link in a menu, disabling a button in JavaScript, or checking a role only in the client does not replace server-side authorization.

10.1 Object-level authorization

A robust pattern is to carry the authorization scope into the resource query itself:

SELECT id, name, content
FROM document
WHERE id = ?
  AND owner_id = ?;

The second parameter is not an ownerId sent by the client; it is derived from the authenticated identity context. More complex systems may use RBAC, ABAC, or a policy engine. The principle remains the same: actor, action, and object are evaluated together.

10.2 Deny by default

If a newly added endpoint becomes accessible to everyone because its authorization rule was forgotten, the system has a dangerous default. Authorization should be designed so that access is denied unless it is explicitly allowed.

This matters especially in large systems. Manual checks are manageable for a few endpoints; in a system with hundreds of routes, message consumers, and background jobs, one forgotten control can become a production vulnerability.

10.3 Horizontal and vertical privilege escalation

Horizontal privilege escalation means accessing another user's resource at the same privilege level. Vertical privilege escalation means performing an operation reserved for a more privileged role.

They should be tested separately:

  • Can user A read user B's object?
  • Can a normal user call an administrative endpoint?
  • Can a read-only user write?
  • Can one tenant access another tenant's objects?
  • Does a bulk endpoint bypass checks enforced by the single-object endpoint?
  • Are export, search, history, and attachment paths protected as strongly as the primary object?

Many authorization bugs live in secondary functionality rather than the main CRUD endpoint.

11. Session Security: Carrying Identity from One Request to the Next

HTTP is stateless. After a user authenticates, a session identifier or token is needed so subsequent requests can be associated with that identity. If that value is compromised, an attacker may act as the user without knowing the password.

A session identifier is therefore a secret.

For browser applications using cookies, at least the following should be evaluated:

  • Secure: transmit only over HTTPS,
  • HttpOnly: restrict direct JavaScript access to the cookie,
  • SameSite: control cross-site request behavior,
  • appropriate Domain and Path: avoid unnecessary scope,
  • rotate the session ID after authentication,
  • invalidate the session server-side on logout,
  • enforce absolute and inactivity timeouts.

HttpOnly does not solve XSS. It narrows one cookie-theft path. With XSS, an attacker may still perform actions in the user's origin and security context. Defense in depth should not be mistaken for a complete cure.

11.2 JWT: signed does not mean safe

JWT is not an authentication protocol; it is a token format that can carry claims. Signature verification is mandatory but insufficient. A resource server should verify at least:

  • the expected signature algorithm,
  • the trusted key,
  • the issuer (iss),
  • the intended audience (aud),
  • expiration (exp),
  • nbf where relevant,
  • the semantics of authorization claims,
  • key rotation and revocation strategy.

JWT payloads are Base64URL-encoded, not secret. Passwords, private keys, and unnecessary personal data do not belong in them.

Asymmetric signatures allow resource servers to hold verification keys without possessing signing keys. This separation is valuable in microservice architectures. Even so, the signature cannot help after a long-lived bearer token has been stolen. Token lifetime, refresh strategy, audience restriction, transport channel, and step-up authentication for sensitive operations must be designed together.

12. Cryptography: Key Management Matters More Than Algorithm Names

RSA public-key flow and key roles
RSA public-key flow

Cryptography is fundamental to secure systems, but when it is applied incorrectly it may produce little more than confidence. Saying that data is protected by AES says almost nothing by itself. Mode of operation, nonce/IV generation, key length, key storage, integrity, rotation, backups, and the access model all matter.

12.1 Encryption, hashing, MACs, and signatures solve different problems

Digital signature flow separating hashing private-key signing and public-key verification
Digital signature flow
  • Encryption: Confidentiality
  • Cryptographic hash: Fixed-length digest of data; does not authenticate by itself
  • **HMAC/MAC:** Integrity and source authentication with a shared secret
  • Digital signature: Integrity and signer authentication using public/private keys
  • Password KDF: Make password guessing expensive

Unsafe-deserialization exercises often introduce the idea of attaching an HMAC to serialized data before it is returned to a client. This teaches an important distinction: integrity and confidentiality are not the same property. HMAC does not hide the data; it detects unauthorized modification. More importantly, if untrusted input does not need to become a native object graph at all, the better design is to use a constrained data representation. Cryptographic verification should not be used to justify a dangerous parser or object-instantiation model.

12.2 Do not design your own cryptography

Understanding cryptographic primitives is essential; assembling a production protocol by saying "AES + SHA-256 + Base64" is not. Use established protocols and well-reviewed libraries.

Disabling certificate validation in TLS can nullify the value of strong encryption. Certificate-pinning bypass exercises on mobile systems make the underlying question visible: where does the client make its trust decision, and on what evidence? Pinning may provide additional defense against particular threats, but the fundamental trust model should begin with correct standard certificate validation. Test-only TrustAll code that reaches production turns TLS into an encrypted tunnel to an identity that has not actually been verified.

12.3 Secret management

Secrets should not be left in:

  • source code,
  • Git history,
  • client applications,
  • Docker image layers,
  • CI logs,
  • error responses,
  • generally readable configuration files,
  • environment-variable dumps visible to too many users,
  • support bundles and diagnostic dumps.

When a secret leaks, deleting the file is not enough. The secret must be treated as compromised and rotated. Removing a key from the latest Git commit does not retrieve it from every clone or cache that may already contain it.

Unit 3: Untrusted Data and the Application Attack Surface

Processing untrusted input begins by identifying the trust boundary and the grammar in which the value will be interpreted. Validation, canonicalization, and context-appropriate output encoding are not interchangeable. When data enters SQL, HTML, or a command context, use the interpreter's parameterization or safe interface. Security tests should cover boundary characters and encoding variations, not merely familiar attack strings.

13. Untrusted Data: A Common Root of Many Attacks

Calling data "from my frontend," "from my database," "from my message queue," or "from the internal network" does not make it trustworthy. Trust should be evaluated at the boundary where data is consumed, not merely by where it was stored previously.

A browser request can be modified. A mobile client can be reverse engineered and client-side checks bypassed. A database row may contain payloads written by an earlier XSS vulnerability. A message queue can contain data produced by a compromised service. A file name may be attacker-controlled. An LDAP attribute may have been populated by an external system.

At every interpreter boundary, two questions should become habitual:

  1. What forms of data are accepted?
  2. In what context will that data be used?

The first is primarily an input-validation problem. The second is often a problem of context-appropriate safe APIs, encoding, or interpretation.

13.1 Allowlist thinking

"Remove dangerous characters" is a weak long-term strategy. A denylist attempts to predict every dangerous representation. Unicode normalization, multiple encodings, canonicalization differences, parser discrepancies, and newly introduced syntax make that difficult to sustain.

If a field is a UUID, accept a UUID. If a page number is a positive integer, parse it as an integer and enforce the range. If a value is an enum, reject values outside the defined set. If a file type affects a security decision, do not infer it only from the extension; evaluate content, MIME type, and processing behavior together.

Validation defines the application's accepted data domain. It does not by itself solve injection. SQL still needs parameterized queries; HTML still needs context-sensitive output encoding or APIs that avoid interpreting text as markup.

14. Injection: When Data Becomes a Command

Injection attacks have different names, but their root failure is similar: externally influenced data is incorporated into command or code syntax.

14.1 SQL injection

String concatenation letting the input create an extra OR keyword and change the SQL structure while a bind variable keeps the whole input as one value token
SQL injection tokens and bind variables

The vulnerable mental model looks like this:

String sql = "SELECT id, role FROM users WHERE username = '" + username + "'";

The defect is more than the single quote. User-controlled data has been concatenated into SQL syntax. Trying to escape every edge case correctly across SQL dialects, encodings, and future code changes creates unnecessary risk.

The security boundary should be structural:

PreparedStatement ps = connection.prepareStatement("SELECT id, role FROM users WHERE username = ?");
ps.setString(1, username);

The query structure and its data travel through distinct channels. That separation is the principle; PreparedStatement is one implementation mechanism.

When an identifier such as a table name, column name, or ORDER BY direction cannot be parameterized, the application should map a small, fixed allowlist of choices to known SQL fragments instead of concatenating arbitrary input.

A second layer is least privilege at the database account. If an injection flaw still appears, a narrowly privileged application identity can constrain its impact.

14.2 Operating-system command injection

Building a shell command to transform a file and concatenating an attacker-controlled file name is the same design error expressed through another interpreter. Whenever possible, call a library or process API directly and pass arguments separately. Adding an extra interpreter layer such as sh -c increases the number of syntactic contexts that must be controlled.

The strongest defense is often not "better escaping" but removing the interpreter from the path.

14.3 LDAP, template, and expression-language injection

LDAP filter injection, expression-language injection, server-side template injection, and related classes fit the same model. During development, it is useful to ask: which parser or interpreter will consume this string next?

A value can pass successively through URL, JSON, HTML, and JavaScript contexts. Each boundary has different escaping and semantic rules. One universal sanitize() function cannot make every context safe.

15. XSS: A Context Problem, Not a Character-Filtering Problem

Older training material often demonstrates XSS using a payload such as <script>alert(...)</script> and proposes removing certain tags as the remedy. That is useful as an introduction to the symptom, but it is not a modern defense model.

The central question is where untrusted data is inserted. HTML text, HTML attributes, URLs, CSS, JavaScript literals, and DOM APIs are not interchangeable contexts. A string safely encoded for one context can be dangerous in another.

The preferred approach is to avoid constructing executable markup from untrusted strings. Template engines that escape by default and DOM APIs such as textContent reduce ambiguity. When HTML is intentionally accepted, sanitization must operate with a well-understood HTML parser and an allowlist policy appropriate to that application.

15.1 DOM XSS

DOM XSS shows why server-side filtering alone cannot define the security boundary. Client-side code can read attacker-influenced data from location fragments, query strings, postMessage, storage, or API responses and pass it into unsafe sinks such as innerHTML, outerHTML, document.write, dynamic script construction, or string-based timer/evaluation APIs.

The useful review pattern is a source-to-sink analysis:

attacker-controlled source
       -> transformations
       -> DOM / script sink
       -> executable interpretation?

The safe fix is usually to select an API whose semantics match the intended data rather than trying to sanitize arbitrary strings after the fact.

15.2 CSP is a defensive layer

Content Security Policy can restrict script sources, inline execution, framing, object loading, and other browser behavior. A strict nonce- or hash-based CSP can substantially increase the cost of exploiting certain XSS flaws.

CSP should nevertheless be treated as defense in depth, not permission to retain unsafe rendering code. Weak policies containing broad wildcards, unsafe-inline, or unnecessary origins often create an illusion of protection while preserving most of the attack surface.

15.3 XSS remains serious even when cookies cannot be read

An HttpOnly session cookie may not be directly accessible to JavaScript, but malicious code executing in the origin can still perform authenticated actions, read page data available to that origin, modify forms, capture inputs, invoke APIs, or manipulate user decisions. Preventing cookie theft addresses one consequence, not the vulnerability class.

Output encoding is context-dependent. An HTML text node, HTML attribute, URL component, and JavaScript string do not share one universal escaping rule. A value safely rendered as HTML text is not necessarily safe when inserted into an event-handler attribute or executable script. Using APIs such as textContent for dynamic text avoids invoking the HTML interpreter unnecessarily. URLs, styles, and other contexts still require their own validation and safe-sink contracts.

16. CSRF and CORS: Similar Acronyms, Different Trust Boundaries

CSRF exploits the browser's tendency to attach ambient credentials such as cookies to requests. If a state-changing endpoint accepts such a request without proving that it originated from the intended application flow, another site can cause the user's browser to perform the action.

Defenses depend on the authentication model and may include:

  • SameSite cookie policy,
  • anti-CSRF tokens bound to the session,
  • Origin/Referer validation where appropriate,
  • avoiding state-changing GET requests,
  • requiring explicit re-authentication for high-risk operations.

CORS solves a different problem. It controls whether browser script from one origin may read or issue certain cross-origin requests under the browser's same-origin policy. CORS is not an authorization mechanism. Granting Access-Control-Allow-Origin: * does not make a private API public by itself, and restricting CORS does not stop non-browser clients from calling an endpoint they can reach.

The distinction is practical: CSRF concerns unwanted authenticated actions performed through a victim browser; CORS governs browser-origin access policy.

17. SSRF: Lending the Server's Network Position to an Attacker

Server-Side Request Forgery appears when the application fetches a URL or network resource influenced by an attacker. The danger is not only that the server retrieves content; the server may possess network reachability and identities that the attacker does not.

A vulnerable service can become a pivot to:

  • loopback-only administration interfaces,
  • internal APIs,
  • metadata services,
  • internal DNS names,
  • storage endpoints,
  • services protected only by network location.

A robust defense starts by asking whether arbitrary outbound requests are required at all. If the function only needs to reach a small number of known services, use an allowlist of destinations and protocols. Resolve and validate addresses carefully, account for redirects and DNS rebinding, and enforce outbound network policy so that the application process cannot reach unnecessary ranges or ports.

The deeper lesson is architectural: "not exposed to the Internet" is not a sufficient authorization model for an internal service.

18. Path Traversal and File Upload: A File Name Is Not Just Data

Path canonicalization and prefix checking with computed steps and state transitions
Path canonicalization and prefix checking

Combining a base directory with user-controlled strings can create path-traversal behavior through ../, absolute paths, alternate separators, encoded forms, or platform-specific path semantics. Normalization and canonical-path checks are useful, but the stronger design is to avoid deriving physical storage paths directly from user-provided names.

File uploads should not be secured only by checking extensions. At least the following dimensions may matter:

  • permitted file types,
  • content validation,
  • size and count limits,
  • server-generated storage names independent of the user-supplied name,
  • storage outside the web root,
  • no execute permission,
  • safe transcoding or re-encoding for images/media where suitable,
  • malware or content analysis where required,
  • correct Content-Type and Content-Disposition on download,
  • authorization re-evaluated on every download.

An upload endpoint is not a single operation. It is a chain of parsing, storage, analysis, transformation, and serving. A weakness in any stage can become the useful stage for an attacker.

19. Unsafe Deserialization: The Cost of Turning Data into an Object Graph

Serialization converts objects into a portable or storable representation. The dangerous boundary appears when untrusted bytes are turned back into powerful native object graphs. In some environments, construction, magic methods, callbacks, or gadget chains can create behavior far beyond simple data restoration.

Examples from PHP, Python pickle/YAML, Java, and .NET teach a platform-independent rule: do not transform untrusted input into a behavior-capable native object graph unless the format and type system are deliberately constrained.

A safer design favors a narrow data schema:

{
  "userId": 42,
  "theme": "dark",
  "language": "en"
}

JSON is not automatically safe; parser options, depth limits, polymorphic binding, and type-resolution features still matter. Yet a schema containing only required primitive values exposes far less behavior than arbitrary class instantiation.

HMACs and digital signatures are useful when the system needs to verify the producer and integrity of serialized data. They are not a substitute for a safe data model. A signed dangerous format remains dangerous if the key leaks, a trusted producer is compromised, or another trusted component generates malicious content unintentionally.

20. API Security: Protect Business Logic, Not Only the Protocol

API security is not a collection of HTTP headers. Modern applications expose much of their business logic through APIs, including functions that may not be visible in the normal user interface.

Five questions form a useful review frame for each endpoint:

  1. Who calls it? How is identity established?
  2. What may that actor do? Is authorization checked against both object and action?
  3. What may be sent? Are schema, size, format, and semantic limits defined?
  4. How often may it be called? What is the resource and automation budget?
  5. What can the caller learn? Do responses, errors, status codes, and timing leak unnecessary information?

20.1 Mass assignment

Binding arbitrary client JSON directly to a domain object can expose fields the UI never intended the user to change:

{
  "displayName": "Ali",
  "role": "ADMIN",
  "approved": true
}

The fact that the standard interface sends only displayName is irrelevant; an attacker writes their own HTTP request. DTO/command objects should express only the fields a caller is allowed to control. Sensitive state should be derived from server-side rules.

20.2 Rate limiting is not only a DoS control

Rate limits raise the cost of password guessing, OTP attempts, username discovery, expensive report generation, bulk extraction, scraping, and automated abuse. A fixed rule such as "100 requests per IP" does not solve every case. NAT, distributed botnets, authenticated identity, action type, and endpoint cost all affect the correct model.

A password endpoint and a static-content endpoint should not share the same resource budget merely because both use HTTP.

21. The Data Layer: More Than Injection

Database security often begins and ends with SQL injection in introductory material. Production data layers are broader: identities, network paths, schema privileges, auditing, backups, replication, retention, bulk export, and administration tooling all belong to the same trust domain.

21.1 Separate application and administrative identities

The runtime application account should not be the schema owner or DBA. Its DML privileges should be restricted to operations required by the application. Schema migrations should use a separate identity and a controlled deployment stage.

This has two effects. First, compromise of application logic has a smaller blast radius. Second, incorrect application code is less able to damage the schema accidentally.

21.2 The database network boundary

An Internet-facing application does not imply that the database listener should be Internet-facing. Required application-to-database flows should be explicit. Administrative access can be separated through management networks or bastions. A strong password is not a reason to preserve unnecessary reachability.

21.3 A backup is production data too

A live database may be encrypted, access-controlled, and heavily audited while its daily backup is written to a broadly readable share. In that case, the real confidentiality of the system is no stronger than the backup path.

Backups should be evaluated for:

  • access control,
  • encryption and separation of keys,
  • integrity verification,
  • immutable or offline copies where required,
  • restoration testing,
  • retention periods,
  • secure deletion,
  • masking before movement into test environments.

In ransomware incidents the useful property is not "a backup exists." It is a restorable, verified backup that the attacker could not alter together with production.

22. Memory Safety: From a Few Bytes to Process Control

The enduring value of classic material such as The Shellcoder's Handbook is not that every historical exploit still works unchanged. Its value is in showing how a memory error can interact with a machine's execution model.

In C and C++, array bounds, pointer lifetime, integer conversion, format-string handling, and use-after-free defects may do more than crash a program. Under suitable conditions they can let an attacker influence memory layout, redirect data, or alter control flow.

22.1 What a stack overflow teaches

Stack buffer overflow overwriting the return address and detection by a stack canary
Stack overflow and canary

A classic stack overflow writes beyond a fixed-size buffer. Historical demonstrations overwrite a saved return address, redirect the instruction pointer, and execute shellcode.

Modern systems add mitigations such as:

  • stack canaries,
  • NX/DEP,
  • ASLR,
  • PIE,
  • RELRO,
  • forms of Control-Flow Integrity,
  • hardware-assisted control-flow protections,
  • hardened compiler options.

Their existence does not make buffer overflows harmless. It changes exploitation strategy and cost; the memory-corruption defect remains.

22.2 Exploit mitigation is not the first layer of defense

A canary or ASLR cannot be the primary defense because it does not remove the bug. The first objective is to avoid producing the memory error:

  • bounded buffer operations,
  • correct integer and length validation,
  • explicit ownership and lifetime models,
  • fuzzing,
  • sanitizers,
  • static analysis,
  • safer standard-library components,
  • memory-safe languages for components where the trade-off is appropriate.

Mitigations form a second layer. If a defect escapes, they increase the work required to turn it into reliable exploitation.

22.3 Heap corruption, use-after-free, and complex memory defects

Heap overflows and use-after-free defects are less intuitive than classical stack overflows. Exploitability depends on allocator behavior, metadata structures, object placement, and timing. Defensively, source-level lifetime discipline, ownership models, safer containers, and dynamic analysis become increasingly important.

One of the most valuable lessons from exploit-development practice is that "the program crashes" does not end the security analysis. A crash that can be reproduced deterministically with attacker-controlled input should be examined for corruption of instruction pointers, function pointers, object metadata, indexes, lengths, or other security-critical state.

23. Reverse Engineering: A Secret Stored in the Client Is Not a Secret

The tradition represented by Reversing: Secrets of Reverse Engineering is not limited to reading assembly. It teaches how to inspect an application's security assumptions at binary level.

The following assumptions are unsafe in mobile or desktop clients:

  • "The API address is hidden; it cannot be found."
  • "The administrator button is not visible, so the operation cannot be called."
  • "The key is embedded in the binary."
  • "License validation runs locally, so the user cannot alter it."
  • "Certificate pinning prevents traffic inspection."
  • "The code is obfuscated, so the business logic is secure."

The attacker owns the execution environment. They may use static analysis, debuggers, API hooking, instrumentation, emulation, or memory inspection. Client security should therefore be designed under the assumption that the client itself is hostile.

23.1 Obfuscation is not a trust boundary

Obfuscation can increase reverse-engineering cost and may be useful for intellectual-property protection or resistance to automated analysis. It cannot replace server-side authorization. A long-lived shared secret embedded in a client binary should be considered recoverable given enough time and motivation.

23.2 The place of reverse engineering in security testing

Reverse engineering is especially useful for questions such as:

  • Which endpoints does the client call?
  • Were debug or test functions left behind?
  • Is certificate validation actually enforced?
  • In what form is sensitive data stored locally?
  • Are tokens or passwords present in local databases?
  • Do native libraries contain memory-safety defects?
  • Has an authorization decision that belongs on the server been delegated to the client?

The purpose is more than to "crack" a binary. It is to identify security responsibilities that a client cannot reliably carry.

Protecting request surfaces by trust and cost class

DoS defense is not merely a count of requests per second. The same request rate can have radically different cost for a static asset and for a dynamic operation that consumes database or remote-service capacity. A useful protection model therefore considers two dimensions together: the trust context of the request and the scarce resources consumed by the work.

request
  |
  +--> identity / trust class
  |
  +--> cost class
           |
           v
    rate + concurrency budget
           |
           v
       application

A rate limit bounds how much work is accepted over time; a concurrency limit bounds how much expensive work is inside the system at once. They are not substitutes. Thousands of very short requests may be a rate problem, while a much smaller number of long-running operations can exhaust connection or execution capacity through concurrency alone. A robust protection layer measures both behaviors separately.

Authenticated and anonymous traffic also need not share exactly the same failure budget. Authentication is not a guarantee of benign behavior, but service contracts and priorities can differ. Bulkheads can keep critical session work from being starved by anonymous discovery or expensive public paths. The authenticated path should not become unbounded, however, because downstream resources still have physical capacity limits.

Security policy should also include environment context. A missing protection setting may justifiably prevent startup in production while being irrelevant to a development or connection-free validation environment. This is not a relaxation of the threat model; it is an explicit definition of where the threat applies. Environment decisions should be concentrated in an observable policy boundary rather than scattered through business code.

The overload response itself belongs to the attack surface. Generating an expensive error document, writing excessive logs, or invoking an external dependency for every rejected request can turn the defense into a new bottleneck. Rejection paths should be cheaper and more deterministic than normal work. Rate limiting, threat modeling, and Software Test Engineering complete the measurement and verification side of this design.

Unit 4: Operating System, Network, Mobile, and Supply Chain Security

24. Operating-System Security: The Layer Beneath the Application

An application can be carefully designed and still inherit an excessive attack surface from the operating system through unnecessary services, broad privileges, weak file permissions, or poor patch hygiene.

24.1 Run the process with as little power as possible

A web service that does not need root privileges should not run as root. On Linux, systemd and related kernel controls can provide additional isolation:

[Service]
User=app
Group=app
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true

Depending on the service, additional controls such as ReadWritePaths, capability bounding, syscall filtering, namespaces, or sandboxing may be appropriate. Hardening options should not be copied blindly. Measure the service's required behavior and grant only what it actually needs.

24.2 File permissions

If a secret file must be read only by a service identity, mode 0644 is too broad. If logs contain sensitive data, they should not live in directories readable by everyone. If the application never needs to modify its binaries or configuration, the runtime identity should not have write permission there.

These apparently small permission decisions often determine how far an attacker can progress after obtaining code execution.

24.3 Patch management

The reflex "do not touch a working production system" is understandable in critical environments, but leaving systems unpatched for years is not a security strategy either. The engineering answer is controlled updates backed by testing, staged rollout, inventory, and rollback plans.

Patch decisions should consider:

  • Is the affected component actually present and used?
  • Is the vulnerable functionality reachable in our configuration?
  • Is a public exploit known or active exploitation observed?
  • At which trust boundary does the component operate?
  • Are compensating controls present?
  • What is the operational risk of the update itself?

Risk acceptance should be recorded and time-bounded. "We are not touching it for now" must not silently become indefinite postponement.

25. Active Directory: An Identity System Is Also an Attack Graph

In an Active Directory environment, users, computers, groups, sessions, ACLs, GPOs, service accounts, delegation, and trust relationships must be evaluated together. BloodHound's graph model makes this complexity visible.

A user not being a direct member of Domain Admins does not prove that the user has no path to administrative authority. User A may be able to modify Group B; Group B may have local-administrator rights on Computer C; and Computer C may host a Domain Admin session. From the attacker's perspective, what matters is not direct membership but reachability through relationships.

25.1 BloodHound is not only a red-team tool

BloodHound can be used defensively to identify attack paths before an adversary does. Useful questions include:

  • What are the shortest paths to high-value assets?
  • Which users or groups are unexpectedly central in the graph?
  • Which service accounts are overprivileged?
  • Which logged-on sessions enlarge identity attack paths?
  • Do ACLs create hidden privilege-escalation paths?
  • Which GPO, delegation, or trust relationships create unintended reachability?

Periodic graph comparison can reveal whether a new group membership or ACL change has silently created a path that did not exist before.

25.2 Understand Kerberos as a protocol

Kerberos is more than "Windows authentication with tickets." Ticket Granting Tickets (TGTs), service tickets (TGS), the KDC, SPNs, principals, and key material need to be understood together before Kerberoasting, AS-REP Roasting, ticket reuse, or forgery can be assessed correctly.

The defensive lesson of Kerberoasting is straightforward: a service account's credential material can become subject to offline password guessing. Long, random, managed service credentials matter; Group Managed Service Accounts and similar mechanisms reduce manual password-lifecycle weaknesses; obsolete encryption types and unnecessary SPNs should be reduced where operationally possible.

AS-REP Roasting shows why accounts with Kerberos pre-authentication disabled deserve special scrutiny. Legacy configuration that remains because "it still works" can preserve an attack surface inside the identity system for years.

25.3 What Pass-the-Hash and Pass-the-Ticket teach

An attacker does not always need the cleartext password. If the authentication mechanism accepts a hash-derived credential or a valid ticket, possessing that artifact may be enough to authenticate or move laterally.

That invalidates the assumption "they did not recover the password, therefore the identity is safe." Credential Guard and related memory protections, separate administrative accounts, avoiding privileged logons on low-trust workstations, reducing NTLM/legacy SMB dependencies, and modern identity controls each address part of the problem.

25.4 krbtgt and the domain trust root

One of an Active Directory domain's most critical secrets is associated with the krbtgt account. Compromise at this level is not equivalent to losing an ordinary user's password and cannot be remediated by simply changing that user's credentials. Incident response must consider the domain's trust model and ticket lifetime.

This is why critical identity material should be classified separately in the asset inventory. Not all passwords are equal; compromise of some secrets affects an entire security domain.

26. Network Security: Do Not Build Assumptions Without Looking at Packets

Working with Wireshark and tcpdump reduces network security from an abstract diagram to actual packets. Even when an application is said to "use HTTPS," observing DNS queries, route selection, the TLS handshake, redirects, peer identity, retransmissions, and connection behavior can expose assumptions that documentation hides.

26.1 Why packet analysis still matters

Even when application payloads are encrypted, metadata remains valuable:

  • source and destination,
  • port and protocol,
  • connection frequency,
  • TCP flags,
  • packet sizes,
  • DNS requests,
  • TLS handshake metadata,
  • retransmissions,
  • connection establishment and teardown behavior.

A behavior not recorded at the application layer may still be visible on the network. Conversely, interpreting an unusual network pattern often requires application context. Neither layer replaces the other.

26.2 Segmentation

A flat network gives an attacker broad room for lateral movement. The purpose of segmentation is not to increase the number of VLANs; it is to enforce trust boundaries in the network topology.

For example:

Internet -> Reverse Proxy: 443
Reverse Proxy -> Application: 8443
Application -> Database: 5432
Application -> Identity Service: 443
Management Network -> Servers: management ports
Everything else: deny

This policy should address egress as well as ingress. If an application server with RCE can connect to every internal port and every Internet address, the attacker's post-exploitation options expand dramatically.

26.3 A firewall does not repair an application vulnerability

A firewall constrains network flows. If the application listening on permitted port 443 contains SQL injection, the firewall does not remove the vulnerability. A WAF may block some payload patterns and provide useful visibility, but it still does not correct the application's failure to separate data from SQL syntax.

Controls should be positioned according to their actual responsibilities:

  • firewall: network reachability,
  • WAF: additional protection and visibility for web attack patterns,
  • application: business logic, authorization, and data/command separation,
  • IDS/IPS: detect or block suspicious behavior,
  • SIEM: aggregate, correlate, and investigate events.

27. IDS/IPS, Snort, Suricata, and Wazuh: Turning Observations into Meaning

No preventive layer is perfect. The system therefore needs the ability to observe indicators that a control has failed or that an attacker is probing it.

Snort and Suricata can perform signature- and behavior-oriented inspection of network traffic. Platforms such as Wazuh can centralize endpoint events, file-integrity monitoring, security logs, vulnerability information, and other telemetry for correlation and analysis.

27.1 A signature is not the same as an incident

An IDS rule can produce an alert after seeing a particular packet pattern. That does not prove that the attack succeeded. The payload may have targeted a non-vulnerable version, may have come from a test system, or may have been rejected by the application.

The opposite problem is equally important: relying only on known signatures can miss new or modified behavior.

Security monitoring becomes more useful when it combines context:

Network event
 + application event
 + identity event
 + asset context
 + time
 = higher-quality alert

Hundreds of failed logins followed by one success and then an unusual data export should not be treated as three unrelated log patterns.

27.2 False positives and false negatives

More alerts do not necessarily mean better detection. A rule that continuously produces false alarms is eventually ignored by the operator, creating alert fatigue.

Useful operational metrics include:

  • alerts per day,
  • proportion of alerts confirmed as meaningful events,
  • false-positive rate,
  • time to detect,
  • time to respond,
  • mapped attack technique,
  • reliability and coverage of the underlying data source.

Tuning is not the act of silencing alerts. It is the process of improving the signal-to-noise ratio while preserving useful coverage.

27.3 Visibility mapping with MITRE ATT&CK

MITRE ATT&CK organizes observed adversary behavior into tactics and techniques. As of August 2026, ATT&CK v19.2 is the current catalog release. The Enterprise ATT&CK material can be used to ask a far more useful question than "have we blocked every technique?":

Which techniques that are plausible in our threat model can we actually observe?

Some behaviors cannot be prevented reliably but can be detected with good confidence. For others, the better engineering decision is to remove the architectural path entirely rather than depend on detection.

28. Availability Security: DoS/DDoS Is More Than a Bandwidth Problem

Exercises involving SYN floods, UDP floods, amplification, or packet-generation tools are useful for understanding network-level denial of service. In a modern application, however, availability depends on far more than the network link.

A service may fail because any of the following resources is exhausted:

  • network bandwidth,
  • connection tables,
  • threads or event-loop capacity,
  • CPU,
  • memory,
  • file descriptors,
  • database connection pools,
  • query capacity,
  • disk I/O,
  • queue backlog,
  • third-party API quota,
  • expensive cryptographic operations,
  • logging storage.

28.1 Application-layer DoS

If one endpoint can generate a report over hundreds of millions of rows, an attacker may not need millions of packets. Ten expensive requests can be more damaging than one hundred thousand cheap requests.

Rate limiting therefore has to consider computational cost, not only request count. Query timeouts, pagination limits, file-size limits, concurrency budgets, circuit breakers, bounded queues, and backpressure may all be relevant.

28.2 A queue is not automatically resilience

A message queue can absorb bursts, but if the producer rate remains above the consumer rate, backlog grows and failure is merely postponed. Basic queueing relationships such as Little's Law remind us that throughput, concurrency, latency, and queue length are connected.

Unbounded queues are especially dangerous because they convert load into memory use and delay. Bounded queues force the system to define overload behavior explicitly.

28.3 Layered DDoS defense

Large volumetric attacks may require upstream capacity and mitigation that an application server cannot provide. Network-level protection, CDN/edge services, upstream filtering, connection controls, application rate limits, caches, resource budgets, and graceful degradation solve different parts of the problem.

The correct defense depends on where the constrained resource is consumed.

29. Mobile Application Security: Running the Client in a Hostile Environment

A mobile application executes on a device controlled by the user and potentially by an attacker. Rooted or jailbroken systems, emulators, instrumentation frameworks, modified binaries, proxying, filesystem access, and runtime hooking should therefore be part of the threat model.

Security-critical decisions such as entitlement, payment state, or server authorization cannot safely depend only on a client flag. The server must treat the client as a request generator, not as the source of truth.

29.1 The proper role of certificate pinning

Pinning can increase resistance to some man-in-the-middle and local trust-store attacks, but it introduces an operational lifecycle: certificates or public keys change, applications may remain outdated, and emergency rotation may be necessary.

Pinning should therefore complement correct TLS certificate validation rather than replace it. A mobile build containing a debug trust manager or disabled verification is a much larger defect than the absence of pinning.

29.2 Local data

Tokens, personal data, cryptographic material, cached documents, logs, and local databases should be reviewed under the assumption that an attacker may obtain the device filesystem or inspect the running process.

Avoid storing what is not needed. Use platform-provided protected storage where appropriate. Keep token lifetimes and server-side revocation in mind. Encryption at rest is useful only if the key is not trivially stored beside the ciphertext.

29.3 Defining verification scope with OWASP MASVS

The OWASP MASVS control groups help prevent a mobile security assessment from collapsing into a package scan or certificate check. They cover storage (MASVS-STORAGE), cryptography (MASVS-CRYPTO), authentication (MASVS-AUTH), network communication (MASVS-NETWORK), platform interaction (MASVS-PLATFORM), code (MASVS-CODE), resilience to reverse engineering and tampering (MASVS-RESILIENCE), and privacy (MASVS-PRIVACY). MASVS states verification objectives; MASTG complements it with testing approaches and evidence collection.

Finding an access token on a device, for example, also requires checking the token's scope, lifetime, and server-side revocation behavior. Intercepting or altering traffic tests server authorization separately from TLS validation. Each finding becomes reproducible when tied to the application build, device and OS state, prerequisites, precise steps, and expected versus observed outcome. The control inventory should lead to verifiable claims, not merely checked boxes.

30. Software Supply Chain: Code You Did Not Write Is Still Your Attack Surface

Modern applications are composed largely of third-party components. Vulnerabilities can arrive not only through your own source code but through libraries, build plugins, container base images, CI actions, package repositories, compilers, and build infrastructure.

OWASP Top 10:2025 placing Software Supply Chain Failures at A03 reflects how central this problem has become.

30.1 Dependency inventory

A team that cannot quickly answer "do we use Log4j?" loses hours or days when a serious vulnerability is announced. This is one reason SBOMs are useful. Generating an SBOM and never using it, however, is not a security capability.

For a dependency, useful inventory includes:

  • exact name and version,
  • package ecosystem and source registry,
  • direct or transitive status,
  • license and support status where relevant,
  • known vulnerabilities,
  • whether the affected functionality is actually reachable,
  • the artifact or service into which it was built,
  • update or exception ownership.

30.2 Dependency confusion and package sources

If an internal package name can also be published in a public registry and the build system prefers the wrong source, an attacker may be able to inject a package with the same name into the dependency chain. Package-manager configuration, namespace ownership, private registries, pinned versions, lockfiles, and integrity verification therefore become security controls.

30.3 The build environment is a critical asset

A CI/CD system capable of releasing to production effectively possesses production authority. Build runners, signing keys, deployment tokens, and source-repository permissions are critical identity material.

A trustworthy chain can be represented as:

Source
  -> reviewed change
  -> controlled dependencies
  -> isolated build
  -> tests
  -> SBOM / provenance
  -> signed artifact
  -> verified deployment

Being able to prove which commit, dependency set, and build environment produced an artifact is valuable not only for prevention but also during incident response.

31. CI/CD Security: Automation May Hold More Authority Than a Human

A CI/CD pipeline commonly reads source code, accesses secrets, publishes artifacts, and deploys to production. It should therefore be treated as its own trust domain rather than as a harmless helper tool.

31.1 A pull request is a trust boundary

Code from an untrusted branch or external contributor should not automatically execute on a runner that can read production secrets. Build scripts are code. An attacker can place exfiltration logic in tests, package scripts, build plugins, or seemingly harmless tooling.

Runner isolation, secret-scoping rules, protected environments, reviewed workflow changes, and separate privilege levels are therefore important even when application code itself is well reviewed.

31.2 Prefer short-lived credentials

Where the platform permits it, workload identity and short-lived credentials are preferable to static long-lived cloud or API keys. Short lifetimes reduce the useful window after leakage and simplify rotation.

31.3 Security gates

Adding every available scanner to a pipeline does not create quality. Noisy, context-free tooling can train developers to ignore security output.

A more defensible policy is to:

  • block newly introduced critical/high-risk findings according to defined policy,
  • track existing technical debt against an explicit baseline,
  • treat secret leakage as a hard failure,
  • evaluate dependency risk with exploitability and runtime context,
  • verify artifact integrity before deployment,
  • allow false-positive exceptions only when recorded, owned, and time-bounded.

Unit 5: Security Testing, Incident Response, and Digital Forensics

32. Security Testing: No Single Tool Is Sufficient

Static analysis, dynamic testing, dependency scanning, fuzzing, configuration review, and penetration testing answer different questions. Their overlap is useful precisely because their blind spots differ.

  • Code review: Strong area: Business logic, context, design intent; Blind spot: Human time and coverage.
  • SAST: Strong area: Dangerous source-to-sink flows and patterns; Blind spot: False positives, runtime context.
  • DAST: Strong area: External behavior of the running application; Blind spot: Cannot see all code paths.
  • SCA: Strong area: Known vulnerable dependencies; Blind spot: Custom code and misuse.
  • Fuzzing: Strong area: Parser, memory, and unexpected-input failures; Blind spot: Requires a suitable harness/oracle.
  • Penetration testing: Strong area: Chaining, business logic, adversary perspective; Blind spot: Time-bounded sampling.
  • Configuration audit: Strong area: Hardening and deployment controls; Blind spot: Application logic.

32.1 Validate SAST findings

When a static analyzer labels a function "SQL Injection," automatically accepting it as a real vulnerability is as weak as dismissing it because "the tool is usually wrong." Follow the data from source to sink. Is parameter binding really used? Is any query fragment still dynamic? Is an allowlist complete? Can tainted data reach the dangerous operation through another path?

The tool proposes evidence; engineering establishes the finding.

32.2 DAST and Burp Suite

Proxy-based web testing makes the real HTTP interface visible. Fields the UI never sends can be added, identifiers changed, methods replaced, headers removed, content types altered, and state transitions replayed. This is particularly instructive for software engineers because it demonstrates physically that client-side controls are not a security boundary.

The objective is not only to launch payloads. Authentication, authorization, validation, state transition, error behavior, workflow abuse, and concurrency should be examined systematically.

32.3 Fuzzing

Fuzzing is particularly valuable for native parsers, file formats, protocols, and complex data transformations. Modern coverage-guided fuzzing is more than generating random bytes; it selects inputs that drive execution into new paths and therefore explores the state space more effectively.

When a crash is found, the work is not finished:

  1. Is it reproducible?
  2. Can the input be minimized?
  3. What do memory sanitizers report?
  4. Which attacker-controlled value corrupts which structure?
  5. Is there a security impact beyond denial of service?
  6. Does the same root cause exist in sibling parsing paths?

Fixing the weakness class is more valuable than patching one crashing input.

33. Penetration Testing: An Engineering Activity, Not a Scan

A vulnerability scanner finds known problems at scale. Penetration testing examines how controls behave together when approached by an adversary.

A disciplined test flow looks like this:

Scope
 -> passive reconnaissance
 -> active discovery
 -> attack-surface mapping
 -> vulnerability hypothesis
 -> controlled validation
 -> privilege-escalation analysis
 -> lateral-movement analysis
 -> impact validation
 -> evidence
 -> cleanup
 -> root cause
 -> remediation
 -> retest

"Exploit succeeded" is not a complete report. A useful report explains the prerequisites, missing controls, attacker capability gained, business impact, possible detection signals, root cause, and durable remediation.

33.1 The proper teaching value of Metasploit

Metasploit is powerful for rapid controlled validation, but knowing how to run a module is not the same as understanding the vulnerability. The most useful approach is to study what the module does at protocol and target-behavior level.

If an exploit follows this chain:

identify target/version
 -> construct a specialized request
 -> trigger memory/logic defect
 -> obtain control
 -> execute payload

defense can interrupt it at different points. Upgrading may remove the root vulnerability; a WAF might temporarily block a request pattern; process sandboxing can reduce post-exploitation impact; EDR may detect follow-on behavior. Permanent remediation and compensating controls should not be confused.

The lasting value of Kevin Mitnick's social-engineering examples is not in memorizing old telephone scripts. It lies in understanding how people make decisions under authority, urgency, helpfulness, curiosity, routine, and incomplete information.

Calling humans "the weakest link" often shifts design responsibility to the user. A better engineering question is: how much damage can one incorrect human decision cause?

If a user enters a password into a phishing page, phishing-resistant MFA may still stop account takeover. If a help desk can disable MFA after a weak telephone check, the technical control can be bypassed. If an administrator reads ordinary email from a highly privileged account, phishing gains far more leverage than necessary.

34.1 Process is a security control

The following workflows deserve explicit resistance to social engineering:

  • password and MFA reset,
  • new-device enrollment,
  • privileged group membership,
  • money or sensitive-data transfer,
  • enabling remote access,
  • creating third-party accounts,
  • emergency exceptions.

If the answer to a recovery question can be learned from public information, it is not a meaningful authenticator. "The manager requested it" is not authorization evidence. Independent verification channels, second-person approval, and step-up authentication reduce the impact of one mistaken decision.

34.2 Security awareness should be measured

Showing one annual presentation is not a security program. Training should become role-specific behavior. A phishing simulation reduced to "who clicked?" can create fear without improving system resilience.

More useful measures include:

  • time to report suspicious messages,
  • proportion reported through the correct channel,
  • help-desk compliance with identity-verification procedures,
  • privileged-user use of trusted administration workstations,
  • recurrence of the same human-process failure after an incident.

The purpose is not to test people for punishment; it is to improve the system's tolerance of predictable human error.

35. Logging: Avoid "We Wish We Had Recorded That"

A security log serves a different purpose from a debug log. Debugging output helps developers diagnose software behavior. Security logging preserves an auditable record of identity events, authorization decisions, high-value actions, and important state changes.

35.1 What should be recorded?

Depending on the system, valuable events include:

  • successful and failed authentication,
  • MFA enrollment and reset,
  • password changes,
  • privilege changes,
  • creation and disabling of users/service accounts,
  • critical data read/write/delete operations,
  • authorization denials,
  • administrative operations,
  • security-configuration changes,
  • token/key lifecycle events,
  • file uploads and downloads,
  • bulk exports,
  • rate-limit triggers,
  • unexpected parser or validation failures.

Including time, actor, source, action, target, result, and a correlation identifier makes many investigations substantially easier.

35.2 What should not be recorded?

Avoid logging:

  • passwords,
  • complete session or bearer tokens,
  • private keys,
  • unnecessary payment or personal data,
  • secrets entered by users,
  • entire request bodies by default.

Log injection also deserves attention. User-controlled newlines or control characters should not be able to forge log structure. Structured logging with explicit fields is generally easier to validate and analyze than arbitrary concatenated text.

35.3 Time synchronization

Distributed investigation requires clocks to be coherent. A difference of even a few minutes can place events from identity, network, database, and application logs in the wrong sequence. NTP or another controlled enterprise time source is a quiet but critical dependency of forensic-quality logging.

36. Incident Response: Do Not Design the Plan During the Incident

Vulnerability management deals primarily with weaknesses before exploitation; incident response deals with the period during and after suspected compromise. A plan written for the first time while production is already under attack is too late.

NIST CSF 2.0 expresses the continuity well through Govern, Identify, Protect, Detect, Respond, and Recover.

36.1 Preparation

Before an incident, the organization should already know:

  • owners of critical systems,
  • communication and escalation paths,
  • log and evidence sources,
  • who has authority to isolate systems,
  • account/token/key revocation mechanisms,
  • backup and restoration procedures,
  • legal or organizational notification obligations,
  • trusted administration channels,
  • where incident runbooks and credentials are available if normal systems fail.

Preparation should be exercised. A recovery procedure that has never been tested is an assumption, not a capability.

36.2 Detection and validation

An alert is the beginning of an investigation, not proof of compromise. Analysts need to determine what happened, which asset is affected, whether the activity succeeded, which identity was involved, and whether the behavior continues.

Preserving evidence before destructive remediation matters. Rebooting, deleting files, or resetting systems prematurely may destroy volatile indicators needed to understand scope.

36.3 Containment

Containment attempts to stop expansion while preserving enough evidence and business continuity to manage the event. Depending on the case this may include isolating a host, disabling an account, revoking tokens, blocking a network path, disabling a vulnerable function, or moving traffic to a known-good environment.

Containment is a trade-off. Disconnecting everything may end the attack but also destroy business continuity and observability. Doing nothing preserves evidence but allows damage to continue. The decision must be tied to asset criticality and attacker capability.

36.4 Eradication and recovery

Removing one malicious file does not prove that the system is clean. Recovery may require credential rotation, rebuild from trusted images, patching the root vulnerability, restoring verified data, validating persistence mechanisms, and staged return to service.

The trustworthiness of the recovery source matters. Restoring a compromised image reproduces the compromise.

36.5 Root cause

The final question is more than "which malware or IP address was involved?" It is which control failure allowed the attacker to enter, expand, persist, or remain undetected?

If the answer becomes a new security requirement, automated test, architecture constraint, monitoring rule, or deployment control, the incident improves the engineering system. If the answer remains only in an incident report, the same weakness class can return.

37. Digital Forensics: Preserving the Reliability of Evidence

Digital forensics asks more than "what happened?" It asks what happened, when, in what sequence, and on what evidence can that conclusion be defended?

Security engineering and forensic readiness meet long before an incident. If a system never records the identity, time, decision, or state transition needed to reconstruct an event, that evidence cannot be invented afterward.

37.1 Volatile and persistent data

Some evidence may disappear when a system is shut down:

  • running processes,
  • active network connections,
  • memory-resident credentials or artifacts,
  • temporary filesystem state,
  • process memory,
  • short-lived tokens and execution state.

Disk files, centralized logs, registry data, filesystem metadata, database history, and remote telemetry may be more persistent. Acquisition order should depend on the incident and on the risk that evidence will be destroyed by collection itself.

37.2 Integrity

Hashing acquired evidence and maintaining chain-of-custody records help demonstrate that the material was not altered after collection. Analysis should be performed on verified copies whenever possible rather than on the original evidence.

This discipline matters even outside a courtroom. To claim that "the attacker created this file," an analyst should be able to distinguish attacker activity from changes introduced by responders, collection tools, or subsequent system operation.

37.3 The application developer's contribution to forensic readiness

Developers influence future incident investigations through log and state design. Request correlation identifiers, user/service identity, authorization outcomes, object identifiers, and durable change identifiers can make it possible to reconstruct a sequence across several systems.

Excessive logging is not the answer. Personal data, secrets, and high-volume noise create both risk and cost. The goal is to leave enough trustworthy evidence to answer meaningful questions later.

38. Vulnerability Management: A Scanner Finding Is the Beginning of a Life Cycle

When a CVE appears, the first reaction may be "is there a patch?" In large environments, that is necessary but not sufficient; prioritization and ownership are required.

A useful vulnerability record contains information such as:

Asset
Component / version
CVE / CWE
Exposure
Exploitation prerequisites
Known or active exploitation
Business impact
Existing controls
Recommended permanent remediation
Temporary mitigation
Owner
Target date
Retest result

38.1 Version matching alone is not enough

An SCA tool finding a vulnerable version does not always prove that the vulnerable code path is reachable in this application. The inverse is equally important: a decision that "the path is not reachable today" may become false after a future code change.

When practical, updating remains the strongest long-term answer. Reachability information is valuable for prioritization, not as a permanent excuse to freeze a vulnerable component indefinitely.

38.2 Security debt

Marking a finding "risk accepted" does not remove the risk. Acceptance should be owned, justified by explicit compensating controls, and expire at a defined time. An exception with no review date becomes a permanent hole in policy.

39. Security Misconfiguration: Correct Code Can Still Run Insecurely

OWASP Top 10:2025 placing Security Misconfiguration at A02 is a useful reminder that vulnerabilities do not live only in source code.

Common examples include:

  • default accounts,
  • debug mode left enabled,
  • directory listing,
  • unnecessary HTTP methods,
  • verbose stack traces,
  • publicly exposed administration interfaces,
  • overly broad CORS,
  • public cloud/object-storage access,
  • unnecessary services,
  • weak TLS configuration,
  • test keys used in production,
  • example, actuator, or management endpoints left unprotected.

Configuration as Code can help because security-relevant settings become reviewable, versioned, and testable. Storing production secrets in the same repository merely moves the weakness; it does not solve secret management.

Unit 6: Security Engineering, Protocols, and Modern Infrastructure

40. Security and Performance Do Not Have to Be Enemies

In critical or high-throughput systems, a security control that ignores latency, throughput, capacity, and resource consumption is likely to be weakened or disabled later under operational pressure. Security mechanisms themselves therefore require performance engineering.

40.1 Password-hashing cost

A higher Argon2id cost is not automatically better. Selecting extreme parameters without measuring authentication capacity can create a denial-of-service vector against legitimate users. The objective is to raise offline guessing cost while keeping the online authentication service within a controlled capacity envelope.

The decision should be based on measurements from representative hardware and should include concurrent-login behavior, failure paths, rate limiting, and scaling characteristics.

40.2 Token-validation architecture

Synchronously calling an authorization server for token introspection on every request can turn that central service into a latency and availability bottleneck. Local verification of signed JWTs reduces network dependency and per-request latency but creates other problems: revocation delay, stale authorization, key rotation, and propagation of role changes.

The security/performance trade-off should therefore be designed explicitly around:

  • token lifetime,
  • key rotation,
  • revocation requirements,
  • cache behavior,
  • step-up or revalidation for sensitive operations,
  • audience restriction,
  • acceptable propagation delay for authorization changes.

40.3 Logging

Synchronously writing every request body to disk creates both performance and privacy problems. Security telemetry should be structured and bounded, with explicit buffering or queueing behavior, backpressure policy, loss semantics, and storage limits.

A control that does not fit the system's operating model survives only on paper.

41. Security and Usability: Do Not Force Users to Work Around the Control

Predictable human behavior is not only an attack vector; it is an input to system design. Excessively complex password rules encourage reuse or written notes. Requiring MFA for every trivial action can make users habituated to approval prompts. Extremely short sessions can disrupt work and encourage unsafe workarounds.

The objective of secure design is not to punish the user. CISA's Secure by Design principle that customers should not carry the security burden alone applies here as well.

A good control should, where possible, be:

  • enabled by default,
  • understandable,
  • compatible with the normal workflow,
  • secure when it fails,
  • difficult to bypass accidentally,
  • unlikely to require users to disable security in order to work.

42. Read Code Like an Attacker During Security Review

Security code review is more than searching for eval, exec, string-built SQL, or hard-coded passwords. It is the practice of reading the code's trust assumptions.

A useful sequence for reviewing an endpoint is:

Where does the input come from?
 -> how is identity established?
 -> where is authorization decided?
 -> is data normalized and validated?
 -> which interpreter or parser receives it next?
 -> which resource can it consume?
 -> under which secret or privilege does it execute?
 -> what happens on failure?
 -> how is the event recorded?

This model is largely independent of language or framework.

42.1 Dangerous conveniences

Frameworks reduce implementation burden, but unsafe defaults or careless use can standardize a vulnerability across the whole application. Particular attention should be paid to:

  • binding persistence entities directly from request bodies,
  • wildcard CORS,
  • disabling CSRF without understanding the authentication model,
  • disabling TLS verification for testing and forgetting it,
  • sending raw HTML into templates,
  • concatenating query fragments,
  • enabling broad polymorphic object deserialization,
  • constructing filesystem paths from user input,
  • leaving authorization only at controller or UI level.

Using a secure framework well means preserving its security mechanisms by default and overriding them only for a documented reason.

43. Reading Spring Security as an Implementation of Security Principles

Spring Security tutorials often teach filter chains, SecurityFilterChain, authentication providers, user details, CSRF, CORS, OAuth 2, method security, and token handling as separate subjects. In production architecture, each should be tied to a more fundamental question:

  • Authentication: on what evidence is identity established?
  • Security context: how is the authenticated identity carried through request processing?
  • Authorization: for which object and action is the decision made?
  • Filter chain: in which order are security decisions enforced before application logic?
  • CSRF: which attack path exists because the browser sends credentials automatically?
  • OAuth 2/OIDC: how are authority and identity delegated across systems?
  • JWT: how does the resource server validate integrity, issuer, audience, lifetime, and authorization meaning?

Once this model is understood, framework APIs can change without erasing the security logic.

43.1 Security tests are regression tests

If an endpoint has no authorization tests, a refactor can silently remove a security rule. Negative tests are as important as successful ones:

ADMIN -> 200
USER -> 403
Anonymous -> 401
Object owned by another user -> 403/404 depending on the design

Equivalent invariants should be protected at endpoint, method-security, and domain-authorization levels where those layers exist.

44. Error and Exception Handling: The Exceptional Path Is Part of the Design

Many systems are secure only on the happy path. Under unexpected conditions they disclose internals, skip an authorization decision, partially commit a transaction, or fall back to a less secure mode.

OWASP Top 10:2025 making Mishandling of Exceptional Conditions an explicit A10 category is significant because it elevates failure behavior from "error handling" to a security concern.

44.1 Parser failure

Invalid JSON, excessively deep objects, huge numbers, malformed Unicode, oversized multipart bodies, decompression bombs, or unexpected content types can alter system behavior before business validation even begins. Parser limits should be explicit and tested.

The goal is not only to reject malformed data but to do so with bounded CPU, memory, recursion depth, allocation, and diagnostic behavior.

44.2 Transaction integrity

Suppose a critical operation has three steps and step two fails. Does step one roll back? In a distributed system, can a retry execute the operation twice? Can an attacker intentionally replay a request during a partial-failure window?

Idempotency is also a security property for payments, quotas, approvals, privilege changes, token issuance, and other stateful operations. "Retry" without state semantics can become double spending or integrity failure.

44.3 Error oracles

Responses such as "user does not exist," "password incorrect," or "MFA device not registered" can assist account enumeration. Returning one completely identical response for every condition may reduce usability or supportability.

The correct boundary depends on the threat model: expose only what the caller needs, while retaining richer diagnostic context in protected internal logs.

45. DNS Security: Name Resolution Is a Security Dependency

DNS often appears as a thin arrow in architecture diagrams, yet it determines where applications connect. If name resolution is manipulated, higher-layer controls such as TLS must still establish the identity of the intended peer. Inside enterprise networks, DNS is also fundamental to Active Directory, service discovery, and management functions.

45.1 Zone transfer and unnecessary inventory disclosure

An unauthorized zone transfer can reveal subdomains and hostnames in bulk. Zone transfer should be restricted to authorized secondary servers where it is required. The broader lesson is that a management function and a public service should not inherit the same access policy simply because they share a protocol.

A DNS record may not be secret by itself, but names such as vpn, dev, jenkins, backup, db, or old-admin lower reconnaissance cost. Naming conventions are not security controls; removing obsolete records and systems is attack-surface management.

45.2 DNS spoofing and cache poisoning

Historical DNS cache-poisoning attacks exploited predictability in transaction IDs, source ports, and resolver behavior. Modern resolvers provide stronger randomness and additional protections; DNSSEC can provide data-origin authentication and integrity for signed DNS data in suitable deployments.

DNSSEC does not encrypt DNS traffic and does not replace TLS peer authentication at the application layer.

Relevant defensive layers include:

  • trustworthy, maintained resolvers,
  • limiting recursive service exposure,
  • restricting zone transfer,
  • DNSSEC where appropriate,
  • TLS identity verification between client and server,
  • detection of anomalous DNS behavior,
  • controlled split-horizon DNS where internal and external views must differ.

45.3 DNS is also a detection source

Malware and command-and-control infrastructure frequently use DNS. Very long or high-entropy labels, newly observed domains, unusual failure rates, domain-generation behavior, or queries outside a host's normal profile can become useful signals.

A single indicator is not proof. New CDNs and telemetry services can produce unusual patterns too. DNS becomes more useful when correlated with process, host, identity, and asset context.

46. ARP, MITM, and Wireless Networks: The Local Network Is Not Automatically Trusted

ARP spoofing/poisoning and wireless interception exercises break a common assumption very effectively: being on the same LAN is not proof of identity.

ARP maps IPv4 addresses to link-layer addresses on local networks but does not provide strong authentication. An attacker in the right network position can attempt to insert their own host into traffic paths through forged ARP responses. Correct end-to-end TLS makes payload inspection far harder; disabled certificate validation or users accepting invalid certificates makes the attack considerably more useful.

46.1 Remove the "internal network is trusted" assumption

The primary defensive lesson from local-network attacks is that service identity must not depend solely on network location. A request originating from a corporate IP range is not automatically authorized. Restricting an administration interface to an internal management network is valuable defense in depth, but it is not a replacement for authentication and authorization.

Controls such as DHCP snooping, Dynamic ARP Inspection, port security, NAC, and segmentation can be useful in appropriate environments. End-to-end protocol authentication should remain intact even when those controls are present.

46.2 Wireless security

WEP remains historically important because it shows how cryptographic design weaknesses become practical attacks, but it should not be used in modern systems. Security in WPA/WPA2/WPA3 families depends on mode and deployment. Weak pre-shared keys make offline guessing more practical. In enterprise 802.1X/EAP deployments, clients that fail to validate the RADIUS server certificate correctly may become vulnerable to evil-twin credential capture.

More durable principles are:

  • disable obsolete and broken protocols,
  • use strong and unique credentials,
  • validate server certificates in enterprise authentication,
  • separate guest networks from corporate networks,
  • use client isolation where appropriate,
  • maintain access-point inventory and detect rogue APs,
  • separate management planes from ordinary user traffic.

Abuse of unauthenticated management frames also explains why mechanisms such as 802.11w/Protected Management Frames were introduced. The lasting lesson is not the name of a deauthentication tool; it is that unauthenticated control traffic can affect availability.

46.3 A VPN is a transport channel, not a trust level

Establishing a VPN does not make the endpoint trustworthy. A VPN can provide an authenticated, encrypted network path, but a compromised client can use that same path on behalf of an attacker. User identity, device posture, segmentation, and application-level authorization remain necessary after the tunnel is established.

47. Malware, Rootkits, and Ransomware: Engineering Persistence and Impact

Malware is an extremely broad field. Viruses, worms, trojans, rootkits, bots, downloaders, information stealers, and ransomware differ in implementation and purpose. Defensively, a useful way to organize them is by adversary life cycle:

Initial access
 -> execution
 -> persistence
 -> privilege escalation
 -> defense evasion
 -> credential access
 -> discovery
 -> lateral movement
 -> collection / exfiltration
 -> impact

This aligns naturally with MITRE ATT&CK tactics.

47.1 Trojans teach trust-chain verification

If a user launches an expected application whose package has been modified to include malicious behavior, the failure is more than "antivirus did not detect it." The software's source and integrity were not established reliably.

Code signing, trustworthy distribution channels, application allowlisting, package integrity verification, and supply-chain controls exist to strengthen this trust chain.

47.2 Rootkits expose the observability problem

The defensive lesson of a rootkit is that if the observation tool runs inside the compromised system, its view may itself be manipulated. If a kernel or low-level component has been altered, blindly trusting local ps, filesystem listings, or local logs is unsafe.

Centralized remote logging, network telemetry, integrity measurement, secure/verified boot where available, EDR with protected telemetry, and known-good rebuild sources become important because they reduce dependence on a single potentially compromised observer.

47.3 Ransomware is not only encryption

Modern ransomware operations often include credential theft, privilege escalation, lateral movement, backup disruption, and data exfiltration before encryption. "We have backups" is therefore not a complete defense.

Resilient design requires measures such as:

  • separating privilege domains,
  • avoiding daily use of administrative identities,
  • reducing lateral-movement paths,
  • isolating critical backups from ordinary domain compromise,
  • regularly testing restoration,
  • detecting unusual bulk file modifications and identity behavior,
  • maintaining rebuild plans for critical services.

During a ransomware incident, understanding which identity-system privileges the attacker obtained is often more important than cleaning one endpoint.

48. E-mail and Phishing: A Social Protocol into the Identity System

Phishing may appear to be an e-mail or fake-web-page problem, but in practice it sits at the intersection of authentication, user behavior, mail infrastructure, browser trust, and organizational process.

48.1 Technical e-mail authentication

SPF, DKIM, and DMARC can work together to reduce abuse of a sending domain. None protects users from every malicious message. Look-alike domains, compromised legitimate accounts, abused third-party services, and validly signed malicious mail remain possible.

E-mail security therefore combines layers:

  • sending-domain policies,
  • link and attachment analysis,
  • restrictions on macros/active content,
  • sandboxing where justified,
  • an easy user-reporting mechanism,
  • phishing-resistant MFA,
  • separation of privileged identities from ordinary e-mail use,
  • correlation with identity and endpoint events.

48.2 What happens after phishing succeeds?

If an employee enters a password, closing the case as "user error" misses the actual identity problem. Investigation should consider:

  • Was the password reused elsewhere?
  • Was an MFA factor or session cookie captured?
  • Were new session tokens issued?
  • Was malicious OAuth consent granted?
  • Was a mailbox forwarding rule created?
  • Was a new authenticator or recovery method registered?
  • Was the same identity used through VPN or other enterprise services?

Changing the password alone can leave persistence paths intact.

49. OSINT and Security Scanners: Measure How Visible You Are

Google dorking historically demonstrated how search operators can find accidentally exposed content. The same idea is now broader than one search engine. Source-code platforms, certificate-transparency logs, Internet measurement services, package registries, archives, public documents, and breach datasets contribute to an attacker's passive reconnaissance surface.

Defenders should perform recurring external attack-surface management. The objective is not to "hide from search engines." It is to discover whether assets that should not be publicly reachable actually are.

49.1 The limits of Nmap, Nessus/OpenVAS, Nikto, and similar tools

Scanners are valuable because they are repeatable and broad. They can rapidly identify exposed ports, probable versions, known CVEs, weak protocol settings, and common web misconfigurations.

They do not reliably answer every high-value question:

  • Can this user read another tenant's data?
  • Can a business approval step be skipped?
  • Do two moderate findings compose into a critical path?
  • Is a custom cryptographic protocol designed incorrectly?
  • Is the application trusting the wrong boundary?

"The vulnerability scan is clean" is therefore not equivalent to "the system is secure."

49.2 Authenticated scanning

For operating systems and servers, authenticated vulnerability scanning can provide a more accurate inventory than examining banners from the outside. The scanner credential itself, however, becomes a privileged secret and must have tightly controlled scope, storage, monitoring, and rotation.

50. OAuth 2, OpenID Connect, and SAML: Expressing Identity and Delegation in Protocols

OAuth 2 is an authorization framework that allows delegated access to resources without giving a third-party application the user's password. OpenID Connect (OIDC) adds an identity layer on top of OAuth 2. SAML remains common in enterprise federation and SSO through XML-based assertions.

Confusing these roles produces serious design errors. An access token should not automatically be treated as a universal identity document. An ID token should not be accepted as an API authorization token merely because it is signed. The presence of a token is not enough; its intended context must be validated.

50.1 Trust boundaries in an OAuth 2 flow

For modern browser and mobile public clients, Authorization Code with PKCE is a common baseline. Client type, ability to protect secrets, redirect-URI handling, issuer trust, and browser behavior all matter.

A resource server should validate:

  • the token came from a trusted issuer,
  • it was issued for this API or resource (aud),
  • it is within its validity window,
  • required scopes/authorities are present,
  • the signature validates against an appropriate trusted key.

A scope does not necessarily replace domain authorization. Possessing documents.read does not mean the caller may read every document. Object ownership or policy still has to be enforced.

50.2 Redirect URI

If OAuth/OIDC redirect URIs are accepted through broad wildcard matching, authorization codes or tokens may be redirected to locations controlled by an attacker. Redirect targets should be pre-registered and compared as strictly as the deployment permits.

50.3 Why PKCE exists

OAuth 2 authorization code flow with PKCE code verifier and code challenge
OAuth 2 with PKCE

A public client cannot reliably protect a static embedded client secret. PKCE binds the authorization request and token exchange through a one-time verifier/challenge relationship. Embedding a fixed secret inside a mobile application does not replace PKCE because that secret can be extracted from the client.

50.4 SAML and XML security

A SAML assertion must be evaluated for signature validity, trusted issuer, audience, recipient, validity period, and replay conditions. Historical XML Signature Wrapping issues demonstrate why "the XML is signed" is not sufficient: the node validated cryptographically must be the same node whose claims the application actually consumes.

In federation systems, many critical failures arise not from weak cryptographic algorithms but from insufficient validation of where, when, and for whom an assertion is valid.

51. XML, XXE, LFI/RFI, and Template Injection: Parser Features Are Part of the Attack Surface

Parsers offer powerful features for convenience. When input is untrusted, those same features can create unexpected file, network, object, or code access.

51.1 XXE

If an XML parser resolves external entities, attacker-controlled XML may cause access to local files or network resources. When DTDs and external entities are unnecessary, the secure configuration is to disable them rather than to filter a handful of known payload patterns.

XXE can also become SSRF because the parser's network requests originate from the server. Parser hardening and egress control are therefore independent defensive layers.

51.2 LFI/RFI and include semantics

Local File Inclusion and Remote File Inclusion historically appeared in applications that dynamically included resources based on user input. The root error is granting the user control over which file or executable resource is loaded.

A modern design should map user choices to fixed resources:

"home"    -> templates/home
"profile" -> templates/profile
"report"  -> templates/report

There is no security benefit in allowing the caller to construct ../../... paths or arbitrary remote URLs when the business requirement only needs a finite set of choices.

51.3 Server-Side Template Injection

SSTI becomes possible when an application treats user-controlled input as template code rather than as template data. If user-authored templates are a genuine business requirement, the sandbox itself becomes a security boundary and must be analyzed for object access, functions, filesystem/network reachability, and escape paths.

The simpler and stronger design is usually for untrusted users to supply values, not executable template structure.

52. Race Conditions and TOCTOU: A Correct Check at the Wrong Time Can Still Be Wrong

TOCTOU: check, swap, and use ordering with computed steps and state transitions
TOCTOU: check, swap, and use ordering

Security controls depend on timing as well as existence. In a time-of-check to time-of-use (TOCTOU) flaw, a resource changes after it has been validated but before it is used.

A simple filesystem example is:

1. Check that a path is safe
2. Another process changes the symlink
3. Open the file

The object used is no longer necessarily the object that was checked.

52.1 Races in business logic

Race conditions are not limited to native filesystem code. Web applications can fail under concurrent operations such as:

  • two withdrawals after one balance check,
  • parallel use of a single-use coupon,
  • parallel resource creation after a quota check,
  • an approval operation executing twice,
  • token use racing with token revocation.

These become integrity and sometimes authorization problems.

52.2 The solution is not simply "add a mutex"

An in-process mutex protects only one process. Distributed systems may require a database transaction or lock, unique constraint, compare-and-set operation, idempotency key, atomic datastore primitive, or correctly designed serializable workflow depending on the invariant being protected.

If security tests never exercise concurrency, a rule that is correct in sequential execution can still fail under real parallel load.

53. Containers, Kubernetes, and Cloud: Do Not Mistake Isolation for a Complete Trust Boundary

Containers are powerful tools for packaging and isolation, but they do not share the same trust model as virtual machines. The host kernel is shared. --privileged, hostPath mounts, broad capabilities, Docker-socket access, or excessive Kubernetes RBAC can weaken isolation dramatically.

53.1 Container images

Image security includes:

  • small, controlled base images,
  • removal of unnecessary packages and tooling,
  • non-root runtime users,
  • no secrets in image layers,
  • digest pinning where reproducibility requires it,
  • vulnerability scanning,
  • signatures and provenance,
  • read-only filesystem where practical.

Multi-stage builds can reduce the final image's attack surface by keeping compilers, package managers, and build tools out of the runtime image.

53.2 Kubernetes

Kubernetes security failures often come from granting the orchestrator's powerful features too broadly:

  • cluster-admin service accounts,
  • unnecessary access to default service-account tokens,
  • missing or overly broad NetworkPolicies,
  • uncontrolled secret use,
  • privileged pods,
  • host namespace access,
  • weak admission control.

A namespace alone should not automatically be treated as a strong tenant-isolation boundary. Multi-tenant Kubernetes requires an explicit threat model.

53.3 Cloud identity

In cloud environments IAM often becomes more important than the classical concept of an "internal network." An overprivileged role, public object storage, or leaked access key can have a very large blast radius. SSRF against metadata services is dangerous for the same reason: it may expose the workload or instance identity available to the application.

Prefer workload/managed identity and short-lived credentials to static long-lived access keys where the platform supports them. Audit logs should be centralized and protected against modification by the workloads they monitor.

53.4 Extending the identity graph into cloud environments

BloodHound/AzureHound-style analysis demonstrates that hybrid identity paths can cross on-premises AD and cloud control planes. A user may have no direct high-level role yet still reach a critical asset through groups, application registrations, service principals, role assignments, delegated permissions, or exposed secrets.

The defensive answer returns to graph reasoning: periodically calculate indirect identity paths to critical assets rather than reviewing only direct role membership.

54. Honeypots and Deception: Turning Adversary Behavior into an Early Signal

A honeypot is a system or resource that should not be part of ordinary business use and is intentionally placed so that attacker interaction becomes observable. A honeynet applies the idea to a broader controlled environment.

When designed correctly, deception can provide a high signal-to-noise ratio. If a credential, file share, service account, or endpoint that no legitimate workflow should ever use is accessed, the event deserves attention.

A honeypot is not a replacement for prevention. A poorly isolated high-interaction honeypot can become a pivot into other systems. Legal, privacy, data-collection, and operational constraints also apply.

Lighter forms of deception include:

  • honey credentials,
  • monitored files that normal users should never access,
  • decoy administration resources,
  • decoy service accounts,
  • isolated shares with no legitimate use.

Their value is more than in "tricking the attacker." It is in transforming behavior that should have near-zero legitimate occurrence into a high-confidence detection signal.

Unit 7: Hardening, Assessment, and Conclusion

55. Reducing Secure Design Principles to Short Rules

At the end of a long study, some principles remain more durable than the tools:

  1. Do not combine untrusted data with commands.
  2. Authenticating an identity is not the same as granting authorization.
  3. The client is not a trust boundary.
  4. Least privilege reduces the impact of a single vulnerability.
  5. A secure default is stronger than a security recommendation hidden in documentation.
  6. A secret must be protected throughout its entire lifecycle, not only where it is stored.
  7. Cryptography is only as strong as its key management.
  8. You cannot respond reliably to an attack you cannot observe.
  9. A backup is not a backup until it has been restored successfully.
  10. Scanning produces findings; risk analysis produces priorities.
  11. Penetration testing evaluates whether a control actually works, not merely whether it exists.
  12. If the same vulnerability keeps recurring, there is a process defect.
  13. The internal network is not assumed to be trusted; every boundary needs its own identity and authorization model.
  14. Design as if one defect will escape; limit its blast radius.
  15. Defense should cut paths in the attack chain, not merely hide indicators.

These should be used as design-review questions rather than slogans.

56. Applied Hardening Algorithm

We can now combine the individual pieces into one process. For a new or existing project, the following order provides a practical way to harden the system.

Step 1 — Identify the asset

Write down what the system does and which data or function is critical. Do not discuss risk before the asset is known.

Output: asset and data-classification list.

Step 2 — Map the real attack surface

Use the code repository and architecture diagram as a starting point, but do not stop there. Verify DNS, ports, APIs, certificates, mobile clients, third parties, and administrative surfaces.

Output: verified inventory and data-flow diagram.

Step 3 — Draw the trust boundaries

Mark client-server, service-service, application-database, organization-third-party, ordinary-user-administrator, and development-production boundaries.

Output: which identity and control are required at each boundary.

Step 4 — Generate threats

Use STRIDE, attack trees, abuse cases, and MITRE ATT&CK knowledge to derive paths that are meaningful in the system's own context.

Output: testable threat scenarios.

Step 5 — Close paths with architecture

Apply least privilege, segmentation, secure defaults, trust minimization, separation of duties, and egress control before relying on code-level filters.

Output: limited impact even when a defect occurs.

Step 6 — Bind identity and authorization to central principles

Define the authentication lifecycle, MFA and recovery paths, service identities, and object-level authorization.

Output: one testable answer to the question, “who may do what, to which resource, under which conditions?”

Step 7 — Put a hard boundary between data and commands

Use parameterized queries, safe process APIs, context-aware output encoding, constrained parser schemas, and file paths generated independently from user input.

Output: fundamental reduction of injection classes.

Step 8 — Manage secrets and cryptography as lifecycles

Design generation, storage, access, rotation, revocation, and destruction together.

Output: leakage that can be detected and managed.

Step 9 — Restrict the runtime environment

Reduce service-user privileges, file permissions, capabilities, container/systemd privileges, network policy, and database grants.

Output: a smaller blast radius for RCE or credential leakage.

Step 10 — Verify the supply chain

Inventory dependencies, base images, CI runners, secrets, artifacts, and deployment permissions. Produce SBOM and provenance information.

Output: evidence-backed answers to “where did this binary come from?”

Step 11 — Combine automated and manual testing

Use SAST, SCA, DAST, fuzzing, configuration tests, unit/integration security tests, and penetration testing for the weakness classes each method can actually observe.

Output: verification that is not dependent on the blind spots of a single tool.

Step 12 — Attack the system

Within an authorized laboratory or defined penetration-test scope, exercise the most realistic attack paths. Test the protocol rather than only the UI; think in chains rather than isolated vulnerabilities.

Output: the control's real behavior rather than its theoretical presence.

Step 13 — Create visibility

Log important security decisions, correlate network, host, and application telemetry, and generate meaningful alerts.

Output: attacks that may not be fully prevented but can still be detected.

Step 14 — Rehearse the incident

Choose a scenario such as account compromise, ransomware, token leakage, or web RCE. Test who makes the decision, which system is isolated, which key or credential is rotated, and which evidence is collected.

Output: an incident-response plan that has become an operational capability rather than a document.

Step 15 — Feed the root cause back into the system

Close not only the individual finding but its weakness class. Create or improve a secure library, lint rule, reusable component, architectural rule, or test so that recurrence becomes harder.

Output: a lower probability of the same failure after every finding or incident.

57. Final CTF: Closing the Route to the Flag

Return to the system from the beginning. Assume its first version contains the following defects:

  • a debugging endpoint is exposed to the Internet,
  • error messages disclose valid usernames,
  • the password policy is weak,
  • MFA is absent,
  • the API does not verify object ownership,
  • the search query is built through string concatenation,
  • the application database account owns the schema,
  • the file-download path is derived from user input,
  • the service runs as root,
  • outbound access to the internal network is unrestricted,
  • a service account has excessive privileges in Active Directory,
  • logs have no correlation identifier,
  • CI uses a static deployment token.

The attacker does not need to depend on a single vulnerability to reach the flag:

Information leakage
 -> account discovery
 -> password spraying
 -> user account
 -> IDOR
 -> service configuration
 -> service credential
 -> AD attack path
 -> privilege escalation
 -> critical data
 -> FLAG

Another path:

SQL injection
 -> database-owner privileges
 -> critical data modification
 -> FLAG

Another path:

File upload / parser vulnerability
 -> RCE
 -> root process
 -> unrestricted internal-network access
 -> lateral movement
 -> FLAG

Now place the defensive decisions along these paths.

Removing the debugging endpoint reduces the ease of reconnaissance, but the system is not yet secure. Improving password policy and MFA narrows the account-compromise path, but the authorization flaw still exists. Object-level authorization closes the IDOR path. Parameterized queries cut the SQL-injection route. A least-privileged database account reduces the impact of a future unknown database or application defect. Sandboxed file processing and a non-root service reduce the consequences of RCE. Egress restrictions make pivoting into the internal network harder. Removing unnecessary group and ACL paths from the Active Directory graph reduces the value of a compromised service account. SIEM correlation makes the chain visible from failed logins through lateral movement.

In the end, we do not claim that “there are no vulnerabilities.” Such a claim is not measurable. A stronger statement is possible:

The known attack surface was identified; threat paths to critical assets were modeled; priority paths were cut with independent security controls; those controls were verified through automated and manual testing; residual risks were recorded; and detection and incident-response paths were rehearsed.

That is how the flag is protected.

58. Security Review Matrix

When reviewing a project quickly, the following matrix can be used for a first pass. It does not replace a standard or threat model; it makes the areas requiring investigation visible early.

  • Inventory: Are all Internet-facing surfaces, services, APIs, and dependencies known?
  • Data: Is sensitive data classified, with defined retention and access models?
  • Threat model: Have trust boundaries and critical attack paths been identified?
  • Identity: Is there a current password, MFA, and recovery policy?
  • Authorization: Is object- and operation-level authorization enforced on the server?
  • Session: Are token/cookie lifecycle, lifetime, revocation, and secure transport correct?
  • Injection: Are data and commands separated at interpreter boundaries?
  • XSS: Are context-appropriate output encoding and safe DOM APIs used?
  • CSRF/CORS: Is the browser trust model understood and enforced with narrow policy?
  • SSRF: Are server-side outbound requests and destination-URL behavior constrained?
  • File handling: Are path, type, size, storage, and serving controls defined?
  • Cryptography: Are standard algorithms used with correct key management and rotation?
  • Secrets: Are secrets kept out of code, repositories, and logs and managed through controlled secret storage?
  • Database: Are queries parameterized, privileges minimized, network boundaries enforced, and backups protected?
  • Operating system: Does the service run non-root with minimal services, tight permissions, and current patches?
  • Active Directory: Are privileged paths, service accounts, and Kerberos/NTLM risks monitored?
  • Network: Do segmentation and egress controls match the real data flow?
  • Supply chain: Are SCA, SBOM, trusted package sources, build provenance, and signatures in place where required?
  • CI/CD: Are runners and deployment identities least-privileged and short-lived where possible?
  • Testing: Are SAST, DAST, SCA, fuzzing, and manual testing used together?
  • Logging: Are security events correlatable without leaking secrets into logs?
  • Detection: Is there visibility for critical ATT&CK behaviors relevant to the threat model?
  • Incident response: Have isolation, credential rotation, and recovery playbooks been tested?
  • Backup: Is restoration regularly and securely verified?
  • Human: Do critical processes expose a one-step social-engineering bypass?

59. Maturity: Metrics More Meaningful Than Vulnerability Count

Measuring a security program only by “how many vulnerabilities did we close?” is misleading. Expanding scan coverage can increase the number of findings; that may indicate better visibility rather than weaker security.

More meaningful metrics, depending on context, can include:

  • inventory coverage of critical assets,
  • proportion of critical flows with a maintained threat model,
  • proportion of features with explicit security requirements,
  • mean remediation time for critical/high findings,
  • recurrence rate of the same CWE class,
  • number and trend of privileged accounts,
  • number of long-lived secrets,
  • MFA and phishing-resistant authenticator coverage,
  • log-source coverage,
  • mean time to detect and respond,
  • successful backup-restoration rate,
  • number of attack paths or length of critical paths,
  • types of security-test pipeline failures,
  • timely re-evaluation rate for time-bounded risk acceptances.

Metrics must be selected carefully because they influence behavior. If a team is rewarded merely for reducing finding counts, it may reduce scan coverage instead. The objective is to reduce real risk.

The Boundary Between Actionable Diagnostics and Information Disclosure

Secure error handling has two bad extremes. The first reduces every problem to an unhelpful message such as “unexpected error.” The second exposes stack traces, SQL, driver messages, filesystem paths, or server details to the user. A secure design establishes a layer between these extremes: enough information to resolve the problem without expanding the attack surface.

The same failure can be handled at three visibility levels:

User surface
  -> safe source, cause, and resolution

Privileged technical diagnostics
  -> bounded additional context and a reference

Server log
  -> real exception chain and technical detail

If a database connection cannot be established, a raw Oracle or JDBC message is rarely appropriate for an ordinary user. “The database is currently unavailable; if the problem continues, provide the error reference to technical support” may be operationally sufficient. The server log should still retain the real exception chain. This distinction forms the security boundary of the self-explaining error experience discussed in UI/UX Engineering in Web Applications.

An error code and a correlation reference are also different concepts. An error code represents a stable class of recurring failures. A correlation reference identifies one concrete occurrence in technical logs. The same error code may appear many times; each occurrence can have a different reference.

error code -> failure class
reference  -> specific occurrence

A correlation value should not encode a user identifier, organizational unit, host name, or other sensitive information. A short random identifier with adequate collision resistance improves support traceability when the same value appears both on the user surface and in the technical log.

Observability should not depend exclusively on the component that is failing. If the only record of a database outage is written to an error table in that same database, diagnostic evidence can disappear precisely when it is needed most. Critical infrastructure failures therefore benefit from an independent application- or operating-system-level technical log path.

Accurate source classification is also a security property. Invalid user input is not the same as a frontend generating an invalid request. Denying access is not the same as revealing whether an unauthorized object exists. Secure diagnostics do not simply reveal more information; they reveal the right information at the right abstraction level. Negative-path and authorization tests in Software Test Engineering should verify this boundary.

Turning threat models into verifiable security requirements

A threat model is useful only when meaningful threats become testable requirements. "Prevent unauthorized access" should be refined into which actor must be unable to access which resource under which conditions.

For example, "a normal user cannot read another user's report" can be verified through authorization tests, direct-object-identifier manipulation, and audit-log checks.

Residual risk should also be recorded with expected impact, detection, and response. This turns security from a one-time penetration test into a lifecycle engineering property.

Scoping security claims with a threat model

“Secure” is not a measurable property by itself. A control cannot be judged sufficient without stating the protected asset, attacker capability, trust boundary, and accepted risk.

Security evidence comes from multiple layers: design review, static/dynamic analysis, authorization tests, dependency/configuration review, audit records, and penetration testing where appropriate. A clean result from one tool does not exclude defects elsewhere.

A remediation should address the root cause rather than only one exploit instance. If the weakness lies in the data model, authorization boundary, or interpretation of untrusted input, the preferred control should reduce the whole class of failures.

Trust Boundaries in Learning and Generative Systems

Adding a generative model does not remove existing trust boundaries; it introduces new boundaries and data flows. In systems that retrieve documents, invoke tools, or access protected enterprise data, model-generated text is not equivalent to an authorized application action.

A simplified flow is:

user input
    ↓
model
    ↓
retrieved context
    ↓
tool / function
    ↓
protected resource

Every arrow is a validation boundary. The fact that a user can instruct a model does not mean that the user is authorized for every resource or tool visible to the model.

Prompt injection and indirect prompt injection

Prompt injection occurs when untrusted input attempts to redirect model behavior away from the intended instruction hierarchy. The input may come directly from the user, or it may be embedded in a document, web page, e-mail, or search result that the model reads. The latter is commonly described as indirect prompt injection.

A useful rule for retrieved content is:

information source != instruction authority

Placing a document into RAG context does not turn its text into trusted commands. The system must preserve the boundary between untrusted data and application instructions. Prompt and template boundaries are discussed separately in Prompt Engineering.

Tool authorization and least privilege

The ability of a model to propose a function call must not grant authority to the model output itself. User identity, object scope, and operation permission must be rechecked at the application boundary for every protected tool action.

model proposes
application validates
policy authorizes
tool executes

Exposing only the tools required for the task and restricting each tool to the minimum required data scope extends the principle of least privilege. High-impact operations such as deletion, payment, privilege assignment, or external data transfer may also require explicit user confirmation. Human confirmation is useful, but it is not a substitute for authorization.

Code, file, and output boundaries

Model-generated code, queries, paths, and commands are untrusted input. When code execution is necessary, execution should be isolated with bounded filesystem, network, process, and resource permissions. If model output is passed to another interpreter, that interpreter's injection and validation rules still apply.

The same principle applies to uploaded files and document processing. File type, size, parser behavior, and archive contents must be validated at the application boundary.

Privacy, logging, and the model supply chain

Prompts, retrieved content, and model output are not automatically safe log material. They may contain personal data, access tokens, confidential information, or other protected content. Logging purpose, retention, and masking should follow the data classification.

Model weights, tokenizers, runtimes, plugins, and conversion tools are also software-supply-chain components. An unknown checkpoint or model package should not be trusted merely because it is called a model. Provenance, integrity verification, trusted distribution sources, and version tracking matter just as they do for conventional dependencies.

The central security question is therefore not whether the model is independently “safe.” A secure application assumes that a model can be wrong, manipulated, and exposed to untrusted content, and keeps data, tool, and authorization boundaries protected by deterministic controls outside the model. Broader capability and limitation questions are covered in Artificial Intelligence: Philosophy, Theory and Practice.

The model life cycle is also an attack surface

In a learning system, training data, model artifacts, evaluation sets, and update channels become part of the trust model. Data poisoning, artifact tampering, and unsafe model loading occur at different stages of the same life cycle:

data → training / selection → model artifact → deployment → inference

Integrity must be considered at each stage. A checksum can show that a file did not change; it does not show that the model was trained on appropriate data or is fit for the task.

Separate predictive-model attacks from generative-model attacks

Evasion and poisoning in adversarial machine learning are not the same class of problem as prompt injection. In predictive systems, an attacker may perturb inputs to cross a decision boundary; in generative systems, untrusted natural-language content can attempt to influence instruction hierarchy. The common factor is untrusted input, while mitigations depend on the threat model.

Security metrics are not model metrics

High accuracy, F1, or low loss is not a security property. Security evaluation depends on attacker capability, access, protected assets, and consequences. Robustness testing does not replace ordinary validation, and ordinary validation does not replace adversarial evaluation.

The underlying rule remains familiar: do not treat untrusted content as authority, preserve least privilege, separate model output from application authorization, and treat the model life cycle as part of the software supply chain.

60. Conclusion: A Simple Definition of a Secure System

When first entering cybersecurity, the number of tools can be intimidating. Nmap, Wireshark, Burp Suite, Metasploit, BloodHound, CrackMapExec/NetExec, Hashcat, Snort, Suricata, Wazuh, debuggers, disassemblers, fuzzing tools, and SAST/DAST products can look like unrelated specialties.

With time, the tools prove transient while the principles remain more durable.

The trust boundary learned while analyzing a packet reappears in a REST API. The principle observed in a stack overflow — that a small data-handling defect can alter control flow — appears in another form in unsafe deserialization. The attack path seen in an Active Directory graph reappears in a microservice authorization graph. Social engineering demonstrates that authentication is more than cryptography. DDoS shows that availability cannot be separated from capacity engineering. Digital forensics reminds us that evidence not designed into the system cannot be created retrospectively after the incident.

If I had to reduce secure software engineering to one sentence, I would express it this way:

Make the assumptions the system trusts explicit, remove unnecessary trust, verify the trust that remains, limit the impact of failure, and prove from the attacker's perspective that the control actually works.

This is also where the Zen character of security appears. More tools, more products, and more rules do not always produce a safer system. If an unnecessary service is closed, it needs no firewall rule. If no shell is used, command-escaping risk shrinks. If a physical file path is never accepted from the user, the path-traversal class narrows. If native object deserialization is not performed, there is no gadget chain to search for in that path. If a service has no unnecessary privileges, the impact of RCE is constrained. If data is not retained, that system cannot later leak it.

Sometimes the strongest security control is not something we add, but a capability we remove because the system does not need it.

The flag is still there. But the path to it is no longer made of accidental trust. Identity is checked at every meaningful gate, authorization is verified at each resource, data remains separate from commands at interpreter boundaries, each process carries only the privilege it needs, and every important event leaves evidence. If one control fails, another limits the impact. If something still gets through, we see it. If we see it, we respond. After responding, we make recurrence harder.

A secure system is not one that is never attacked. It is a system prepared for attack, with explicit boundaries, measurable behavior, and resilience under compromise.


A Short Note on Using These Standards Together

These sources serve different purposes. OWASP Top 10 is useful for awareness and risk groupings; ASVS for verifiable application-level security requirements; NIST SSDF for the secure development process; NIST CSF for the organizational cyber-risk lifecycle; CIS Controls for actionable organizational priorities; and MITRE ATT&CK for reasoning about adversary behavior and detection coverage. Establishing traceability between them is more useful than treating one as a replacement for the others.

Archive and Decompression Bombs

At file-upload and content-processing boundaries, checking only compressed size is insufficient. A ZIP Bomb can expand into disproportionate CPU, memory or disk usage, making resource budgets part of the security boundary.

Conceptual Map of the Secure Software Lifecycle

Secure development is not reducible to a single scanner. Threat Modeling makes assets, adversaries and trust boundaries explicit during design, while the Attack Surface identifies reachable entry points. Defense in Depth and Least Privilege then limit the consequence of a single control failure.

Weakness and vulnerability terminology should remain distinct. CWE classifies a weakness pattern, CVE identifies a specific disclosed vulnerability, and CVSS provides a standardized severity assessment. Keeping those concepts separate prevents a source-level defect category from being treated as if it were the same thing as a concrete field vulnerability.

At verification time, Static Application Security Testing examines source or intermediate representations without executing the application, whereas Dynamic Application Security Testing probes externally observable behavior of a running system. Fuzzing complements both by exercising parsers, protocols and boundary checks with malformed or unexpected inputs.

For dependency visibility, a Software Bill of Materials records the third-party components carried by the application. At the web boundary, Server-Side Request Forgery attempts to redirect server-originated requests toward attacker-chosen resources, while Cross-Site Request Forgery abuses an existing browser session to trigger an unintended state-changing action. The names are similar, but the trust boundaries and mitigations are different.

  • Apostol Vassilev et al. Adversarial Machine Learning: A Taxonomy and Terminology of Attacks and Mitigations. NIST AI 100-2e2025, 2025. https://doi.org/10.6028/NIST.AI.100-2e2025

Attack Surface of Generative-AI Applications

The threat model of an LLM-enabled application is broader than malicious user prompts. The system can include the model, prompt, retrieval pipeline, tool layer, database, embedding index, model artifacts, and user session.

User
 |
 v
Prompt / API
 |
 +--> RAG / Vector Store
 +--> Tools
 +--> External content
 |
 v
LLM
 |
 v
Output
 |
 +--> User
 +--> Code / command / database

Each boundary needs its own security controls.

Direct and indirect prompt injection

Direct prompt injection comes from a user attempting to override system policy.

Indirect prompt injection is carried inside content the model reads, such as a document, web page, email, or retrieved RAG passage.

External content should remain data rather than gaining system authority.

Prompt injection cannot be reliably solved by a blacklist of phrases because the attack is expressed through natural language.

Stronger controls include least privilege, constrained tools, separate trust domains, argument validation, approval gates, output validation, and audit logging.

The goal is not to guarantee that the model never interprets malicious text. The goal is to prevent a misled model from having unrestricted consequences.

Tool Authorization and Excessive Agency

Connecting an agent to the file system, shell, email, database, or external APIs amplifies model errors.

model error
   x
tool privilege
   =
operational risk

Prefer narrow tools such as read-only search or constrained database queries over universal shell execution.

High-impact writes can use:

plan
 -> dry-run
 -> diff
 -> validation
 -> approval
 -> commit

RAG, Vector, and Embedding Security

OWASP LLM08:2025 identifies risks in vector and embedding systems including unauthorized access, cross-context leakage, embedding inversion, and poisoning.

Authorization must be applied before retrieval.

user / tenant
   |
authorized partition
   |
retrieval
   |
LLM

A poisoned document can rank highly and make the model faithfully summarize malicious evidence. Ingestion should therefore retain source trust, hashes, approval state, version, uploader, and source type.

Model and Data Supply Chain

Local models reduce some external API exposure but introduce artifact supply-chain risks.

Verify model publisher, license, hashes or signatures, runtime, custom code requirements, tokenizer files, package dependencies, and the provenance of quantized derivatives.

Open weights do not imply that an arbitrary repackaged model artifact is trustworthy.

Local does not automatically mean secure

On-premises inference can improve data control while still remaining vulnerable to prompt injection, malicious local users, poisoned models, sensitive logs, over-privileged tools, weak file permissions, and outdated runtimes.

Penetration Testing LLM Applications

Traditional application testing should be extended with LLM-specific scenarios:

1. authorization bypass
2. direct prompt injection
3. indirect prompt injection
4. sensitive-data extraction
5. RAG poisoning
6. tool abuse
7. unsafe output handling
8. resource exhaustion
9. model/plugin supply chain
10. tenant isolation

A finding should preserve input, model/prompt version, retrieved evidence, tool calls, output, and application impact so it can be reproduced.

Improper output handling

LLM output can be interpreted later as SQL, HTML, Markdown, shell commands, or URLs. Model output must therefore be treated as untrusted data and validated before entering another interpreter.

Security Is a System Property

A model's refusal rate is not equivalent to application security.

model safety
 + application authorization
 + tool sandboxing
 + data isolation
 + output validation
 = system security

NIST's Generative AI Profile and the OWASP GenAI Top 10 both support lifecycle and system-level risk management rather than reliance on one prompt filter.

Unit 8: Policy Decisions, Formal Assurance, and Secure Deployment

Secure software is not only a matter of correct authentication, input validation, or cryptography. In large systems, authorization must account for where policy is administered, which contextual information feeds the decision, where the decision is computed, and where it is enforced. Security verification likewise spans techniques with very different evidence strength and cost, from static analysis to formal methods. At deployment time, secure code is only one part of the problem: configuration, artifact integrity, and release behavior are equally important.

8.1 Authorization decision architecture: PAP, PIP, PDP, and PEP

In a distributed system, “check the user's role and allow access” becomes difficult to govern as policy grows. A more durable design separates four questions:

Where is policy administered?       -> PAP
Where does decision context come from? -> PIP
Who computes allow/deny?            -> PDP
Who enforces the decision?          -> PEP

A Policy Administration Point (PAP) manages the policy life cycle. This includes more than a policy-editing UI: policy versions, change authority, approval flow, and rollback behavior all belong to administration.

A Policy Information Point (PIP) provides attributes and context required by the decision. Organizational unit, device posture, resource classification, time, network zone, or risk signals can be PIP inputs. Stale or incorrect attributes can make a logically correct PDP produce a security-incorrect outcome.

A Policy Decision Point (PDP) evaluates subject, action, resource, and context against policy:

decision = f(subject, action, resource, context, policy_version)

A Policy Enforcement Point (PEP) applies that result on the real request path. An API gateway, service filter, reverse proxy, in-process interceptor, or data-access boundary can act as a PEP.

This decomposition is an architectural reasoning model rather than a requirement to deploy four separate services. Small applications may implement the roles inside one process. The important property is that decision responsibilities remain explicit.

Decision caching and consistency

Remote policy evaluation can become a latency and availability dependency at high throughput. Caching decisions or attributes can reduce cost, but creates a security window between policy revocation and cache expiration. Revoked privileges, locked accounts, and changes in sensitive-resource classification therefore require explicit consistency semantics.

Longer TTL -> lower decision cost -> longer stale-privilege window
Shorter TTL -> fresher policy     -> more decision traffic

Critical operations may require fresh evaluation, while lower-risk, high-volume reads can sometimes use bounded caching. A cache key that contains only user identity but omits action, resource, or context can incorrectly reuse authorization across distinct requests.

Failure behavior

The system's behavior when authorization infrastructure is unavailable must be designed deliberately. “Fail closed” is a strong default, but safety-critical or mission-critical systems may need a separately controlled emergency path where availability consequences are themselves part of the threat model. The objective is not a generic fail-open mode; it is explicit failure semantics with auditable constraints.

8.2 Evidence strength of security verification techniques

No single analysis technique proves that software is “secure.” Methods should be selected according to the classes of defect they can observe and the assumptions under which they operate.

Static analysis

Static analysis examines source code, intermediate representations, or binaries without executing the program. Data flow, taint propagation, API misuse, unreachable code, and some memory errors can be detected this way.

Its strength is broad code coverage; limitations include false positives, environmental assumptions, and incomplete modeling of runtime state. The number of SAST findings is not itself a security metric: findings need triage by reachability, exploitability, and business impact.

Dynamic analysis and fuzzing

Dynamic analysis observes a running program. Fuzzing generates structured or semi-structured inputs to search for crashes, hangs, boundary errors, and unexpected state transitions. Coverage-guided fuzzers use execution coverage as feedback to explore new paths.

Dynamic methods observe real behavior, but only on paths actually reached. A rare state that is never generated can remain invisible.

Symbolic execution

Symbolic execution treats inputs as symbols rather than individual concrete values and represents execution paths as path constraints:

if x > 10:
    ...

Path A: x > 10
Path B: x <= 10

A constraint solver can generate inputs that reach a selected path. The technique can uncover deep boundary conditions, but branching creates the path explosion problem. Modeling complex external systems, concurrency, and environmental behavior can also be expensive.

Formal methods and model checking

Formal methods express system properties using mathematical models and logical specifications, then seek proofs or explore state spaces. Model checking can examine a property such as “no unauthorized state can transition into a privileged state” over a finite-state model.

The strength of a formal result is bounded by the property proved and the model used. An incorrect model, invalid assumption, or integration defect outside the proof scope can leave the real system vulnerable. A statement such as “formally verified” is therefore incomplete unless it identifies what was verified and under which assumptions.

Proof-carrying code

Proof-carrying code is historically and academically significant: a code producer supplies machine-checkable evidence that the code satisfies a specified safety policy, and the consumer validates the proof instead of repeating expensive analysis. It is not the dominant deployment model for general-purpose application development, but it illustrates a valuable principle—trust can sometimes be replaced with verifiable evidence.

8.3 Combining security verification layers

Verification layers are complements rather than substitutes:

Requirements review
        |
        v
Threat modeling
        |
        v
Code review + SAST
        |
        v
Unit/integration security tests
        |
        v
Fuzzing + DAST
        |
        v
Penetration testing
        |
        v
Production observation and incident feedback

Passing a SQL injection test does not establish correct authorization, and broad static-analysis coverage does not establish correct runtime identity boundaries. Assurance emerges from evidence targeted at different failure classes.

For high-criticality components, formal methods or model checking can add confidence to selected core properties. Proving a narrow authorization state machine, security kernel, or protocol transition is often more tractable than attempting a formal proof of the entire application.

8.4 Secure deployment and configuration drift

Secure code can be defeated by insecure deployment. Production security depends on preserving integrity across this chain:

Source -> Build -> Artifact -> Configuration -> Deployment -> Runtime

At each stage, the difference between “what was tested” and “what is running” should be minimized.

Immutable artifacts and provenance

Rebuilding in production under the same release tag can make the deployed binary differ from the tested one. A stronger pattern is to build an artifact once, verify it, and promote that same artifact across environments. Signatures, checksums, and provenance records can support integrity and origin claims, but a signature made by an untrusted key does not create trust by itself.

Configuration as code and secrets

Configuration should be versioned, reviewable, and reproducible where practical. Passwords, API keys, and private keys should remain separate from source and general configuration.

Security-sensitive defaults should be explicit, including:

  • debug and diagnostic endpoints,
  • sample accounts,
  • default passwords,
  • exposed management ports,
  • CORS and origin policy,
  • TLS verification,
  • file and directory permissions,
  • container capabilities and privileges,
  • service-account permissions.

Configuration drift

An environment that starts secure can diverge from its reference state through manual changes. Configuration drift is therefore a security issue, not merely an operational consistency problem. Continuous comparison, change records, and controlled reconciliation are stronger than assuming an environment remains hardened because it once was.

Progressive deployment and rollback

Canary, blue-green, and staged deployments also have security value. A security update can be observed for unexpected authorization or traffic behavior within a limited blast radius. Rollback design must consider whether the security data model remains compatible with the previous version; schema changes or key rotation, for example, can make rollback non-trivial.

8.5 Container, microservice, and virtualization boundaries

Using a container or virtual machine does not automatically make an application secure. The isolation mechanism must be understood in terms of which threats it actually contains.

Common container risks include:

  • privileged execution,
  • unnecessary Linux capabilities,
  • host filesystem or socket mounts,
  • running as root,
  • unsigned or obsolete base images,
  • embedded secrets,
  • weak network segmentation,
  • unbounded CPU or memory consumption.

In microservice systems, an in-process call becomes a network boundary. Service identity, TLS, timeouts, retries, circuit breakers, and distributed authorization create new failure surfaces. “The internal network is trusted” is therefore an insufficient design assumption.

8.6 Secure-development maturity

Managing security as a sequence of isolated tool purchases is difficult to sustain. A maturity model evaluates how consistently and measurably security practices operate across the organization.

The OWASP Software Assurance Maturity Model (SAMM) is an open framework for assessing current software-security practices, building a risk-informed assurance program, and measuring improvement. The current OWASP project page identifies SAMM 2.2.0 as the latest version.

Maturity should not become a race to the highest score. A critical payment platform and a low-risk internal utility need not receive the same control intensity. The target should reflect threat exposure, data sensitivity, regulation, change frequency, and incident cost.

A maturity score is also not a direct measure of actual security. A documented process does not prove that controls are effective. Process indicators should be evaluated alongside defect trends, incidents, remediation time, and attack-surface evidence.

8.7 Treating security assurance as a system property

NIST SP 800-160 Vol. 1 Rev. 1 frames trustworthy secure systems across the systems-engineering life cycle. This moves security away from a single “security team” checkpoint and treats it as the combined result of requirements, architecture, implementation, integration, verification, deployment, and operations.

A practical chain is:

Security requirement
    -> threat model
    -> architectural control
    -> enforceable policy
    -> verification evidence
    -> secure deployment
    -> runtime observation
    -> incident learning

Strong secure-software engineering does not come from one tool or one audit. It comes from keeping the assumptions and evidence across this chain traceable and mutually consistent.

Resource-Exhaustion Attacks and Secure Degradation

Security and reliability are not independent bolt-on features; both shape how a system contains faults and abuse. In secure software design, blast radius is not reduced by network segmentation alone; least privilege, resource quotas, secure defaults, reversible changes, explicit recovery procedures, and post-incident root-cause analysis must work together to constrain how far a fault or compromise can propagate. In denial-of-service scenarios in particular, the protection mechanism itself must not consume the availability it is intended to preserve.

  • Assess starvation risk for legitimate users when designing rate limits and quotas.
  • Scenario-test availability and security consequences of fail-open versus fail-closed behavior.
  • Verify that a protection mechanism does not exhaust CPU, memory, or database connection pools itself.

Unit 9: Capability, Provenance, and Side-Effect Safety for Language-Mediated Actions

Correctly interpreting a user request does not authorize the requested operation. A secure system treats language interpretation and execution authority as separate trust boundaries.

user text
  ↓
intent / parameter extraction
  ↓
premise validation
  ↓
parameter-provenance check
  ↓
capability / authorization gate
  ↓
allowlisted tool
  ↓
side effect

Intent is not authority

A classifier can identify an action with high confidence and still lack permission to execute it.

Execution can additionally require session authorization, resource scope, workspace capability, trusted parameter provenance, and policy approval.

Stricter acceptance policy for side-effecting actions

Read-only analysis and actions that create persistent or physical side effects do not need to share the same natural-language acceptance policy. As side-effect risk increases, the system can require stronger linguistic evidence and a better-grounded target.

Two measurements are especially useful:

  • the acceptance score of the strongest candidate,
  • the margin between the two strongest candidates.

A high top score with a very small margin can still indicate ambiguity. Clarification may be acceptable for a read-only query; an ambiguous side-effect request should not be converted directly into execution.

A side-effecting operation can require three independent classes of evidence:

  1. an explicit action expression in the user's current request,
  2. a target bound from trustworthy and current context,
  3. a separate capability and authorization check.

A record selected in an earlier turn, or a record found by retrieval, proves what the request may refer to; it does not prove that the user currently intends to act on it. Target grounding and action evidence should therefore remain separate checks.

The security objective is to reduce false-positive execution by raising the acceptance bar for side effects and by refusing to force ambiguity into the nearest executable command.

Provenance-constrained binding

For a critical parameter, origin matters as much as value.

resourceId = 381
source = USER_LITERAL

or:

resourceId = 381
source = VERIFIED_RESULT

can represent trusted binding classes.

A parameter derived only from fuzzy similarity or unconstrained generation should not automatically control a side-effecting action.

Premise validation

A user can request the second result when only one exists.

Before authorization, the system can verify that the requested item exists, the selection belongs to the current result version, the identifier is grounded, and the action is valid for the selected object.

Capability gates

Authorization is not only a user role. A particular workspace or session may simply not expose an operation.

Capabilities such as read, analyze, open, export, or execute can be checked independently of language understanding.

Tool registry and allowlisting

Allowing natural language to generate arbitrary function names greatly expands the attack surface.

A narrower design maps validated intents to registered tools with explicit schemas, side-effect classes, required capabilities, and failure behavior.

Hard veto for negated commands

A model can route “do not open” toward an OPEN intent because of lexical similarity.

For side effects, an independent negation guard can enforce:

action detected = true
negation detected = true
=> invoke = false

This is defense in depth, not a substitute for the intent model.

Bound chained side effects

A safe analytical chain should not silently grow into an autonomous action chain:

search
 -> rank
 -> select
 -> open
 -> export

Dependent analytical steps may be bounded, while a side-effecting step can require a separate explicit user action.

Safe default

When context is ambiguous, the secure default is to clarify, decline execution, or show supported options rather than invoke the nearest tool.

Validate tool output

Tool results should also cross a contract boundary:

tool result
 -> schema validation
 -> authorization-safe projection
 -> user-facing response

This prevents internal fields from leaking merely because the underlying function returned them.

Auditable decision events

Security telemetry can record verifiable events such as request class, selected tool, parameter provenance, capability decision, execution status, and error family.

This is not hidden reasoning storage.

Language-mediated action safety requires more than a prompt-injection filter. It requires separate gates for interpretation, parameter binding, authority, tool selection, and side effects.

References

  • Anley, C.; Heasman, J.; Lindner, F.; Richarte, G., The Shellcoder's Handbook: Discovering and Exploiting Security Holes, 2nd ed., Wiley, 2007.
  • BloodHound Enterprise / Community Edition documentation — https://bloodhound.specterops.io/
  • Cadar, Cristian; Dunbar, Daniel; Engler, Dawson. KLEE: Unassisted and Automatic Generation of High-Coverage Tests for Complex Systems Programs. OSDI 2008, USENIX Association. https://www.usenix.org/conference/osdi-08/klee-unassisted-and-automatic-generation-high-coverage-tests-complex-systems
  • Center for Internet Security, CIS Critical Security Controls v8.1 — https://www.cisecurity.org/controls/v8-1
  • CISA and partner organizations, Shifting the Balance of Cybersecurity Risk: Principles and Approaches for Secure by Design Software — https://www.cisa.gov/securebydesign
  • Easttom, C., Computer Security Fundamentals, Pearson.
  • Eilam, E., Reversing: Secrets of Reverse Engineering, Wiley, 2005.
  • FIRST, Common Vulnerability Scoring System (CVSS) — https://www.first.org/cvss/
  • Heather Adkins; Betsy Beyer; Paul Blankinship; Piotr Lewandowski; Ana Oprea; Adam Stubblefield. Building Secure & Reliable Systems: Best Practices for Designing, Implementing, and Maintaining Systems. O’Reilly Media, 2020.
  • Microsoft Learn, Active Directory Domain Services and Windows security documentation — https://learn.microsoft.com/windows-server/identity/
  • Mitnick, K. D.; Simon, W. L., The Art of Deception: Controlling the Human Element of Security, Wiley, 2002.
  • MITRE, ATT&CK Enterprise Matrix, current release information and technical catalog — https://attack.mitre.org/
  • MITRE, Common Weakness Enumeration (CWE) — https://cwe.mitre.org/
  • Necula, George C. Proof-Carrying Code. POPL 1997, pp. 106–119. https://doi.org/10.1145/263699.263712
  • National Institute of Standards and Technology. Artificial Intelligence Risk Management Framework: Generative Artificial Intelligence Profile (NIST AI 600-1). 2024. DOI: https://doi.org/10.6028/NIST.AI.600-1
  • NIST, Cybersecurity Framework (CSF) 2.0, 2024 — https://www.nist.gov/cyberframework
  • NIST, SP 800-160 Vol. 1 Rev. 1: Engineering Trustworthy Secure Systems, 2022 — https://csrc.nist.gov/pubs/sp/800/160/v1/r1/final
  • NIST, SP 800-218: Secure Software Development Framework (SSDF) Version 1.1, 2022 — https://csrc.nist.gov/pubs/sp/800/218/final
  • NIST, SP 800-63-4: Digital Identity Guidelines, 2025 — https://csrc.nist.gov/pubs/sp/800/63/4/final
  • NIST, SP 800-63B-4: Authentication and Authenticator Management, 2025 — https://csrc.nist.gov/pubs/sp/800/63/B/4/final
  • OWASP Foundation, Application Security Verification Standard (ASVS) 5.0.0 — https://owasp.org/www-project-application-security-verification-standard/
  • OWASP Foundation, OWASP Cheat Sheet Series — https://cheatsheetseries.owasp.org/
  • OWASP Foundation, OWASP Top 10:2025 — https://owasp.org/Top10/
  • OWASP Foundation, Software Assurance Maturity Model (SAMM) 2.2.0 — https://owasp.org/projects/samm
  • OWASP GenAI Security Project. LLM01:2025 Prompt Injection. https://genai.owasp.org/llmrisk/llm01-prompt-injection/
  • OWASP GenAI Security Project. LLM08:2025 Vector and Embedding Weaknesses. https://genai.owasp.org/llmrisk/llm082025-vector-and-embedding-weaknesses/
  • OWASP, Mobile Application Security (MAS) Project — https://mas.owasp.org/
  • OWASP, Web Security Testing Guide (WSTG) — https://owasp.org/www-project-web-security-testing-guide/
  • PortSwigger, Web Security Academy — https://portswigger.net/web-security
  • Snort Documentation — https://www.snort.org/documents
  • Spilcă, L., Spring Security in Action, Manning Publications.
  • Suricata Documentation — https://docs.suricata.io/
  • Wazuh Documentation — https://documentation.wazuh.com/
  • Wireshark Documentation — https://www.wireshark.org/docs/
Contents
QR code for this page