Custom Software

Securing Custom Enterprise Software: Beyond the OWASP Top 10

Securing Custom Enterprise Software: Beyond the OWASP Top 10

The OWASP Top 10 is a starting checklist, not a security programme. Durable application security comes from threat modelling at design time, secure defaults enforced by frameworks, automated dependency and secret scanning in the pipeline, and a rehearsed response process for when something gets through.

Why a checklist is not a programme

The OWASP Top 10 catalogues categories of common weakness. It is genuinely useful as a shared vocabulary and as a review prompt. It is not a security strategy, because it says nothing about your system, your data, your adversaries or your blast radius.

Two applications can both pass an OWASP-aligned review and have wildly different risk. One processes public marketing content; the other holds payment instructions and personal health data. Treating them as equivalent wastes effort and leaves the important one under-protected.

A programme starts from assets and threats: what would hurt if disclosed, altered or made unavailable, who would want that, and which controls actually reduce the likelihood or impact.

Threat modelling that finishes in an afternoon

Threat modelling does not require a month of workshops. Draw the system as components, data stores and trust boundaries, then walk the four questions: what are we building, what can go wrong, what are we going to do about it, and did we do a good enough job.

For each trust boundary, ask what an attacker who already controls the outside of that boundary can do. This is what surfaces the systemic issues that code review misses: an internal service with no authentication, a shared database credential, an admin surface reachable from the public internet.

Record the output as a short list of accepted risks and mitigations with owners. A threat model that is not written down is a conversation, not a control.

  • Diagram components, data stores and trust boundaries.
  • Interrogate each boundary for what an attacker already inside it could reach.
  • Record accepted risks with owners rather than resolving everything immediately.
  • Revisit the model when the architecture changes, not annually.

Secure defaults and platform controls

The most reliable way to prevent a class of vulnerability is to remove the possibility. Parameterised queries by default eliminate injection for that data path. Output encoding in the template engine eliminates a large share of cross-site scripting. Framework-provided session handling eliminates most home-grown token mistakes.

Platform controls then close what remains. Enforce a strict Content Security Policy so injected script cannot execute, set a strict transport security policy so downgrade is impossible, and deny framing, sniffing and unnecessary permissions at the edge.

Where a control cannot be made default, make violating it loudly visible: a lint rule, a pipeline gate, or a required review. Silent exceptions become permanent.

Control layers mapped to common weakness classes
Weakness class Primary control Detection
InjectionParameterised queries, typed data accessStatic analysis, integration tests
Broken access controlCentral authorisation, deny by defaultAutomated authorisation tests per role
Cross-site scriptingOutput encoding, strict CSPStatic analysis, DAST
Vulnerable dependenciesPinned versions, SBOMDependency scanning in pipeline
Credential leakageSecret manager, no secrets in repoSecret scanning on commit
Insecure designThreat modelling, architecture reviewDesign review gate

Pipeline gates and incident response

Security controls only hold if they run automatically. Dependency scanning, secret scanning, static analysis and container image scanning should run on every change, with the build failing on high-severity findings and a documented exception path for genuine false positives.

Software bills of materials matter now that regulators and enterprise customers ask for them. Generating an SBOM per release costs almost nothing and turns vulnerability response from archaeology into a query.

Finally, rehearse the response. Know who triages a report, how a patch is released out of band, how customers are informed and what the legal disclosure obligations are. The first real test should not be the first time the process is used.

  • Run dependency, secret, static and image scanning on every change.
  • Fail the build on high-severity findings with a documented exception path.
  • Generate an SBOM per release and keep it queryable.
  • Rehearse the vulnerability response process before it is needed.

Frequently asked questions

Is passing an OWASP Top 10 review enough to be secure?

No. The OWASP Top 10 is a useful shared vocabulary for common weakness classes, but it does not account for your specific assets, adversaries or architecture. Threat modelling and automated pipeline controls are what make the difference.

What security tooling should run on every commit?

At minimum dependency scanning, secret scanning and static analysis, with container image scanning if you deploy containers. High-severity findings should fail the build so they cannot accumulate silently.

How often should a threat model be updated?

Whenever the architecture changes materially, such as adding a new trust boundary, a third-party integration, a new data classification or a new deployment environment. A fixed annual cadence is less useful than change-triggered review.

References

Related engineering guides

Engineer your next strategic platform

Estimate your project investment and delivery timeline instantly, or schedule an architectural discovery call with our engineering leadership.

Launch Cost Estimator Speak with an Architect