PS Product SecurityKnowledge Base

๐Ÿงฑ Secure by Design for AppSec and SDLC

Secure by Design Review Loop

Intro: The most useful parts of Secure by Design are not โ€œsecurity magicโ€ or one more checklist. They are design habits that make bugs, confused invariants, and unsafe assumptions harder to create in the first place.

What this page includes

  • the durable design ideas from Secure by Design that still matter for AppSec work;
  • what to import into modern SDLC, API, and product-security reviews;
  • where the book feels timeless, and where it needs modernization;
  • practical ways to translate the ideas into engineering standards and review prompts.

Why this book still matters

A lot of AppSec content starts from scanners, findings, or exploit classes. This book is more valuable as a design lens:

  • security is a concern that should shape the model, not a late feature ticket;
  • shallow models create broken business integrity and hidden abuse paths;
  • code constructs such as immutability, fail-fast contracts, and ordered validation remove whole classes of mistakes before runtime;
  • delivery pipelines should exercise security expectations continuously, not only during periodic review.

That framing still fits modern product security well.

What still feels highly current in 2026

1. Model the business invariant, not only the technical endpoint

One of the strongest lessons is that security failures often come from broken business integrity, not only classic CVEs.

Examples:

  • negative values that turn discounts into money leaks;
  • state transitions that were technically allowed but business-illegal;
  • โ€œtrustedโ€ integrations that bypass the rule a user-facing flow would enforce.

This is still exactly how modern product abuse and logic abuse show up.

2. Use DDD ideas where they clarify trust, ownership, and meaning

The DDD material is especially useful for security when it sharpens:

  • bounded contexts;
  • ubiquitous language;
  • entities, value objects, and aggregates;
  • explicit semantic boundaries between systems.

That does not mean every service needs full ceremonial DDD. It means security gets stronger when โ€œtenant ID,โ€ โ€œmoney,โ€ โ€œinventory delta,โ€ โ€œapproval state,โ€ or โ€œcallback URLโ€ are treated as meaningful types with rules, not casual strings passed around the codebase.

3. Domain primitives are a strong defensive engineering pattern

A modern interpretation of domain primitives works very well for:

  • identifiers;
  • tenant IDs;
  • emails and usernames;
  • URLs and callback destinations;
  • currency and quantities;
  • secrets and one-time tokens.

The high-value idea is simple: put parsing, normalization, and invariant checks into the smallest useful domain type instead of re-implementing them ad hoc across handlers and services.

4. Ordered validation is more useful than generic โ€œvalidate inputโ€ advice

A particularly reusable idea is to validate in a deliberate order:

  1. origin โ€” where did the data come from and what trust level does it have?
  2. size โ€” can it explode memory, CPU, parser depth, or downstream cost?
  3. lexical content โ€” allowed character set or coarse shape;
  4. syntax โ€” does it conform to the expected structural format?
  5. semantics โ€” is it valid in the business context?

This is a much better review pattern than throwing regexes everywhere.

5. Fail fast on illegal input and illegal state

Fail-fast contracts, constructor preconditions, and invariant checks remain valuable because they make ambiguous or unsafe objects impossible to construct in the first place.

That helps with:

  • data integrity;
  • hidden privilege transitions;
  • malformed internal state that later becomes a security bug;
  • โ€œthis should never happenโ€ paths that attackers love to reach.

6. Handle failure as a security topic, not only a reliability topic

The failure-handling chapters map directly to modern AppSec concerns:

  • avoid leaking secrets or internals in exception flows;
  • separate business exceptions from technical exceptions;
  • prevent cascading failures that widen blast radius;
  • design resilience and backpressure as part of availability.

This is especially relevant in event-driven and microservice-heavy systems.

What needs modernization or selective use

XML and parser examples are still educational, but not the center of gravity

The XML and Billion Laughs material still teaches a good lesson about parsers, expansion, and operational limits, but in many product teams today the more common high-value parser risks are:

  • JSON and schema ambiguity;
  • archive and media parsing;
  • markdown or template rendering;
  • SSRF-capable fetchers;
  • unsafe third-party API consumption.

The book predates todayโ€™s API-specific framing

The design principles are strong, but they should now be mapped to current API failure modes such as:

  • broken object-level authorization;
  • property-level authorization failures;
  • unrestricted business-flow abuse;
  • unsafe consumption of upstream APIs.

Cloud-native specifics need a translation layer

The microservice and pipeline advice is still useful, but modern teams should reinterpret it through:

  • workload identity instead of shared secrets;
  • admission policy and IaC guardrails;
  • signed artifacts and evidence chains;
  • service-to-service authorization and egress control;
  • API and queue contracts as enforceable review artifacts.

How to apply the book in a real SDLC

1) Add a design-invariant section to architecture reviews

For every feature or service change, capture:

  • what object or workflow invariants must stay true;
  • what state transitions are illegal;
  • what caller or system is allowed to change that state;
  • what data type should stop being โ€œjust a string.โ€

2) Treat domain primitives as a practical coding standard

Strong candidates:

  • TenantId
  • SpaceId / InvoiceId / OrderId
  • EmailAddress
  • SafeRedirectUri
  • MoneyAmount
  • SignedWebhookSecret
  • OneTimeToken

Each should own normalization and validation rules.

3) Use secure-construction rules in code review

Ask:

  • can this object exist in an invalid state?
  • do constructors or factories enforce required invariants?
  • are mutable collections or mutable references leaking out of the object?
  • do setters allow bypassing business rules after creation?

4) Move design expectations into the pipeline

A modern pipeline translation looks like:

  • unit tests for invariants and dangerous state transitions;
  • contract tests for authorization and tenant isolation;
  • schema linting and negative tests for malformed inputs;
  • feature-flag and rollback tests for high-risk flows;
  • evidence that security-relevant invariants were exercised before release.

5) Use the ideas to improve legacy code gradually

The book is also good at explaining how to strengthen legacy code without rewriting everything:

  • introduce domain primitives at system edges first;
  • wrap dangerous primitives with safer factories;
  • centralize validation rules before attempting broad refactors;
  • replace โ€œstringly typedโ€ trust decisions one hotspot at a time.

High-value review prompts

  • Which values in this codebase should become domain primitives?
  • What business rule would still fail even if the infrastructure and auth were perfect?
  • Can an attacker drive the system into an illegal but technically representable state?
  • Are we validating origin, size, lexical content, syntax, and semantics in the right order?
  • Which exception or fallback paths would leak internal structure, secrets, or privileged behavior?
  • Which service boundary is pretending to be simpler than the real domain semantics?

Where this should connect inside the KB

This material is most useful as a strengthening layer for:

  • web and API architecture review;
  • threat modeling;
  • stack-specific secure engineering guides;
  • CI/CD quality gates;
  • business-logic abuse and product-abuse analysis.

---Author attribution: Ivan Piskunov, 2026 - Educational and defensive-engineering use.