Showing posts with label security. Show all posts
Showing posts with label security. Show all posts

Thursday, 3 September 2026

Secure by Default Is Not Enough — Frameworks Need Security Evidence

Secure by Default Is Not Enough — Frameworks Need Security Evidence

“Secure by default” sounds reassuring.

It is also something almost every serious framework wants to say.

Use parameterized queries. Set sensible cookie defaults. Escape output. Protect forms from CSRF. Make unsafe configuration harder.

All of that matters.

But while designing EvolvePHP 2, I have become increasingly uncomfortable with stopping there.

Because there is another question behind every security claim:

How do we know the protection actually holds?

That is where I think frameworks need to go further.

Not just secure defaults.

Security evidence.

A security claim is not the same as a security guarantee

Imagine a framework says:

“Request state is isolated between persistent-worker executions.”

That sounds good.

But what actually supports the claim?

Documentation?

A code comment?

A few unit tests?

Or have we repeatedly tried to make one execution leak into another?

The distinction matters.

For EvolvePHP, one of the architectural rules is that execution-specific state should not survive into the next execution.

That may include:

current user
current tenant
transaction context
authorization state
trace context
temporary listeners

If I claim those things are isolated, I want more than confidence in the implementation.

I want tests designed specifically to prove me wrong.

Tests should attack the assumptions

A normal test might do this:

Execution A starts
Execution A completes
Execution B starts
Execution B completes

Everything passes.

Great.

But an assurance test should be more hostile.

Execution A
User: Alice
Tenant: Company A
Handler: succeeds

Execution B
Anonymous
No tenant
Handler: throws

Execution C
User: Bob
Tenant: Company B
Cleanup: partially fails

Then ask:

  • Can Bob see Alice's state?

  • Does an anonymous execution inherit authentication?

  • Is a transaction left open?

  • Does trace context survive?

  • Is the worker reused after cleanup becomes uncertain?

That is a different mindset.

The goal isn't only to show that the framework works.

It is to discover the conditions under which it stops being safe.

Some rules should be architectural invariants

There are certain things I would rather make difficult or impossible by design.

For example:

Application-scoped service
        ↓
Execution-scoped CurrentUser

That is a dangerous lifetime relationship in a long-running process.

Instead of documenting:

“Please don't do this.”

the container should reject it when possible.

Likewise, if cleanup fails, EvolvePHP should not quietly assume the worker is safe.

The rule should be:

Cleanup successful
→ reuse may continue

Cleanup failed or uncertain
→ quarantine

Then the test suite should continuously verify that no path accidentally turns cleanup failure into safe reuse.

These are the kinds of claims that can become measurable.

Unit tests are only the beginning

Traditional tests are necessary, but they are not enough for the kinds of guarantees I want EvolvePHP to eventually make.

Different problems need different kinds of pressure.

Property-based tests can generate many combinations of lifecycle state rather than testing only examples we thought of manually.

Fuzzing can feed unexpected input into parsers, routing, protocol boundaries, and other exposed surfaces.

Mutation testing can deliberately alter security-sensitive code and show whether our tests actually notice.

Fault injection can simulate database failures, reset failures, telemetry failures, timeouts, and partial cleanup.

Soak testing can run persistent workers through hundreds of thousands of executions while alternating users, tenants, successes, failures, and memory pressure.

The idea is not complexity for its own sake.

It is proportional evidence for important claims.

Security is bigger than the runtime

Execution isolation is only one part of security.

A PHP framework also has to think about familiar application risks:

  • SQL injection

  • XSS

  • CSRF

  • SSRF

  • broken authorization

  • insecure sessions

  • unsafe redirects

  • secrets exposure

  • file and path handling

  • dependency vulnerabilities

  • insecure defaults

I don't want EvolvePHP to invent its own definition of application security.

That is why the direction includes alignment with established security references such as OWASP ASVS and secure-development practices such as NIST SSDF.

Not so I can put a badge on the website.

But so there is a recognized baseline asking:

What security requirements apply here?

and:

What evidence do we have that we followed them?

Framework security and application security are different

This distinction is important.

Even a well-designed framework cannot guarantee that every application built with it is secure.

A developer can still make an authorization mistake.

A company can expose a secret.

A deployment can be misconfigured.

A custom plugin can introduce a vulnerability.

So I do not want EvolvePHP to eventually claim:

“Applications built with EvolvePHP are secure.”

That would be irresponsible.

A better goal is:

EvolvePHP should provide safe defaults, enforce important boundaries where possible, expose insecure conditions, and make security verification easier for application teams.

That is a much more defensible promise.

“Secure by default” should be the starting point

I still want secure defaults.

Developers should not need to be security specialists just to get sensible behavior.

But defaults alone are not enough for software that may eventually run financial systems, SaaS platforms, government applications, or other long-lived business systems.

The stronger question is:

Can we show why we believe this behavior is safe?

That is the direction I want EvolvePHP to move toward.

Not:

“Trust us. We designed it securely.”

But:

These are our security and safety claims. These are the boundaries. And here is the evidence continuously trying to prove those claims wrong.

For me, that is a much stronger foundation for trust.