Suhosin HOWTOs
Contents
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
Cookie Encryption
Cookie values can be encrypted transparently. Cookies are stored within the client's web browser and are transferred with the HTTP header. By encrypting cookies, you may protect your application against numerous attacks, such as
- cookie tampering: An attacker may try to guess other reasonable cookie values to attack the application.
- inter-application cookie usage: Incorrectly configured applications may have the same session storage, e.g. sessions all stored in /tmp. A cookie from one application can never be reused for another application as long as the encryption key differs.
- knowing what exactly is stored in the cookie
However:
- Cookies are still stored on the client and should not be trusted unchecked in any case.
- Even with encryption, please do not store secret data in cookies, e.g. passwords.
- An attacker may try to reuse an old cookie.
- The cookie size is slightly bigger with encryption than without encryption. Some applications make use of huge cookies in the first place and may not work correctly if the encrypted cookie is too big for the web browser.
This feature is disabled by default.
You can specify which cookies to encrypt (cryptlist) or which to exempt (plainlist). Note: Cookies handled on client side with JavaScript as well as on server side should not be encrypted, e.g. listed in suhosin.cookie.plainlist or omitted in suhosin.cookie.cryptlist.
Example php.ini:
suhosin.cookie.encrypt = On ;; the cryptkey should be generated, e.g. with 'apg -m 32' suhosin.cookie.cryptkey = oykBicmyitApmireipsacsumhylWaps1 suhosin.cookie.cryptua = On suhosin.cookie.cryptdocroot = On ;; whitelist/blacklist (use only one) ;suhosin.cookie.cryptlist = WALLET,IDEAS suhosin.cookie.plainlist = LANGUAGE ;; IPv4 only suhosin.cookie.cryptraddr = 0 suhosin.cookie.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.