Suhosin HOWTOs

Compile for debugging and development

How to compile the Suhosin extension for debugging and development purposes.

Linux and most other platforms

  • clean it all up from previous builds

    $ make distclean
    
  • rebuild configure for your particular PHP version

    $ /opt/php/5.6.3/bin/phpize
    
  • run configure with experimental option

    $ ./configure --with-php-config=/opt/php/5.6.3/bin/php-config --enable-suhosin-experimental
    
  • compile with debug option

    $ make -j2 CFLAGS="-DSUHOSIN_DEBUG=1"
    
  • testing...

    $ make test NO_INTERACTION=1 TESTS=tests/
    
  • run custom scripts without installation:

    $ /opt/php/5.6.3/bin/php -d extension=./suhosin/modules/suhosin.so foo.php
    $ /opt/php/5.6.3/bin/php -d extension=./suhosin/modules/suhosin.so -r 'phpinfo();'
    

MacOSX 32bit or 64bit

Compilation works just fine as describes above. But you can specify the target architecture, too.

Just add CFLAGS="-arch x86_64" or CFLAGS="-arch i386" where appropriate:

$ make distclean
$ /opt/php/5.6.3/bin/phpize
$ ./configure --with-php-config=/opt/php/5.6.3/bin/php-config --enable-suhosin-experimental CFLAGS="-arch x86_64"
$ make -j2 CFLAGS="-DSUHOSIN_DEBUG=1 -arch x86_64"

Encryption Features

Session Encryption

Session data - usually held in $_SESSION - can be encrypted transparently on the server. This is done by encrypting the data just before storage and decrypting upon restoring $_SESSION. That way storage handlers, e.g. for Memcache or database session storage, will only ever handle encrypted data.

This feature is enabled by default, but needs custom configuration. You should set a custom cryptkey. Example php.ini:

suhosin.session.encrypt = On

;; the cryptkey should be generated, e.g. with 'apg -m 32'
suhosin.session.cryptkey = zuHywawAthLavJohyRilvyecyondOdjo
suhosin.session.cryptua = On
suhosin.session.cryptdocroot = On

;; IPv4 only
suhosin.session.cryptraddr = 0
suhosin.session.checkraddr = 0

Blocking Functions

Whitelist vs blacklist

Throughout Suhosin whitelisting and blacklisting are mutually exclusive - you either use a whitelist for a feature or a blacklist. If both happen to be defined, the whitelist takes precedence and the blacklist is ignored.

Whitelisting

So, let's explicitly allow a bunch of functions and disable the rest.

suhosin.executor.func.whitelist = htmlentities,htmlspecialchars,base64_encode
suhosin.executor.eval.whitelist = htmlentities

This will allow the following code to be executed - the eval whitelist corresponds to the eval() call:

<?php
echo htmlspecialchars('<test>');
eval('echo htmlentities("<test>");');

Note: The function whitelist (or blacklist) always takes precedence over the eval whitelist (or blacklist). E.g. it would not have been possible to eval htmlspecialchars() in this example.

Blacklisting

Now, let's disable a few dangerous functions and allow the rest. The example shows how to disable functions executed with eval() in addition to functions already blacklisted.

suhosin.executor.func.blacklist = assert,unserialize,exec,popen,proc_open,passthru,shell_exec,system
suhosin.executor.eval.blacklist = mail,parse_str,mt_srand

Note: Of course it is possible to combine function blacklist and eval whitelist or vice versa. The function whitelist/blacklist will always be applied, even in an eval() context.

Finding out which functions to allow

In order to find out which functions to allow for whitelisting (or to remove from the blacklist for blacklisting), you can use the simulation mode and enable logging:

suhosin.simulation = 1
suhosin.log.file = 511
suhosin.log.file.name = /tmp/suhosin-alert.log

Now, use your application and the logfile will show any violation:

Nov 16 12:01:34 [63213] ALERT-SIMULATION - function outside of whitelist called: preg_replace() (attacker '10.0.0.1', file '/var/www/foo.php', line 2)
Nov 16 12:01:34 [63213] ALERT-SIMULATION - function outside of whitelist called: strtoupper() (attacker '10.0.0.1', file '/var/www/foo.php', line 2)

When done, don't forget to re-arm Suhosin:

suhosin.simulation = 0

eval() and other language constructs

Some functions - most notably eval() - can not be blocked by a function whitelist or blacklist, because they are language constructs rather than functions. Others are __halt_compiler(), array(), die(), empty(), exit(), isset(), list(), unset()...

In order to disable eval() entirely, Suhosin provides the following option:

suhosin.executor.disable_eval = On

Even more

Please take a look at the configuration page for a complete list of possible configuration options.