Mass Virtual Hosting Part Seven: Securing PHP with Suhosin
Suhosin is a Korean word which, roughly translated, means guardian angel. It is also the name of a clever PHP extension brought to us by the Hardened-PHP Project. When I found out it could provide transparent on-the-fly session and cookie encryption I thought sexual thoughts and sped off to install it. Fortunately for gentoo users, it's a simple matter of adding the suhosin USE flag to PHP and (re)compiling:
# echo "dev-lang/php suhosin" >> /etc/portage/package.use # emerge --newuse php
In fact, now is probably a good time to reevaluate your PHP USE flags; I tend to disable a bunch of functions that would simply not exist if certain extensions were not compiled in at all. This is what your stripped-down flags might look like:
[ebuild R ] dev-lang/php-5.2.13 USE="apache2 bcmath berkdb bzip2 cgi cli crypt ctype exif filter gd hash iconv ipv6 json mysql mysqli ncurses nls pcntl pcre pdo readline reflection session simplexml snmp spl ssl suhosin threads truetype unicode xml zip zlib -adabas -birdstep -calendar -cdb -cjk -concurrentmodphp -curl -curlwrappers -db2 -dbase -dbmaker -debug -discard-path -doc -empress -empress-bcs -esoob -fastbuild -fdftk -firebird -flatfile -force-cgi-redirect -frontbase -ftp -gd-external -gdbm -gmp -imap -inifile -interbase -iodbc (-java-external) -kerberos -kolab -ldap -ldap-sasl -libedit -mcve -mhash -msql -mssql -oci8 -oci8-instant-client -odbc -pic -posix -postgres -qdbm -recode -sapdb -sharedext -sharedmem -soap -sockets -solid -spell -sqlite -sybase -sybase-ct -sysvipc -tidy -tokenizer -wddx -xmlreader -xmlrpc -xmlwriter -xpm -xsl -yaz"
Once you've recompiled you're going to have to add the Suhosin configuration directives to your php.ini. For apache open /etc/php/apache-php5/php.ini and tack this on to the end:
; Logging suhosin.log.syslog = S_ALL suhosin.log.syslog.facility = LOG_USER suhosin.log.syslog.priority = LOG_WARNING suhosin.log.sapi = S_ALL ;suhosin.log.script ;suhosin.log.phpscript ;suhosin.log.script.name ;suhosin.log.phpscript.name ;suhosin.log.use-x-forwarded-for ; Executor Options suhosin.executor.max_depth = 1000000 suhosin.executor.include.max_traversal = 3 ;suhosin.executor.include.whitelist ;suhosin.executor.include.blacklist ;suhosin.executor.func.whitelist suhosin.executor.func.blacklist = "" ;suhosin.executor.eval.whitelist suhosin.executor.eval.blacklist = "" suhosin.executor.disable_eval = On suhosin.executor.disable_emodifier = On suhosin.executor.allow_symlink = Off ; Misc Options suhosin.simulation = Off suhosin.apc_bug_workaround = Off suhosin.sql.bailout_on_error = On ;suhosin.sql.user_prefix ;suhosin.sql.user_postfix suhosin.multiheader = On suhosin.mail.protect = 2 ;suhosin.memory_limit ; Transparent Encryption Options suhosin.session.encrypt = On suhosin.session.cryptkey = "INSERT RANDOM CRAP HERE" suhosin.session.cryptua = On suhosin.session.cryptdocroot = On suhosin.session.cryptraddr = 2 suhosin.session.checkraddr = 2 suhosin.cookie.encrypt = On suhosin.cookie.cryptkey = "INSERT RANDOM CRAP HERE" suhosin.cookie.cryptua = On suhosin.cookie.cryptdocroot = On suhosin.cookie.cryptraddr = 2 suhosin.cookie.checkraddr = 2 ;suhosin.cookie.cryptlist ;suhosin.cookie.plainlist ; Filtering Options suhosin.filter.action = 402 suhosin.cookie.max_array_depth = 100 suhosin.cookie.max_array_index_length = 64 suhosin.cookie.max_name_length = 64 suhosin.cookie.max_totalname_length = 256 suhosin.cookie.max_value_length = 10000 suhosin.cookie.max_vars = 100 suhosin.cookie.disallow_nul = On suhosin.get.max_array_depth = 50 suhosin.get.max_array_index_length = 64 suhosin.get.max_name_length = 64 suhosin.get.max_totalname_length = 256 suhosin.get.max_value_length = 512 suhosin.get.max_vars = 100 suhosin.get.disallow_nul = On suhosin.post.max_array_depth = 100 suhosin.post.max_array_index_length = 64 suhosin.post.max_name_length = 64 suhosin.post.max_totalname_length = 256 suhosin.post.max_value_length = 50000000 suhosin.post.max_vars = 200 suhosin.post.disallow_nul = On suhosin.request.max_array_depth = 100 suhosin.request.max_array_index_length = 64 suhosin.request.max_totalname_length = 256 suhosin.request.max_value_length = 65000 suhosin.request.max_vars = 200 suhosin.request.max_varname_length = 64 suhosin.request.disallow_nul = On suhosin.upload.max_uploads = 25 suhosin.upload.disallow_elf = On suhosin.upload.disallow_binary = Off suhosin.upload.remove_binary = Off ;suhosin.upload.verification_script suhosin.session.max_id_length = 128
Now head over to http://www.hardened-php.net/suhosin/configuration.html and tailor the configuration to suit your environment. Don't forget to blacklist dangerous functions like apache_child_terminate, apache_setenv, define_syslog_variables, eval, exec, ftp_connect, ftp_exec, ftp_get, ftp_login, ftp_nb_fput, ftp_put, ftp_raw, ftp_rawlist, highlight_file, ini_alter, ini_get_all, ini_restore, inject_code, openlog, passthru, php_uname, phpAds_remoteInfo, phpAds_XmlRpc, phpAds_xmlrpcDecode, phpAds_xmlrpcEncode, popen, posix_getpwuid, posix_kill, posix_mkfifo, posix_setpgid, posix_setsid, posix_setuid, posix_setuid, posix_uname, proc_close, proc_get_status, proc_nice, proc_open, proc_terminate, shell_exec, syslog, system, xmlrpc_entity_decode, exec, pipe, set_time_limit, popen, proc_open, parse_ini_file, show_source, mail, dl, ini_set, ini_alter, virtual, openlog, apc_add, apc_bin_dump, apc_bin_dumpfile, apc_bin_loadfile, apc_cache_info, apc_cas, apc_clear_cache, apc_compile_file, apc_dec, apc_define_constants, apc_delete_file, apc_delete, apc_exists, apc_fetch, apc_inc, apc_load_constants, apc_store, symlink and eval!
It seems Suhosin provides its own stack-smashing protection, potentially removing the need for the slow PIC (-fstack_protector_all) compile-time option. Until I get confirmation on this I'll be using both just to be safe.
Comments
[…] worse news is suhosin, a really sweet PHP security patch that I’ve written about before and which would give us the ability to do this has been abandoned for about two years now and there […]