Nyholm / psr7

A super lightweight PSR-7 implementation

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Broken PSR-7 immutability

zonuexe opened this issue · comments

This issue is related to php/php-src#8351 and vimeo/psalm#7857.

Most PSR-7 interfaces ensure immutability by providing withXXX instead of setXXX,
but many PSR-7 implementations expose constructors so objects can be easily modified.

$uri = $psr17Factory->createURI('http://tnyholm.se');
var_dump([spl_object_id($uri) => (string)$uri]);

$uri->__construct('https://evil.example.com/');
var_dump([spl_object_id($uri) => (string)$uri]);

This issue seems to have been mentioned in a 2017 article.
https://www.simonholywell.com/post/2017/03/php-and-immutability/

And yesterday I learned about this issue by @twada at a conference in Japan called "PHPerKaigi 2022".
https://speakerdeck.com/twada/growing-reliable-code-phperkaigi-2022?slide=84

PSR-7 interfaces do not define those constructors, so it's just an implementation package issue.

I don't think there are any security holes due to this issue, but it makes it easier for application implementers to implement against the PSR-7 and PSR-15 concepts.

I replied on php/php-src#8351 and I think this applies here to:

"Encapsulation" relates to the public API of some software design. A constructor doesn't belong to what "encapsulation" refers to. Yes, you can mutate the object. So does reflection with private properties. Calling the constructor is like using reflection to me: do it if you know why you shouldn't 🤷 ...

I'd suggest closing this as "won't fix".

You are very correct. But I think we should not really care in this case.

Thank you for reporting.