Type Driven Design

Alex Tatulchenkov
1 min readApr 19, 2020

Let’s look how can we implement all previously mentioned principles (Lord of the Sinks, Least Power Principle and Forget-me-not) in our PHP application to make it more secure.

Assume we have a following code which loads images of some items

<img src="/showImage?filename=42.png">

The /showImageendpoint takes a filename parameter and returns the contents of the specified file. The image files themselves are stored on disk in the location /var/www/images/. Application expects files to be located in images folder and simply appends $_GET['filename']to the base dir /var/www/images/. In such case an attacker can read arbitrary file

http://vulnerable.tld/?filename=../../../etc/passwd

PHP has only 8 data types and the most dangerous one is string. In most cases developers use strings and string data flows here and there. But if we look attentively we’ll realize that our application expects not a string but a ItemName. PHP does not have such type but we can create it and to force it to follow our rules. For this purpose we can use ValueObject pattern:

Introducing a new type we can safely transfer it all over the system and not be afraid of losing knowledge regarding validity of related data (Forget-me-not).

Using new type we can follow Parse, don't validate principle and Least Power Principle by instantiating ItemName as close to source as possible.

And finally, near the sink we extract string value of ItemName using value() method (raw data) and do context specific escaping or additional check — in this case we should ensure that normalized with realpath() filename starts with /var/www/images/ .

--

--

Alex Tatulchenkov

Senior Software Engineer at Intetics Inc., AppSec Manifesto evangelist