Repository: stefanesser/suhosin Branch: master Commit: 611d261ea69d Files: 246 Total size: 550.3 KB Directory structure: gitextract_i6z6y2bt/ ├── .gitignore ├── .travis.yml ├── CREDITS ├── Changelog ├── LICENSE ├── README.md ├── aes.c ├── config.m4 ├── config.w32 ├── crypt.c ├── ex_imp.c ├── execute.c ├── header.c ├── ifilter.c ├── log.c ├── mbregex/ │ ├── COPYING.LIB │ └── mbregex.h ├── mbregex.h ├── memory_limit.c ├── php_suhosin.h ├── pkg/ │ └── build_deb.sh ├── pledge.c ├── pledge.h ├── post_handler.c ├── rfc1867_new.c ├── session.c ├── sha256.c ├── sha256.h ├── suhosin.c ├── suhosin.ini ├── suhosin_logo.h ├── suhosin_rfc1867.h ├── tests/ │ ├── cookie/ │ │ ├── crypt.checkraddr_4.phpt │ │ ├── crypt.checkraddr_4_incorrect.phpt │ │ ├── crypt.cryptlist.phpt │ │ ├── crypt.docroot.phpt │ │ ├── crypt.invalid.phpt │ │ ├── crypt.key_default.phpt │ │ ├── crypt.key_empty.phpt │ │ ├── crypt.key_empty_remote_addr.phpt │ │ ├── crypt.no_encryption.phpt │ │ ├── crypt.plainlist.phpt │ │ ├── crypt.raddr_1.phpt │ │ ├── crypt.raddr_2.phpt │ │ ├── crypt.raddr_3.phpt │ │ ├── crypt.raddr_4.phpt │ │ └── crypt.ua.phpt │ ├── empty.inc │ ├── executor/ │ │ ├── allow_symlink_off.phpt │ │ ├── allow_symlink_on.phpt │ │ ├── disable_emod_off.phpt │ │ ├── disable_emod_on.phpt │ │ ├── disable_eval_off.phpt │ │ ├── disable_eval_on.phpt │ │ ├── eval_blacklist.phpt │ │ ├── eval_blacklist_printf.phpt │ │ ├── eval_blacklist_printf_function_exists.phpt │ │ ├── eval_whitelist_absmax.phpt │ │ ├── eval_whitelist_call_user_func.phpt │ │ ├── function_blacklist.phpt │ │ ├── function_blacklist_printf.phpt │ │ ├── function_blacklist_printf_function_exists.phpt │ │ ├── function_call_user_func.phpt │ │ ├── function_whitelist.phpt │ │ ├── function_whitelist_absmax.phpt │ │ ├── function_whitelist_call_user_func.phpt │ │ ├── function_whitelist_function_exists.phpt │ │ ├── function_whitelist_maxabs.phpt │ │ ├── function_whitelist_without_function_exists.phpt │ │ ├── memory_limit.phpt │ │ ├── memory_limit_64bit.phpt │ │ ├── memory_limit_64bit_10G.phpt │ │ ├── memory_limit_negative.phpt │ │ ├── memory_limit_other_hardlimit.phpt │ │ ├── preg_replace.phpt │ │ ├── preg_replace_error.phpt │ │ ├── recursion_maxdepth.phpt │ │ └── user_session_handler.phpt │ ├── filter/ │ │ ├── cookie_disallow_nul.phpt │ │ ├── cookie_disallow_ws.phpt │ │ ├── cookie_max_array_depth.phpt │ │ ├── cookie_max_array_index_length.phpt │ │ ├── cookie_max_name_length.phpt │ │ ├── cookie_max_totalname_length.phpt │ │ ├── cookie_max_value_length.phpt │ │ ├── cookie_max_vars.phpt │ │ ├── filter_action_302.phpt │ │ ├── filter_action_php.phpt │ │ ├── filter_logging_statistics.phpt │ │ ├── get_allow_ws.phpt │ │ ├── get_disallow_nul.phpt │ │ ├── get_disallow_ws.phpt │ │ ├── get_filter_1.phpt │ │ ├── get_filter_2.phpt │ │ ├── get_globals.phpt │ │ ├── get_max_array_depth.phpt │ │ ├── get_max_array_index_length.phpt │ │ ├── get_max_name_length.phpt │ │ ├── get_max_totalname_length.phpt │ │ ├── get_max_value_length.phpt │ │ ├── input_filter_allow_nul.phpt │ │ ├── input_filter_request_max_value_length.phpt │ │ ├── post_disallow_nul.phpt │ │ ├── post_disallow_nul_rfc1867.phpt │ │ ├── post_disallow_ws.phpt │ │ ├── post_fileupload_array_index_blacklist.phpt │ │ ├── post_fileupload_array_index_whitelist.phpt │ │ ├── post_fileupload_filter_1.phpt │ │ ├── post_fileupload_filter_2.phpt │ │ ├── post_filter_1.phpt │ │ ├── post_filter_2.phpt │ │ ├── post_filter_empty_avar.phpt │ │ ├── post_filter_empty_var.phpt │ │ ├── post_max_array_depth.phpt │ │ ├── post_max_array_depth_rfc1867.phpt │ │ ├── post_max_array_index_length.phpt │ │ ├── post_max_array_index_length_rfc1867.phpt │ │ ├── post_max_name_length.phpt │ │ ├── post_max_name_length_rfc1867.phpt │ │ ├── post_max_totalname_length.phpt │ │ ├── post_max_totalname_length_rfc1867.phpt │ │ ├── post_max_value_length.phpt │ │ ├── post_max_value_length_rfc1867.phpt │ │ ├── request_array_index_blacklist.phpt │ │ ├── request_array_index_whitelist.phpt │ │ ├── request_disallow_nul.phpt │ │ ├── request_disallow_ws.phpt │ │ ├── request_max_array_depth.phpt │ │ ├── request_max_array_index_length.phpt │ │ ├── request_max_name_length.phpt │ │ ├── request_max_totalname_length.phpt │ │ ├── server_encode_off.phpt │ │ ├── server_encode_on.phpt │ │ ├── server_filter.phpt │ │ ├── server_strip_off.phpt │ │ ├── server_strip_on.phpt │ │ ├── server_user_agent_strip_off.phpt │ │ ├── server_user_agent_strip_on.phpt │ │ ├── suhosin_upload_disallow_binary_off.phpt │ │ ├── suhosin_upload_disallow_binary_on.phpt │ │ ├── suhosin_upload_disallow_binary_utf8.phpt │ │ ├── suhosin_upload_disallow_binary_utf8fail.phpt │ │ ├── suhosin_upload_disallow_elf.phpt │ │ ├── suhosin_upload_disallow_elf_off.phpt │ │ ├── suhosin_upload_max_uploads.phpt │ │ ├── suhosin_upload_remove_binary.phpt │ │ ├── suhosin_upload_remove_binary_utf8.phpt │ │ └── suhosin_upload_remove_binary_utf8fail.phpt │ ├── funcs/ │ │ ├── crypt_blowfish.phpt │ │ ├── crypt_ext_des.phpt │ │ ├── crypt_md5.phpt │ │ ├── crypt_std_des.phpt │ │ └── sha256.phpt │ ├── include/ │ │ ├── include_allow_writable_files_off.phpt │ │ ├── include_allow_writable_files_on.phpt │ │ ├── include_blacklist.phpt │ │ ├── include_blackwhitelist_empty.phpt │ │ ├── include_constant.phpt │ │ ├── include_etc_passwd.phpt │ │ ├── include_max_traversal.phpt │ │ ├── include_nul_in_filename.phpt │ │ ├── include_once_constant.phpt │ │ ├── include_once_tmpvar.phpt │ │ ├── include_once_var.phpt │ │ ├── include_tmpvar.phpt │ │ ├── include_too_long.phpt │ │ ├── include_uploaded_file_diff_filename.phpt │ │ ├── include_uploaded_file_from_FILES.phpt │ │ ├── include_var.phpt │ │ ├── include_whitelist.phpt │ │ ├── require_constant.phpt │ │ ├── require_once_constant.phpt │ │ ├── require_once_tmpvar.phpt │ │ ├── require_once_var.phpt │ │ ├── require_tmpvar.phpt │ │ └── require_var.phpt │ ├── logging/ │ │ ├── log_max_error_length.phpt │ │ ├── logscript_executable.phpt │ │ ├── logscript_nonexecutable.phpt │ │ ├── logscript_nonexistant.phpt │ │ ├── use_x_forwarded_for_off.phpt │ │ ├── use_x_forwarded_for_off_no_remote_addr.phpt │ │ ├── use_x_forwarded_for_on.phpt │ │ └── use_x_forwarded_for_on_no_x_forwarded.phpt │ ├── misc/ │ │ ├── disable_display_errors_fail.phpt │ │ ├── disable_display_errors_off.phpt │ │ ├── disable_display_errors_on.phpt │ │ ├── mailprotect_1_header_nl.phpt │ │ ├── mailprotect_1_header_nlnl.phpt │ │ ├── mailprotect_1_subject.phpt │ │ ├── mailprotect_1_subject_long.phpt │ │ ├── mailprotect_1_to.phpt │ │ ├── mailprotect_1_to_long.phpt │ │ ├── mailprotect_2_bcc.phpt │ │ ├── mailprotect_2_cc.phpt │ │ ├── mailprotect_2_to.phpt │ │ ├── mt_srand_ignore_off.phpt │ │ ├── mt_srand_ignore_on.phpt │ │ ├── protectkey_off.phpt │ │ ├── protectkey_on.phpt │ │ ├── srand_ignore_off.phpt │ │ └── srand_ignore_on.phpt │ ├── session/ │ │ ├── PHPSESSID_max_id_length_ok.phpt │ │ ├── PHPSESSID_max_id_length_toolong.phpt │ │ ├── crypt.checkraddr_4.phpt │ │ ├── crypt.checkraddr_4_incorrect.phpt │ │ ├── crypt.docroot.phpt │ │ ├── crypt.key_default.phpt │ │ ├── crypt.key_empty.phpt │ │ ├── crypt.key_empty_remote_addr.phpt │ │ ├── crypt.no_encryption.phpt │ │ ├── crypt.raddr_1.phpt │ │ ├── crypt.raddr_2.phpt │ │ ├── crypt.raddr_3.phpt │ │ ├── crypt.raddr_4.phpt │ │ ├── crypt.ua.phpt │ │ ├── max_id_length_ok.phpt │ │ ├── max_id_length_toolong.phpt │ │ ├── session_recursive_crash.phpt │ │ ├── session_recursive_crash2.phpt │ │ └── sessionhandler.inc │ ├── skipif.inc │ ├── skipifcli.inc │ ├── skipifnotcli.inc │ └── sql/ │ ├── connect.inc │ ├── mysqli_comment_conditional.phpt │ ├── mysqli_comment_cstyle_fail.phpt │ ├── mysqli_comment_hashstyle_fail.phpt │ ├── mysqli_comment_sqlstyle.phpt │ ├── mysqli_comment_sqlstyle_fail.phpt │ ├── mysqli_connect_invalid_username.phpt │ ├── mysqli_multiselect.phpt │ ├── mysqli_multiselect_fail.phpt │ ├── mysqli_multiselect_subselect.phpt │ ├── mysqli_no_constraints.phpt │ ├── mysqli_open_comment.phpt │ ├── mysqli_open_comment_fail.phpt │ ├── mysqli_union.phpt │ ├── mysqli_union_fail.phpt │ ├── mysqli_user_match_error.phpt │ ├── mysqli_user_match_ok.phpt │ ├── mysqli_user_postfix.phpt │ ├── mysqli_user_prefix.phpt │ └── skipifmysqli.inc ├── treat_data.c └── ufilter.c ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .DS_Store /config.log /config.guess /config.h /config.h.in /config.h.in~ /config.nice /config.status /config.sub /*.lo /.deps /.libs/ /Makefile /Makefile.* /ac*.m4 /autom4te.cache/ /build/ /configure /configure.in /install-sh /libtool /ltmain.sh /missing /mkinstalldirs /modules/ /run-tests.php /suhosin.la /tests/*/*.tmp ================================================ FILE: .travis.yml ================================================ language: php os: linux php: - 5.6 - 5.5 - 5.4 env: - CC=gcc CFLAGS="" - CC=clang CFLAGS="" before_install: - lsb_release -a - uname -a before_script: - phpize - ./configure --enable-suhosin-experimental - make -j2 CFLAGS="-DSUHOSIN_DEBUG=1" - phpenv config-rm xdebug.ini script: - make test NO_INTERACTION=1 ================================================ FILE: CREDITS ================================================ suhosin Stefan Esser ================================================ FILE: Changelog ================================================ 2016-xx-xx - 0.9.39dev2 - some improvements for Windows (NewEraCracker) - fixes for test cases (NewEraCracker) - new feature: suhosin.log.max_error_length to limit the error output - fixed function_exists wrapper to ignore backslash-prefixes (#92) - backport of PHP bug 71152: mt_rand() returns the different values from original mt19937ar.c - removed dead code - better debian integration - fixed perdir checks - merged PHP changes to RFC1867 code 2015-05-21 - 0.9.38 - removed code compatibility for PHP <5.4 (lots of code + ifdefs) - allow https location for suhosin.filter.action - fixed newline detection for suhosin.mail.protect - Added suhosin.upload.max_newlines to protect againt DOS attack via many MIME headers in RFC1867 uploads (CVE-2015-4024) - mail related test cases now work on linux 2014-12-12 - 0.9.37.1 - Changed version string to 0.9.37.1 (without -dev) - Relaxed array index blacklist (removed '-') due to wordpress incompatibility 2014-12-03 - 0.9.37 - Added SQL injection protection for Mysqli and several test cases - Added wildcard matching for SQL username - Added check for SQL username to only contain valid characters (>= ASCII 32) - Test cases for user_prefix and user_postfix - Added experimental PDO support - SQL checks other than mysql (Mysqli + old-style) must be enabled with configure --enable-suhosin-experimental, e.g. MSSQL. - disallow_ws now matches all single-byte whitespace characters - remove_binary and disallow_binary now optionally allow UTF-8. - Introduced suhosin.upload.allow_utf8 (experimental) - Reimplemented suhosin_get_raw_cookies() - Fixed potential segfault for disable_display_errors=fail (only on ARM) - Fixed potential NULL-pointer dereference with func.blacklist and logging - Logging timestamps are localtime instead of gmt now (thanks to mkrokos) - Added new array index filter (character whitelist/blacklist) - Set default array index blacklist to '"+-<>;() - Added option to suppress date/time for suhosin file logging (suhosin.log.file.time=0) - Added simple script to create binary Debian package - Fixed additional recursion problems with session handler - Suhosin now depends on php_session.h instead of version-specific struct code 2014-06-10 - 0.9.36 - Added better handling of non existing/non executable shell scripts - Added protection against XSS/SQL/Other Injections through User-Agent HTTP header - Fix variable logging statistics outputting on every include - ticket: #37 - Added more entropy from /dev/urandom to internal random seeding (64 bit => 256 bit) - Added non initialized stack variables to random seeding - Added php_win32_get_random_bytes for windows compatibility in random seeding - Added suhosin.rand.seedingkey for INI supplied additional entropy string (idea DavisNT) - Added suhosin.rand.reseed_every_request to allow reseeding on every request (idea DavisNT) - Changed that calls to srand() / mt_srand() will trigger auto reseeding (idea DavisNT) - Fixed problems with SessionHandler() class and endless recursions - Added LICENSE file to make distributions happy 2014-02-24 - 0.9.35 - From now only PHP >= 5.4 is officially supported - Fix problems with the hard memory_limit on 64 bit systems - Fix problems with user space session handler due to change in PHP 5.4.0 - Add changes in PHP 5.5 session handlers structures for PHP 5.5 compability - Fix std post handler for PHP >= 5.3.11 - Fix suhosin logo in phpinfo() for PHP 5.5 - Change fileupload handling for PHP >= 5.4.0 to use an up to date RFC1867 replacement code - Adapted suhosin to PHP 5.5 executor - Added some test cases for various things - Added suhosin.log.stdout to log to stdout (for debugging purposes only) - Add ini_set() fail mode to suhosin.disable.display_errors - Fix suhosin.get/post/cookie.max_totalname_length filter - Refactor array index handling in filter to make it work always - Added support for PHP 5.6.0alpha2 - WARNING: FUNCTION WHITELISTS/BLACKLISTS NEVER WORKED CORRECTLY WITH PHP < 5.5 2012-02-12 - 0.9.34 - Added initial support for PHP 5.4.0 - Fix include whitelist and blacklist to support shemes with dots in their names - Fix read after efree() that lets function_exists() malfunction - Fix build with clang compiler - Added a request variable drop statistic log message 2012-01-19 - 0.9.33 - Make clear that suhosin is incompatible to mbstring.encoding_translation=On - Stop mbstring extension from replacing POST handlers - Added detection of extensions manipulating POST handlers - Fixed environment variables for logging do not go through the filter extension anymore - Fixed stack based buffer overflow in transparent cookie encryption (see separate advisory) - Fixed that disabling HTTP response splitting protection also disabled NUL byte protection in HTTP headers - Removed crypt() support - because not used for PHP >= 5.3.0 anyway 2010-07-23 - 0.9.32.1 - Fixed missing header file resulting in compile errors 2010-07-23 - 0.9.32 - Added support for memory_limit > 2GB - Fixed missing header file resulting in wrong php_combined_lcg() prototype being used - Improved random number seed generation more by adding /dev/urandom juice 2010-03-28 - 0.9.31 - Fix ZTS build of session.c - Increased session identifier entropy by using /dev/urandom if available 2010-03-25 - 0.9.30 - Added line ending characters %0a and %0d to the list of dangerous characters handled by suhosin.server.encode and suhosin.server.strip - Fixed crash bug with PHP 5.3.x and session module (due to changed session globals struct) - Added ! protection to PHP session serializer - Fixed simulation mode now also affects (dis)allowed functions - Fixed missing return (1); in random number generator replacements - Fixed random number generator replacement error case behaviour in PHP 5.3.x - Fixed error case handling in function_exists() PHP 5.3.x - Merged changes/fixes in import_request_variables()/extract() from upstream PHP - Fixed suhosin_header_handler to be PHP 5.3.x compatible - Merge fixes and new features of PHP's file upload code to suhosin 2009-08-15 - 0.9.29 - Fixing crash bugs with PHP 5.3.0 caused by unexpected NULL in EG(active_symbol_table) - Added more compatible way to retrieve ext/session globals - Increased default length and count limit for POST variables (for people not reading docu) 2009-08-14 - 0.9.28 - Fixed crash bug with PHP 5.2.10 caused by a change in extension load order of ext/session - Fixed harmless parameter order error in a bogus memset() - Disable suhosin.session.cryptua by default because of Internet Explorer 8 "features" - Added suhosin.executor.include.allow_writable_files which can be disabled to disallow inclusion of files writable by the webserver 2008-08-23 - 0.9.27 - Fixed typo in replacement rand() / mt_rand() that was hidden by LAZY symbol loading 2008-08-22 - 0.9.26 - Fixed problem with suhosin.perdir Thanks to Hosteurope for tracking this down - Fixed problems with ext/uploadprogress Reported by: Christian Stocker - Added suhosin.srand.ignore and suhosin.mt_srand.ignore (default: on) - Modified rand()/srand() to use the Mersenne Twister algorithm with separate state - Added better internal seeding of rand() and mt_rand() 2008-08-06 - 0.9.25 - Fixed PHP 4 compilation problem introduced in 0.9.24 - Fixed PHP 5.3 compilation problem - Changed PHP default POST handler to PHP's current handler 2008-05-10 - 0.9.24 - Added support for method-calls to function handling - This fixes white- and blacklist affecting methods with the same name 2008-01-14 - 0.9.23 - Fixed suhosin extension now compiles with snapshots of PHP 5.3 - Fixed crypt() behaves like normal again when there is no salt supplied 2007-12-01 - 0.9.22 - Removed LFS warning message because it crashed on several systems 2007-11-30 - 0.9.21 - Fixed function_exists() now checks the Suhosin permissions - Fixed crypt() salt no longer uses Blowfish by default - Fixed .htaccess/perdir support - Fixed compilation problem on OS/X - Added protection against some attacks through _SERVER variables - Added suhosin.server.strip and suhosin.server.encode - Added error message that warns about the LFS binary incompatibility 2007-05-19 - 0.9.20 - Added protection flags against whitespace at variable start - Added mutex around crypt() to close the PHP crypt() thread safety vulnerability class - Improved HTTP Response Splitting Protection - Changed default maximum array depth to 50 for GPCR - Fixed possible endless loop in file logging - Fixed file locking in file logging 2007-05-01 - 0.9.19 - Fixed typo in HTTP header protection (only during simulation mode) Reported by: Ilia Alshanetsky - Fixed wrong \0 termination in cookie decryptor - Fixed possible crash in SERVER variables protection when SAPI=embedded Fix provided by: Olivier Blin/Mandriva Linux - Added possibility to en-/disable INI_PERDIR Problem reported by: Ilia Alshanetsky - Added PHP Warning when disabled function is called - Added examples for new configuration option in suhosin.ini 2007-03-06 - 0.9.18 - Fixed session double hooking in edge case - Added additional crash protection for PHP's session module 2007-03-04 - 0.9.17 - Added a suhosin.ini example configuration Thanks to Mandriva Linux for supplying us with one - Added new logging device: file - Fixed that suhosin.filter.action did not affect POST limits - Fixed behaviour of request variable limit to be an upper limit for the other settings instead of being additive limit - Fixed hard_memory_limit bypass due to casting bug in PHP Problem was found by: Ilia Alshanetsky - Fixed some sql prefix/postfix problems - Added experimental SQL injection heuristic 2006-12-02 - 0.9.16 - Added suhosin.stealth which controls if suhosin loads in stealth mode when it is not the only zend_extension (Required for full compatibility with certain encoders that consider open source untrusted. e.g. ionCube, Zend) - Activate suhosin.stealth by default - Fixed that Suhosin tries handling functions disabled by disable_function. In v0.9.15 it was impossible to disable phpinfo() with disable_function. Problem was found by: Thorsten Schifferdecker 2006-11-28 - 0.9.15 - Added a transparent protection for open phpinfo() pages by adding an HTML META ROBOTS tag to the output that forbids indexing and archiving 2006-11-22 - 0.9.14 - Drop wrongly decrypted cookies instead of leaving them empty - Fix another problem with urlencoded cookie names - Fix compilation problem with PHP4 - Added better regression to the release process to stop compilation and missing symbol problems 2006-11-20 - 0.9.13 - More compatible support for ap_php_snprintf() for old PHP - Changed phpinfo() output to put suhosin logo into a data: URL for Opera and Gecko based browsers when expose_php=off 2006-11-14 - 0.9.12 - Adding ap_php_snprintf() when compiling against PHP 4.3.9 - Added suhosin.protectkey to remove cryptkeys from phpinfo() output - Disabled suhosin.cookie.encrypt in default install - Fixed static compilation against PHP 5.2.0 2006-11-06 - 0.9.11 - Fixed input filter for simulation mode 2006-10-26 - 0.9.10 - Fixed ZTS compile problem in new code - Fixed PHP4 compile problem in new code 2006-10-25 - 0.9.9 - Fixed mail() protection that failed to detect some injected headers - Fixed cookie decryption to not potentially trash apache memory - Fixed cookie enctyption to handle url encoded names correctly - Added suhosin.cookie/session.checkraddr - Added suhosin.cookie.cryptlist - Added suhosin.cookie.plainlist - Added suhosin_encrypt_cookie function for JS - Added suhosin_get_raw_cookies function - Changed dropped variable error messages 2006-10-08 - 0.9.8 - Fixed a PHP4 ZTS compile problem 2006-10-08 - 0.9.7 - Moved input handler hooking to a later place to ensure better compatibility with 3rd party extensions - Fixed a problem with overlong mail headers in mail protection - Fixed a problem with empty log/verification script names - Fixed a PHP4 compile problem with old gcc/in ZTS mode - Added mbregex.h from PHP4 to solve compile problems on systesm with broken header installations 2006-10-02 - 0.9.6 - Disallow symlink() when open_basedir (activated by default) - Fix a problem with compilation in Visual Studio 2006-09-29 - 0.9.5 - Added missing logo file - Added suhosin.apc_bug_workaround flag to enable compatibility with buggy APC 3.0.12x 2006-09-29 - 0.9.4 - Added version number and logo to phpinfo() output - Fixed that all uploaded files are dropped after a single one was disallowed - Added undocumented suhosin.coredump flag to tell suhosin to dump core instead of logging S_MEMORY events - Disable handling of rfc1867 mbstring decoding 2006-09-24 - 0.9.3 - Added protection against endless recursion for suhosin.log.phpscript - Added possibility to disable open_basedir and safe_mode for suhosin.log.phpscript - Added suhosin.executor.include.max_traversal to stop directory traversal includes 2006-09-19 - 0.9.2 - Fixes broken rfc1867 fileupload hook - Changed definition of binary to: 0..31, 128..255 except whitespace - Added suhosin.log.phpscript(.name) directive to log to a PHP script 2006-09-16 - 0.9.1 - A bunch of changes to compile and work on Windows 2006-09-09 - BETA - Added decryption of HTTP_COOKIE - Fixed a last problem in suhosin_strcasestr() helper function 2006-09-08 - BETA - Fixed a problem within suhosin_strcasestr() because it broke URL checks 2006-09-07 - BETA - CVS version of PHP 5.2.0 was changed to support incasesensitive URLs, support for this in suhosin added - Fixed a problem when preg_replace() was called with more than 4 parameters ================================================ FILE: LICENSE ================================================ -------------------------------------------------------------------- The PHP License, version 3.01 Copyright (c) 1999 - 2014 The PHP Group. All rights reserved. -------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, is permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name "PHP" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact group@php.net. 4. Products derived from this software may not be called "PHP", nor may "PHP" appear in their name, without prior written permission from group@php.net. You may indicate that your software works in conjunction with PHP by saying "Foo for PHP" instead of calling it "PHP Foo" or "phpfoo" 5. The PHP Group may publish revised and/or new versions of the license from time to time. Each version will be given a distinguishing version number. Once covered code has been published under a particular version of the license, you may always continue to use it under the terms of that version. You may also choose to use such covered code under the terms of any subsequent version of the license published by the PHP Group. No one other than the PHP Group has the right to modify the terms applicable to covered code created under this License. 6. Redistributions of any form whatsoever must retain the following acknowledgment: "This product includes PHP software, freely available from ". THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------- This software consists of voluntary contributions made by many individuals on behalf of the PHP Group. The PHP Group can be contacted via Email at group@php.net. For more information on the PHP Group and the PHP project, please see . PHP includes the Zend Engine, freely available at . ================================================ FILE: README.md ================================================ [![Build Status](https://travis-ci.org/sektioneins/suhosin.svg?branch=master)](https://travis-ci.org/sektioneins/suhosin) [![Join the chat at https://gitter.im/sektioneins/suhosin](https://badges.gitter.im/sektioneins/suhosin.svg)](https://gitter.im/sektioneins/suhosin?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) # Suhosin Suhosin (pronounced 'su-ho-shin') is an advanced protection system for PHP installations. It was designed to protect servers and users from known and unknown flaws in PHP applications and the PHP core. ================================================ FILE: aes.c ================================================ /* Rijndael Block Cipher - rijndael.c Written by Mike Scott 21st April 1999 mike@compapp.dcu.ie An alternative faster version is implemented in MIRACL ftp://ftp.computing.dcu.ie/pub/crypto/miracl.zip Copyright (c) 1999 Mike Scott Simply compile and run, e.g. cl /O2 rijndael.c (Microsoft C) bcc32 /O2 rijndael.c (Borland C) gcc -O2 rijndael.c -o rijndael (Gnu C) Compiles and runs fine as a C++ program also. See rijndael documentation. The code follows the documentation as closely as possible, and where possible uses the same function and variable names. Permission for free direct or derivative use is granted subject to compliance with any conditions that the originators of the algorithm place on its exploitation. Inspiration from Brian Gladman's implementation is acknowledged. Written for clarity, rather than speed. Assumes long is 32 bit quantity. Full implementation. Endian indifferent. */ #include "php.h" #include "php_suhosin.h" /* rotates x one bit to the left */ #define ROTL(x) (((x)>>7)|((x)<<1)) /* Rotates 32-bit word left by 1, 2 or 3 byte */ #define ROTL8(x) (((x)<<8)|((x)>>24)) #define ROTL16(x) (((x)<<16)|((x)>>16)) #define ROTL24(x) (((x)<<24)|((x)>>8)) /* Fixed Data */ static BYTE InCo[4]={0xB,0xD,0x9,0xE}; /* Inverse Coefficients */ static BYTE fbsub[256]; static BYTE rbsub[256]; static BYTE ptab[256],ltab[256]; static WORD ftable[256]; static WORD rtable[256]; static WORD rco[30]; /* Parameter-dependent data */ static int Nk,Nb,Nr; static WORD pack(BYTE *b) { /* pack bytes into a 32-bit Word */ return ((WORD)b[3]<<24)|((WORD)b[2]<<16)|((WORD)b[1]<<8)|(WORD)b[0]; } static void unpack(WORD a,BYTE *b) { /* unpack bytes from a word */ b[0]=(BYTE)a; b[1]=(BYTE)(a>>8); b[2]=(BYTE)(a>>16); b[3]=(BYTE)(a>>24); } static BYTE xtime(BYTE a) { BYTE b; if (a&0x80) b=0x1B; else b=0; a<<=1; a^=b; return a; } static BYTE bmul(BYTE x,BYTE y) { /* x.y= AntiLog(Log(x) + Log(y)) */ if (x && y) return ptab[(ltab[x]+ltab[y])%255]; else return 0; } static WORD SubByte(WORD a) { BYTE b[4]; unpack(a,b); b[0]=fbsub[b[0]]; b[1]=fbsub[b[1]]; b[2]=fbsub[b[2]]; b[3]=fbsub[b[3]]; return pack(b); } static BYTE product(WORD x,WORD y) { /* dot product of two 4-byte arrays */ BYTE xb[4],yb[4]; unpack(x,xb); unpack(y,yb); return bmul(xb[0],yb[0])^bmul(xb[1],yb[1])^bmul(xb[2],yb[2])^bmul(xb[3],yb[3]); } static WORD InvMixCol(WORD x) { /* matrix Multiplication */ WORD y,m; BYTE b[4]; m=pack(InCo); b[3]=product(m,x); m=ROTL24(m); b[2]=product(m,x); m=ROTL24(m); b[1]=product(m,x); m=ROTL24(m); b[0]=product(m,x); y=pack(b); return y; } static BYTE ByteSub(BYTE x) { BYTE y=ptab[255-ltab[x]]; /* multiplicative inverse */ x=y; x=ROTL(x); y^=x; x=ROTL(x); y^=x; x=ROTL(x); y^=x; x=ROTL(x); y^=x; y^=0x63; return y; } void suhosin_aes_gentables() { /* generate tables */ int i; BYTE y,b[4]; /* use 3 as primitive root to generate power and log tables */ ltab[0]=0; ptab[0]=1; ltab[1]=0; ptab[1]=3; ltab[3]=1; for (i=2;i<256;i++) { ptab[i]=ptab[i-1]^xtime(ptab[i-1]); ltab[ptab[i]]=i; } /* affine transformation:- each bit is xored with itself shifted one bit */ fbsub[0]=0x63; rbsub[0x63]=0; for (i=1;i<256;i++) { y=ByteSub((BYTE)i); fbsub[i]=y; rbsub[y]=i; } for (i=0,y=1;i<30;i++) { rco[i]=y; y=xtime(y); } /* calculate forward and reverse tables */ for (i=0;i<256;i++) { y=fbsub[i]; b[3]=y^xtime(y); b[2]=y; b[1]=y; b[0]=xtime(y); ftable[i]=pack(b); y=rbsub[i]; b[3]=bmul(InCo[0],y); b[2]=bmul(InCo[1],y); b[1]=bmul(InCo[2],y); b[0]=bmul(InCo[3],y); rtable[i]=pack(b); } } void suhosin_aes_gkey(int nb,int nk,char *key TSRMLS_DC) { /* blocksize=32*nb bits. Key=32*nk bits */ /* currently nb,bk = 4, 6 or 8 */ /* key comes as 4*Nk bytes */ /* Key Scheduler. Create expanded encryption key */ int i,j,k,m,N; int C1,C2,C3; WORD CipherKey[8]; Nb=nb; Nk=nk; /* Nr is number of rounds */ if (Nb>=Nk) Nr=6+Nb; else Nr=6+Nk; C1=1; if (Nb<8) { C2=2; C3=3; } else { C2=3; C3=4; } /* pre-calculate forward and reverse increments */ for (m=j=0;j>8)])^ ROTL16(ftable[(BYTE)(x[SUHOSIN_G(fi)[m+1]]>>16)])^ ROTL24(ftable[x[SUHOSIN_G(fi)[m+2]]>>24]); } t=x; x=y; y=t; /* swap pointers */ } /* Last Round - unroll if possible */ for (m=j=0;j>8)])^ ROTL16((WORD)fbsub[(BYTE)(x[SUHOSIN_G(fi)[m+1]]>>16)])^ ROTL24((WORD)fbsub[x[SUHOSIN_G(fi)[m+2]]>>24]); } for (i=j=0;i>8)])^ ROTL16(rtable[(BYTE)(x[SUHOSIN_G(ri)[m+1]]>>16)])^ ROTL24(rtable[x[SUHOSIN_G(ri)[m+2]]>>24]); } t=x; x=y; y=t; /* swap pointers */ } /* Last Round - unroll if possible */ for (m=j=0;j>8)])^ ROTL16((WORD)rbsub[(BYTE)(x[SUHOSIN_G(ri)[m+1]]>>16)])^ ROTL24((WORD)rbsub[x[SUHOSIN_G(ri)[m+2]]>>24]); } for (i=j=0;i | | Ben Fuhrmannek | +----------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "TSRM.h" #include "php_suhosin.h" #include "ext/standard/base64.h" #include "sha256.h" static void suhosin_get_ipv4(char *buf TSRMLS_DC) { char *raddr = suhosin_getenv(ZEND_STRL("REMOTE_ADDR") TSRMLS_CC); int i; if (raddr == NULL) { memset(buf, 0, 4); return; } for (i=0; i<4; i++) { if (raddr[0] == 0) { buf[i] = 0; } else { buf[i] = strtol(raddr, &raddr, 10); if (raddr[0] == '.') { raddr++; } } } } char *suhosin_encrypt_string(char *str, int len, char *var, int vlen, char *key TSRMLS_DC) { int padded_len, i, slen; unsigned char *crypted, *tmp; unsigned int check = 0x13579BDF; if (str == NULL) { return NULL; } if (len == 0) { return estrndup("", 0); } suhosin_aes_gkey(4,8,key TSRMLS_CC); padded_len = ((len+15) & ~0xF); crypted = emalloc(16+padded_len+1); memset(crypted, 0xff, 16+padded_len+1); memcpy(crypted+16, str, len+1); /* calculate check value */ for (i = 0; i> (32-3)); check += check << 1; check ^= (unsigned char)var[i]; } for (i = 0; i> (32-3)); check += check << 1; check ^= (unsigned char)str[i]; } /* store ip value */ suhosin_get_ipv4((char *)crypted+4 TSRMLS_CC); /* store check value */ crypted[8] = check & 0xff; crypted[9] = (check >> 8) & 0xff; crypted[10] = (check >> 16) & 0xff; crypted[11] = (check >> 24) & 0xff; /* store original length */ crypted[12] = len & 0xff; crypted[13] = (len >> 8) & 0xff; crypted[14] = (len >> 16) & 0xff; crypted[15] = (len >> 24) & 0xff; for (i=0, tmp=crypted; i 0) { int j; for (j=0; j<16; j++) tmp[j] ^= tmp[j-16]; } suhosin_aes_encrypt((char *)tmp TSRMLS_CC); } tmp = php_base64_encode(crypted, padded_len+16, NULL); efree(crypted); slen=strlen((char *)tmp); for (i=0; i=0; i-=16, tmp-=16) { suhosin_aes_decrypt((char *)tmp TSRMLS_CC); if (i > 0) { int j; for (j=0; j<16; j++) tmp[j] ^= tmp[j-16]; } } /* retrieve orig_len */ o_len = decrypted[15]; o_len <<= 8; o_len |= decrypted[14]; o_len <<= 8; o_len |= decrypted[13]; o_len <<= 8; o_len |= decrypted[12]; if (o_len < 0 || o_len > len-16) { goto error_out; } /* calculate check value */ for (i = 0; i> (32-3)); check += check << 1; check ^= (unsigned char)var[i]; } for (i = 0; i> (32-3)); check += check << 1; check ^= decrypted[16+i]; } /* check value */ invalid = (decrypted[8] != (check & 0xff)) || (decrypted[9] != ((check >> 8) & 0xff)) || (decrypted[10] != ((check >> 16) & 0xff)) || (decrypted[11] != ((check >> 24) & 0xff)); /* check IP */ if (check_ra > 0) { if (check_ra > 4) { check_ra = 4; } suhosin_get_ipv4(&buf[0] TSRMLS_CC); if (memcmp(buf, decrypted+4, check_ra) != 0) { goto error_out; } } if (invalid) { goto error_out; } if (orig_len) { *orig_len = o_len; } memmove(decrypted, decrypted+16, o_len); decrypted[o_len] = 0; /* we do not realloc() here because 16 byte less is simply not worth the overhead */ return (char *)decrypted; } char *suhosin_generate_key(char *key, zend_bool ua, zend_bool dr, long raddr, char *cryptkey TSRMLS_DC) { char *_ua = NULL; char *_dr = NULL; char *_ra = NULL; suhosin_SHA256_CTX ctx; if (ua) { _ua = suhosin_getenv(ZEND_STRL("HTTP_USER_AGENT") TSRMLS_CC); } if (dr) { _dr = suhosin_getenv(ZEND_STRL("DOCUMENT_ROOT") TSRMLS_CC); } if (raddr > 0) { _ra = suhosin_getenv(ZEND_STRL("REMOTE_ADDR") TSRMLS_CC); } SDEBUG("(suhosin_generate_key) KEY: %s - UA: %s - DR: %s - RA: %s", key,_ua,_dr,_ra); suhosin_SHA256Init(&ctx); if (key == NULL || *key == 0) { suhosin_SHA256Update(&ctx, (unsigned char*)"D3F4UL7", strlen("D3F4UL7")); } else { suhosin_SHA256Update(&ctx, (unsigned char*)key, strlen(key)); } if (_ua) { suhosin_SHA256Update(&ctx, (unsigned char*)_ua, strlen(_ua)); } if (_dr) { suhosin_SHA256Update(&ctx, (unsigned char*)_dr, strlen(_dr)); } if (_ra) { if (raddr >= 4) { suhosin_SHA256Update(&ctx, (unsigned char*)_ra, strlen(_ra)); } else { long dots = 0; char *tmp = _ra; while (*tmp) { if (*tmp == '.') { dots++; if (dots == raddr) { break; } } tmp++; } suhosin_SHA256Update(&ctx, (unsigned char*)_ra, tmp-_ra); } } suhosin_SHA256Final((unsigned char *)cryptkey, &ctx); cryptkey[32] = 0; /* uhmm... not really a string */ return cryptkey; } ================================================ FILE: ex_imp.c ================================================ /* +----------------------------------------------------------------------+ | Suhosin Version 1 | +----------------------------------------------------------------------+ | Copyright (c) 2006-2007 The Hardened-PHP Project | | Copyright (c) 2007-2015 SektionEins GmbH | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Stefan Esser | +----------------------------------------------------------------------+ */ /* $Id: ex_imp.c,v 1.2 2008-01-04 11:23:47 sesser Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_ini.h" #include "php_suhosin.h" #include "ext/standard/php_smart_str.h" #include "ext/standard/php_var.h" #define EXTR_OVERWRITE 0 #define EXTR_SKIP 1 #define EXTR_PREFIX_SAME 2 #define EXTR_PREFIX_ALL 3 #define EXTR_PREFIX_INVALID 4 #define EXTR_PREFIX_IF_EXISTS 5 #define EXTR_IF_EXISTS 6 #define EXTR_REFS 0x100 static int php_valid_var_name(char *var_name, int len) /* {{{ */ { int i, ch; if (!var_name) return 0; /* These are allowed as first char: [a-zA-Z_\x7f-\xff] */ ch = (int)((unsigned char *)var_name)[0]; if (var_name[0] != '_' && (ch < 65 /* A */ || /* Z */ ch > 90) && (ch < 97 /* a */ || /* z */ ch > 122) && (ch < 127 /* 0x7f */ || /* 0xff */ ch > 255) ) { return 0; } /* And these as the rest: [a-zA-Z0-9_\x7f-\xff] */ if (len > 1) { for (i = 1; i < len; i++) { ch = (int)((unsigned char *)var_name)[i]; if (var_name[i] != '_' && (ch < 48 /* 0 */ || /* 9 */ ch > 57) && (ch < 65 /* A */ || /* Z */ ch > 90) && (ch < 97 /* a */ || /* z */ ch > 122) && (ch < 127 /* 0x7f */ || /* 0xff */ ch > 255) ) { return 0; } } } if (suhosin_is_protected_varname(var_name, len)) { return 0; } return 1; } /* {{{ proto int extract(array var_array [, int extract_type [, string prefix]]) Imports variables into symbol table from an array */ PHP_FUNCTION(suhosin_extract) { zval *var_array, *prefix = NULL; long extract_type = EXTR_OVERWRITE; zval **entry, *data; char *var_name; ulong num_key; uint var_name_len; int var_exists, key_type, count = 0; int extract_refs = 0; HashPosition pos; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|lz/", &var_array, &extract_type, &prefix) == FAILURE) { return; } extract_refs = (extract_type & EXTR_REFS); extract_type &= 0xff; if (extract_type < EXTR_OVERWRITE || extract_type > EXTR_IF_EXISTS) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid extract type"); return; } if (extract_type > EXTR_SKIP && extract_type <= EXTR_PREFIX_IF_EXISTS && ZEND_NUM_ARGS() < 3) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "specified extract type requires the prefix parameter"); return; } if (prefix) { convert_to_string(prefix); if (Z_STRLEN_P(prefix) && !php_valid_var_name(Z_STRVAL_P(prefix), Z_STRLEN_P(prefix))) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "prefix is not a valid identifier"); return; } } if (!EG(active_symbol_table)) { zend_rebuild_symbol_table(TSRMLS_C); } /* var_array is passed by ref for the needs of EXTR_REFS (needs to * work on the original array to create refs to its members) * simulate pass_by_value if EXTR_REFS is not used */ if (!extract_refs) { SEPARATE_ARG_IF_REF(var_array); } zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(var_array), &pos); while (zend_hash_get_current_data_ex(Z_ARRVAL_P(var_array), (void **)&entry, &pos) == SUCCESS) { zval final_name; ZVAL_NULL(&final_name); key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(var_array), &var_name, &var_name_len, &num_key, 0, &pos); var_exists = 0; if (key_type == HASH_KEY_IS_STRING) { var_name_len--; var_exists = zend_hash_exists(EG(active_symbol_table), var_name, var_name_len + 1); } else if (key_type == HASH_KEY_IS_LONG && (extract_type == EXTR_PREFIX_ALL || extract_type == EXTR_PREFIX_INVALID)) { zval num; ZVAL_LONG(&num, num_key); convert_to_string(&num); php_prefix_varname(&final_name, prefix, Z_STRVAL(num), Z_STRLEN(num), 1 TSRMLS_CC); zval_dtor(&num); } else { zend_hash_move_forward_ex(Z_ARRVAL_P(var_array), &pos); continue; } switch (extract_type) { case EXTR_IF_EXISTS: if (!var_exists) break; /* break omitted intentionally */ case EXTR_OVERWRITE: /* GLOBALS protection */ if (var_exists && var_name_len == sizeof("GLOBALS") && !strcmp(var_name, "GLOBALS")) { break; } if (var_exists && var_name_len == sizeof("this") && !strcmp(var_name, "this") && EG(scope) && EG(scope)->name_length != 0) { break; } ZVAL_STRINGL(&final_name, var_name, var_name_len, 1); break; case EXTR_PREFIX_IF_EXISTS: if (var_exists) { php_prefix_varname(&final_name, prefix, var_name, var_name_len, 1 TSRMLS_CC); } break; case EXTR_PREFIX_SAME: if (!var_exists && var_name_len != 0) { ZVAL_STRINGL(&final_name, var_name, var_name_len, 1); } /* break omitted intentionally */ case EXTR_PREFIX_ALL: if (Z_TYPE(final_name) == IS_NULL && var_name_len != 0) { php_prefix_varname(&final_name, prefix, var_name, var_name_len, 1 TSRMLS_CC); } break; case EXTR_PREFIX_INVALID: if (Z_TYPE(final_name) == IS_NULL) { if (!php_valid_var_name(var_name, var_name_len)) { php_prefix_varname(&final_name, prefix, var_name, var_name_len, 1 TSRMLS_CC); } else { ZVAL_STRINGL(&final_name, var_name, var_name_len, 1); } } break; default: if (!var_exists) { ZVAL_STRINGL(&final_name, var_name, var_name_len, 1); } break; } if (Z_TYPE(final_name) != IS_NULL && php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) { if (extract_refs) { zval **orig_var; SEPARATE_ZVAL_TO_MAKE_IS_REF(entry); zval_add_ref(entry); if (zend_hash_find(EG(active_symbol_table), Z_STRVAL(final_name), Z_STRLEN(final_name) + 1, (void **) &orig_var) == SUCCESS) { zval_ptr_dtor(orig_var); *orig_var = *entry; } else { zend_hash_update(EG(active_symbol_table), Z_STRVAL(final_name), Z_STRLEN(final_name) + 1, (void **) entry, sizeof(zval *), NULL); } } else { MAKE_STD_ZVAL(data); *data = **entry; zval_copy_ctor(data); ZEND_SET_SYMBOL_WITH_LENGTH(EG(active_symbol_table), Z_STRVAL(final_name), Z_STRLEN(final_name) + 1, data, 1, 0); } count++; } zval_dtor(&final_name); zend_hash_move_forward_ex(Z_ARRVAL_P(var_array), &pos); } if (!extract_refs) { zval_ptr_dtor(&var_array); } RETURN_LONG(count); } /* }}} */ ZEND_BEGIN_ARG_INFO_EX(suhosin_arginfo_extract, 0, 0, 1) ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, arg) /* ARRAY_INFO(0, arg, 0) */ ZEND_ARG_INFO(0, extract_type) ZEND_ARG_INFO(0, prefix) ZEND_END_ARG_INFO() /* {{{ suhosin_ex_imp_functions[] */ zend_function_entry suhosin_ex_imp_functions[] = { PHP_NAMED_FE(extract, PHP_FN(suhosin_extract), suhosin_arginfo_extract) {NULL, NULL, NULL} }; /* }}} */ void suhosin_hook_ex_imp(TSRMLS_D) { /* replace the extract and import_request_variables functions */ zend_hash_del(CG(function_table), "extract", sizeof("extract")); zend_register_functions(NULL, suhosin_ex_imp_functions, NULL, MODULE_PERSISTENT TSRMLS_CC); } /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ ================================================ FILE: execute.c ================================================ /* +----------------------------------------------------------------------+ | Suhosin Version 1 | +----------------------------------------------------------------------+ | Copyright (c) 2006-2007 The Hardened-PHP Project | | Copyright (c) 2007-2015 SektionEins GmbH | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Stefan Esser | +----------------------------------------------------------------------+ */ /* $Id: execute.c,v 1.1.1.1 2007-11-28 01:15:35 sesser Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "php.h" #include "php_ini.h" #include "zend_hash.h" #include "zend_extensions.h" #include "ext/standard/info.h" #include "ext/standard/php_rand.h" #include "ext/standard/php_lcg.h" #include "php_suhosin.h" #include "zend_compile.h" #include "zend_llist.h" #include "SAPI.h" #include "sha256.h" #ifdef PHP_WIN32 # include "win32/fnmatch.h" # include "win32/winutil.h" # include "win32/time.h" #else # ifdef HAVE_FNMATCH # include # endif # include #endif #if PHP_VERSION_ID >= 50500 static void (*old_execute_ex)(zend_execute_data *execute_data TSRMLS_DC); static void suhosin_execute_ex(zend_execute_data *execute_data TSRMLS_DC); #endif static void (*old_execute)(zend_op_array *op_array TSRMLS_DC); static void suhosin_execute(zend_op_array *op_array TSRMLS_DC); static void (*old_execute_ZO)(zend_op_array *op_array, long dummy TSRMLS_DC); static void suhosin_execute_ZO(zend_op_array *op_array, long dummy TSRMLS_DC); static void *(*zo_set_oe_ex)(void *ptr) = NULL; /*STATIC zend_op_array* (*old_compile_file)(zend_file_handle* file_handle, int type TSRMLS_DC); STATIC zend_op_array* suhosin_compile_file(zend_file_handle*, int TSRMLS_DC);*/ #if PHP_VERSION_ID >= 50500 static void suhosin_execute_internal(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC); static void (*old_execute_internal)(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC); #else static void suhosin_execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC); static void (*old_execute_internal)(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC); #endif extern zend_extension suhosin_zend_extension_entry; /* {{{ suhosin_strcasestr */ static char *suhosin_strcasestr(char *haystack, char *needle) { unsigned char *t, *h, *n; h = (unsigned char *) haystack; conts: while (*h) { n = (unsigned char *) needle; if (toupper(*h++) == toupper(*n++)) { for (t=h; *n; t++, n++) { if (toupper(*t) != toupper(*n)) goto conts; } return ((char*)h-1); } } return (NULL); } /* }}} */ #define SUHOSIN_CODE_TYPE_UNKNOWN 0 #define SUHOSIN_CODE_TYPE_COMMANDLINE 1 #define SUHOSIN_CODE_TYPE_EVAL 2 #define SUHOSIN_CODE_TYPE_REGEXP 3 #define SUHOSIN_CODE_TYPE_ASSERT 4 #define SUHOSIN_CODE_TYPE_CFUNC 5 #define SUHOSIN_CODE_TYPE_SUHOSIN 6 #define SUHOSIN_CODE_TYPE_UPLOADED 7 #define SUHOSIN_CODE_TYPE_0FILE 8 #define SUHOSIN_CODE_TYPE_BLACKURL 9 #define SUHOSIN_CODE_TYPE_BADURL 10 #define SUHOSIN_CODE_TYPE_GOODFILE 11 #define SUHOSIN_CODE_TYPE_BADFILE 12 #define SUHOSIN_CODE_TYPE_LONGNAME 13 #define SUHOSIN_CODE_TYPE_MANYDOTS 14 #define SUHOSIN_CODE_TYPE_WRITABLE 15 #define SUHOSIN_CODE_TYPE_MBREGEXP 16 static int suhosin_check_filename(char *s, int len TSRMLS_DC) { char fname[MAXPATHLEN+1]; char *t, *h, *h2, *index, *e; int tlen, i, count=0; uint indexlen; ulong numindex; zend_bool isOk; /* check if filename is too long */ if (len > MAXPATHLEN) { return SUHOSIN_CODE_TYPE_LONGNAME; } memcpy(fname, s, len); fname[len] = 0; s = (char *)&fname; e = s + len; /* check if ASCIIZ attack -> not working yet (and cannot work in PHP4 + ZO) */ if (len != strlen(s)) { return SUHOSIN_CODE_TYPE_0FILE; } /* disallow uploaded files */ if (SG(rfc1867_uploaded_files)) { if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) s, e-s+1)) { return SUHOSIN_CODE_TYPE_UPLOADED; } } /* count number of directory traversals */ for (i=0; i < len-3; i++) { if (s[i] == '.' && s[i+1] == '.' && (s[i+2] == '/' || s[i+2] == '\\')) { count++; i+=2; } } if (SUHOSIN_G(executor_include_max_traversal) && SUHOSIN_G(executor_include_max_traversal)<=count) { return SUHOSIN_CODE_TYPE_MANYDOTS; } SDEBUG("xxx %p %p",SUHOSIN_G(include_whitelist),SUHOSIN_G(include_blacklist)); /* no black or whitelist then disallow all */ if (SUHOSIN_G(include_whitelist)==NULL && SUHOSIN_G(include_blacklist)==NULL) { /* disallow all URLs */ if (strstr(s, "://") != NULL || suhosin_strcasestr(s, "data:") != NULL) { return SUHOSIN_CODE_TYPE_BADURL; } } else /* whitelist is stronger than blacklist */ if (SUHOSIN_G(include_whitelist)) { do { isOk = 0; h = strstr(s, "://"); h2 = suhosin_strcasestr(s, "data:"); h2 = h2 == NULL ? NULL : h2 + 4; t = h = (h == NULL) ? h2 : ( (h2 == NULL) ? h : ( (h < h2) ? h : h2 ) ); if (h == NULL) break; while (t > s && (isalnum(t[-1]) || t[-1]=='_' || t[-1]=='.')) { t--; } tlen = e-t; zend_hash_internal_pointer_reset(SUHOSIN_G(include_whitelist)); do { int r = zend_hash_get_current_key_ex(SUHOSIN_G(include_whitelist), &index, &indexlen, &numindex, 0, NULL); if (r==HASH_KEY_NON_EXISTANT) { break; } if (r==HASH_KEY_IS_STRING) { if (h-t <= indexlen-1 && tlen>=indexlen-1) { if (strncasecmp(t, index, indexlen-1)==0) { isOk = 1; break; } } } zend_hash_move_forward(SUHOSIN_G(include_whitelist)); } while (1); /* not found in whitelist */ if (!isOk) { return SUHOSIN_CODE_TYPE_BADURL; } s = h + 1; } while (1); } else { do { int tlen; h = strstr(s, "://"); h2 = suhosin_strcasestr(s, "data:"); h2 = h2 == NULL ? NULL : h2 + 4; t = h = (h == NULL) ? h2 : ( (h2 == NULL) ? h : ( (h < h2) ? h : h2 ) ); if (h == NULL) break; while (t > s && (isalnum(t[-1]) || t[-1]=='_' || t[-1]=='.')) { t--; } tlen = e-t; zend_hash_internal_pointer_reset(SUHOSIN_G(include_blacklist)); do { int r = zend_hash_get_current_key_ex(SUHOSIN_G(include_blacklist), &index, &indexlen, &numindex, 0, NULL); if (r==HASH_KEY_NON_EXISTANT) { break; } if (r==HASH_KEY_IS_STRING) { if (h-t <= indexlen-1 && tlen>=indexlen-1) { if (strncasecmp(t, index, indexlen-1)==0) { return SUHOSIN_CODE_TYPE_BLACKURL; } } } zend_hash_move_forward(SUHOSIN_G(include_blacklist)); } while (1); s = h + 1; } while (1); } /* disallow writable files */ if (!SUHOSIN_G(executor_include_allow_writable_files)) { /* protection against *REMOTE* attacks, potential race condition of access() is irrelevant */ if (access(s, W_OK) == 0) { return SUHOSIN_CODE_TYPE_WRITABLE; } } return SUHOSIN_CODE_TYPE_GOODFILE; } static int (*old_zend_stream_open)(const char *filename, zend_file_handle *fh TSRMLS_DC); static int suhosin_zend_stream_open(const char *filename, zend_file_handle *fh TSRMLS_DC) { zend_execute_data *exd; exd=EG(current_execute_data); if (EG(in_execution) && (exd!=NULL) && (exd->opline != NULL) && (exd->opline->opcode == ZEND_INCLUDE_OR_EVAL)) { int filetype = suhosin_check_filename((char *)filename, strlen(filename) TSRMLS_CC); switch (filetype) { case SUHOSIN_CODE_TYPE_LONGNAME: suhosin_log(S_INCLUDE, "Include filename ('%s') is too long", filename); suhosin_bailout(TSRMLS_C); break; case SUHOSIN_CODE_TYPE_UPLOADED: suhosin_log(S_INCLUDE, "Include filename is an uploaded file"); suhosin_bailout(TSRMLS_C); break; case SUHOSIN_CODE_TYPE_0FILE: suhosin_log(S_INCLUDE, "Include filename contains an ASCIIZ character"); suhosin_bailout(TSRMLS_C); break; case SUHOSIN_CODE_TYPE_WRITABLE: suhosin_log(S_INCLUDE, "Include filename ('%s') is writable by PHP process", filename); suhosin_bailout(TSRMLS_C); break; case SUHOSIN_CODE_TYPE_BLACKURL: suhosin_log(S_INCLUDE, "Include filename ('%s') is a URL that is forbidden by the blacklist", filename); suhosin_bailout(TSRMLS_C); break; case SUHOSIN_CODE_TYPE_BADURL: suhosin_log(S_INCLUDE, "Include filename ('%s') is a URL that is not allowed", filename); suhosin_bailout(TSRMLS_C); break; case SUHOSIN_CODE_TYPE_MANYDOTS: suhosin_log(S_INCLUDE, "Include filename ('%s') contains too many '../'", filename); suhosin_bailout(TSRMLS_C); break; } } return old_zend_stream_open(filename, fh TSRMLS_CC); } static int suhosin_detect_codetype(zend_op_array *op_array TSRMLS_DC) { char *s; int r; s = (char *)op_array->filename; /* eval, assert, create_function, preg_replace */ if (op_array->type == ZEND_EVAL_CODE) { if (s == NULL) { return SUHOSIN_CODE_TYPE_UNKNOWN; } if (strstr(s, "eval()'d code") != NULL) { return SUHOSIN_CODE_TYPE_EVAL; } if (strstr(s, "regexp code") != NULL) { return SUHOSIN_CODE_TYPE_REGEXP; } if (strstr(s, "mbregex replace") != NULL) { return SUHOSIN_CODE_TYPE_MBREGEXP; } if (strstr(s, "assert code") != NULL) { return SUHOSIN_CODE_TYPE_ASSERT; } if (strstr(s, "runtime-created function") != NULL) { return SUHOSIN_CODE_TYPE_CFUNC; } if (strstr(s, "Command line code") != NULL) { return SUHOSIN_CODE_TYPE_COMMANDLINE; } if (strstr(s, "Command line begin code") != NULL) { return SUHOSIN_CODE_TYPE_COMMANDLINE; } if (strstr(s, "Command line run code") != NULL) { return SUHOSIN_CODE_TYPE_COMMANDLINE; } if (strstr(s, "Command line end code") != NULL) { return SUHOSIN_CODE_TYPE_COMMANDLINE; } if (strstr(s, "suhosin internal code") != NULL) { return SUHOSIN_CODE_TYPE_SUHOSIN; } } else { r = suhosin_check_filename(s, strlen(s) TSRMLS_CC); return r; } return SUHOSIN_CODE_TYPE_UNKNOWN; } /* {{{ void suhosin_execute_ex(zend_op_array *op_array TSRMLS_DC) * This function provides a hook for execution */ #if PHP_VERSION_ID >= 50500 static void suhosin_execute_ex(zend_execute_data *execute_data TSRMLS_DC) { zend_op_array *op_array = execute_data->op_array; #else static void suhosin_execute_ex(zend_op_array *op_array, int zo, long dummy TSRMLS_DC) { #endif zend_op_array *new_op_array; int op_array_type, len; char *fn; zval cs; zend_uint orig_code_type; unsigned long *suhosin_flags = NULL; /* log variable dropping statistics */ if (SUHOSIN_G(abort_request)) { SUHOSIN_G(abort_request) = 0; /* we only want this to happen the first time */ if (SUHOSIN_G(att_request_variables)-SUHOSIN_G(cur_request_variables) > 0) { suhosin_log(S_VARS, "dropped %u request variables - (%u in GET, %u in POST, %u in COOKIE)", SUHOSIN_G(att_request_variables)-SUHOSIN_G(cur_request_variables), SUHOSIN_G(att_get_vars)-SUHOSIN_G(cur_get_vars), SUHOSIN_G(att_post_vars)-SUHOSIN_G(cur_post_vars), SUHOSIN_G(att_cookie_vars)-SUHOSIN_G(cur_cookie_vars)); } if (!SUHOSIN_G(simulation) && SUHOSIN_G(filter_action)) { char *action = SUHOSIN_G(filter_action); long code = -1; while (*action == ' ' || *action == '\t') action++; if (*action >= '0' && *action <= '9') { char *end = action; while (*end && *end != ',' && *end != ';') end++; code = zend_atoi(action, end-action); action = end; } while (*action == ' ' || *action == '\t' || *action == ',' || *action == ';') action++; if (*action) { if (strncasecmp("http://", action, sizeof("http://")-1)==0 || strncasecmp("https://", action, sizeof("https://")-1)==0) { sapi_header_line ctr = {0}; if (code == -1) { code = 302; } ctr.line_len = spprintf(&ctr.line, 0, "Location: %s", action); ctr.response_code = code; sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC); efree(ctr.line); } else { zend_file_handle file_handle; zend_op_array *new_op_array; zval *result = NULL; if (code == -1) { code = 200; } if (zend_stream_open(action, &file_handle TSRMLS_CC) == SUCCESS) { if (!file_handle.opened_path) { file_handle.opened_path = estrndup(action, strlen(action)); } new_op_array = zend_compile_file(&file_handle, ZEND_REQUIRE TSRMLS_CC); zend_destroy_file_handle(&file_handle TSRMLS_CC); if (new_op_array) { EG(return_value_ptr_ptr) = &result; EG(active_op_array) = new_op_array; zend_execute(new_op_array TSRMLS_CC); destroy_op_array(new_op_array TSRMLS_CC); efree(new_op_array); if (!EG(exception)) { if (EG(return_value_ptr_ptr)) { zval_ptr_dtor(EG(return_value_ptr_ptr)); EG(return_value_ptr_ptr) = NULL; } } } else { code = 500; } } else { code = 500; } } } sapi_header_op(SAPI_HEADER_SET_STATUS, (void *)code TSRMLS_CC); zend_bailout(); } } SDEBUG("%s %s", op_array->filename, op_array->function_name); SUHOSIN_G(execution_depth)++; if (SUHOSIN_G(max_execution_depth) && SUHOSIN_G(execution_depth) > SUHOSIN_G(max_execution_depth)) { suhosin_log(S_EXECUTOR|S_GETCALLER, "maximum execution depth reached - script terminated"); suhosin_bailout(TSRMLS_C); } fn = (char *)op_array->filename; len = strlen(fn); orig_code_type = SUHOSIN_G(in_code_type); if (op_array->type == ZEND_EVAL_CODE) { SUHOSIN_G(in_code_type) = SUHOSIN_EVAL; } else { if (suhosin_zend_extension_entry.resource_number != -1) { suhosin_flags = (unsigned long *) &op_array->reserved[suhosin_zend_extension_entry.resource_number]; SDEBUG("suhosin flags: %08lx", *suhosin_flags); if (*suhosin_flags & SUHOSIN_FLAG_CREATED_BY_EVAL) { SUHOSIN_G(in_code_type) = SUHOSIN_EVAL; } if (*suhosin_flags & SUHOSIN_FLAG_NOT_EVALED_CODE) { goto not_evaled_code; } } if (strstr(op_array->filename, "eval()'d code")) { SUHOSIN_G(in_code_type) = SUHOSIN_EVAL; } else { if (suhosin_flags) { *suhosin_flags |= SUHOSIN_FLAG_NOT_EVALED_CODE; } } } not_evaled_code: SDEBUG("code type %u", SUHOSIN_G(in_code_type)); if (op_array->function_name) { goto continue_execution; } /* if (SUHOSIN_G(deactivate)) { goto continue_execution; } */ op_array_type = suhosin_detect_codetype(op_array TSRMLS_CC); switch (op_array_type) { case SUHOSIN_CODE_TYPE_EVAL: if (SUHOSIN_G(executor_disable_eval)) { suhosin_log(S_EXECUTOR|S_GETCALLER, "use of eval is forbidden by configuration"); if (!SUHOSIN_G(simulation)) { zend_error(E_ERROR, "SUHOSIN - Use of eval is forbidden by configuration"); } } break; case SUHOSIN_CODE_TYPE_REGEXP: if (SUHOSIN_G(executor_disable_emod)) { suhosin_log(S_EXECUTOR|S_GETCALLER, "use of preg_replace() with /e modifier is forbidden by configuration"); if (!SUHOSIN_G(simulation)) { zend_error(E_ERROR, "SUHOSIN - Use of preg_replace() with /e modifier is forbidden by configuration"); } } break; case SUHOSIN_CODE_TYPE_MBREGEXP: /* XXX TODO: Do we want to disallow this, too? */ break; case SUHOSIN_CODE_TYPE_ASSERT: break; case SUHOSIN_CODE_TYPE_CFUNC: break; case SUHOSIN_CODE_TYPE_LONGNAME: suhosin_log(S_INCLUDE|S_GETCALLER, "Include filename ('%s') is too long", op_array->filename); suhosin_bailout(TSRMLS_C); break; case SUHOSIN_CODE_TYPE_MANYDOTS: suhosin_log(S_INCLUDE|S_GETCALLER, "Include filename ('%s') contains too many '../'", op_array->filename); suhosin_bailout(TSRMLS_C); break; case SUHOSIN_CODE_TYPE_UPLOADED: suhosin_log(S_INCLUDE|S_GETCALLER, "Include filename is an uploaded file"); suhosin_bailout(TSRMLS_C); break; case SUHOSIN_CODE_TYPE_0FILE: suhosin_log(S_INCLUDE|S_GETCALLER, "Include filename contains an ASCIIZ character"); suhosin_bailout(TSRMLS_C); break; case SUHOSIN_CODE_TYPE_WRITABLE: suhosin_log(S_INCLUDE|S_GETCALLER, "Include filename ('%s') is writable by PHP process", op_array->filename); suhosin_bailout(TSRMLS_C); break; case SUHOSIN_CODE_TYPE_BLACKURL: suhosin_log(S_INCLUDE|S_GETCALLER, "Include filename ('%s') is a URL that is forbidden by the blacklist", op_array->filename); suhosin_bailout(TSRMLS_C); break; case SUHOSIN_CODE_TYPE_BADURL: suhosin_log(S_INCLUDE|S_GETCALLER, "Include filename ('%s') is a URL that is not allowed", op_array->filename); suhosin_bailout(TSRMLS_C); break; case SUHOSIN_CODE_TYPE_BADFILE: cs.type = IS_STRING; #define DIE_WITH_MSG "die('disallowed_file'.chr(10).chr(10));" cs.value.str.val = estrndup(DIE_WITH_MSG, sizeof(DIE_WITH_MSG)-1); cs.value.str.len = sizeof(DIE_WITH_MSG)-1; new_op_array = compile_string(&cs, "suhosin internal code" TSRMLS_CC); if (new_op_array) { op_array = new_op_array; goto continue_execution; } suhosin_bailout(TSRMLS_C); break; case SUHOSIN_CODE_TYPE_COMMANDLINE: case SUHOSIN_CODE_TYPE_SUHOSIN: case SUHOSIN_CODE_TYPE_UNKNOWN: case SUHOSIN_CODE_TYPE_GOODFILE: goto continue_execution; } continue_execution: #if PHP_VERSION_ID >= 50500 old_execute_ex (execute_data TSRMLS_CC); #else if (zo) { old_execute_ZO (op_array, dummy TSRMLS_CC); } else { old_execute (op_array TSRMLS_CC); } #endif /* nothing to do */ SUHOSIN_G(in_code_type) = orig_code_type; SUHOSIN_G(execution_depth)--; } /* }}} */ #if PHP_VERSION_ID < 50500 /* {{{ void suhosin_execute(zend_op_array *op_array TSRMLS_DC) * This function provides a hook for execution */ static void suhosin_execute(zend_op_array *op_array TSRMLS_DC) { suhosin_execute_ex(op_array, 0, 0 TSRMLS_CC); } /* {{{ void suhosin_execute(zend_op_array *op_array, long dummy TSRMLS_DC) * This function provides a hook for execution */ static void suhosin_execute_ZO(zend_op_array *op_array, long dummy TSRMLS_DC) { suhosin_execute_ex(op_array, 1, dummy TSRMLS_CC); } /* }}} */ #endif #if PHP_VERSION_ID >= 50500 #define IH_HANDLER_PARAMS_REST int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC #define IH_HANDLER_PARAMS internal_function_handler *ih, IH_HANDLER_PARAMS_REST #define IH_HANDLER_PARAM_PASSTHRU ih, ht, return_value, return_value_ptr, this_ptr, return_value_used TSRMLS_CC #else #define IH_HANDLER_PARAMS_REST zend_execute_data *execute_data_ptr, int return_value_used, int ht, zval *return_value TSRMLS_DC #define IH_HANDLER_PARAMS internal_function_handler *ih, IH_HANDLER_PARAMS_REST #define IH_HANDLER_PARAM_PASSTHRU ih, execute_data_ptr, return_value_used, ht, return_value TSRMLS_CC #endif HashTable ihandler_table; typedef struct _internal_function_handler { char *name; int (*handler)(struct _internal_function_handler *ih, IH_HANDLER_PARAMS_REST); void *arg1; void *arg2; void *arg3; } internal_function_handler; int ih_preg_replace(IH_HANDLER_PARAMS) { zval **regex, **replace, **subject, **limit, **zcount; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZZ|ZZ", ®ex, &replace, &subject, &limit, &zcount) == FAILURE) { return (1); } if (Z_TYPE_PP(regex) == IS_ARRAY) { zval **regex_entry; zend_hash_internal_pointer_reset(Z_ARRVAL_PP(regex)); /* For each entry in the regex array, get the entry */ while (zend_hash_get_current_data(Z_ARRVAL_PP(regex), (void **)®ex_entry) == SUCCESS) { if (Z_TYPE_PP(regex_entry) == IS_STRING) { if (strlen(Z_STRVAL_PP(regex_entry)) != Z_STRLEN_PP(regex_entry)) { suhosin_log(S_EXECUTOR, "string termination attack on first preg_replace parameter detected"); if (!SUHOSIN_G(simulation)) { RETVAL_FALSE; return (1); } } } zend_hash_move_forward(Z_ARRVAL_PP(regex)); } } else if (Z_TYPE_PP(regex) == IS_STRING) { if (strlen(Z_STRVAL_PP(regex)) != Z_STRLEN_PP(regex)) { suhosin_log(S_EXECUTOR, "string termination attack on first preg_replace parameter detected"); if (!SUHOSIN_G(simulation)) { RETVAL_FALSE; return (1); } } } return (0); } int ih_symlink(IH_HANDLER_PARAMS) { if (SUHOSIN_G(executor_allow_symlink)) { return (0); } if (PG(open_basedir) && PG(open_basedir)[0]) { suhosin_log(S_EXECUTOR, "symlink called during open_basedir"); if (!SUHOSIN_G(simulation)) { RETVAL_FALSE; return (1); } } return (0); } int ih_mail(IH_HANDLER_PARAMS) { char *to=NULL, *message=NULL, *headers=NULL; char *subject=NULL, *extra_cmd=NULL; char *tmp; int to_len, message_len, headers_len; int subject_len, extra_cmd_len; if (SUHOSIN_G(mailprotect) == 0) { return (0); } if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|ss", &to, &to_len, &subject, &subject_len, &message, &message_len, &headers, &headers_len, &extra_cmd, &extra_cmd_len ) == FAILURE) { RETVAL_FALSE; return (1); } if (headers_len > 0 && headers && (strstr(headers, "\n\n") || strstr(headers, "\n\r\n") /* double newline */ || *headers == '\n' || (headers[0] == '\r' && headers[1] == '\n') /* starts with newline */ )) { suhosin_log(S_MAIL, "mail() - double newline in headers, possible injection, mail dropped"); if (!SUHOSIN_G(simulation)) { RETVAL_FALSE; return (1); } } /* check for spam attempts with buggy webforms */ if (to_len > 0 && to) { do { if ((tmp = strchr(to, '\n')) == NULL) tmp = strchr(to, '\r'); if (tmp == NULL) break; to = tmp + 1; if (!isspace(*to)) break; } while (1); if (tmp != NULL) { suhosin_log(S_MAIL, "mail() - newline in To header, possible injection, mail dropped"); if (!SUHOSIN_G(simulation)) { RETVAL_FALSE; return (1); } } } if (subject_len > 0 && subject) { do { if ((tmp = strchr(subject, '\n')) == NULL) tmp = strchr(subject, '\r'); if (tmp == NULL) break; subject = tmp + 1; if (!isspace(*subject)) break; } while (1); if (tmp != NULL) { suhosin_log(S_MAIL, "mail() - newline in Subject header, possible injection, mail dropped"); if (!SUHOSIN_G(simulation)) { RETVAL_FALSE; return (1); } } } if (SUHOSIN_G(mailprotect) > 1) { /* search for to, cc or bcc headers */ if (headers_len > 0 && headers != NULL) { if (strncasecmp(headers, "to:", sizeof("to:") - 1) == 0 || suhosin_strcasestr(headers, "\nto:")) { suhosin_log(S_MAIL, "mail() - To: headers aren't allowed in the headers parameter."); if (!SUHOSIN_G(simulation)) { RETVAL_FALSE; return (1); } } if (strncasecmp(headers, "cc:", sizeof("cc:") - 1) == 0 || suhosin_strcasestr(headers, "\ncc:")) { suhosin_log(S_MAIL, "mail() - CC: headers aren't allowed in the headers parameter."); if (!SUHOSIN_G(simulation)) { RETVAL_FALSE; return (1); } } if (strncasecmp(headers, "bcc:", sizeof("bcc:") - 1) == 0 || suhosin_strcasestr(headers, "\nbcc:")) { suhosin_log(S_MAIL, "mail() - BCC: headers aren't allowed in the headers parameter."); if (!SUHOSIN_G(simulation)) { RETVAL_FALSE; return (1); } } } } return (0); } #define SQLSTATE_SQL 0 #define SQLSTATE_IDENTIFIER 1 #define SQLSTATE_STRING 2 #define SQLSTATE_COMMENT 3 #define SQLSTATE_MLCOMMENT 4 int ih_querycheck(IH_HANDLER_PARAMS) { void **p = zend_vm_stack_top(TSRMLS_C) - 1; unsigned long arg_count; zval **arg; char *query, *s, *e; zval *backup; int len; char quote; int state = SQLSTATE_SQL; int cnt_union = 0, cnt_select = 0, cnt_comment = 0, cnt_opencomment = 0; int mysql_extension = 0; SDEBUG("function: %s", ih->name); arg_count = (unsigned long) *p; if (ht < (long) ih->arg1) { return (0); } if ((long) ih->arg2) { mysql_extension = 1; } arg = (zval **) p - (arg_count - (long) ih->arg1 + 1); /* count from 0 */ backup = *arg; if (Z_TYPE_P(backup) != IS_STRING) { return (0); } len = Z_STRLEN_P(backup); query = Z_STRVAL_P(backup); SDEBUG("SQL |%s|", query); s = query; e = s+len; while (s < e) { switch (state) { case SQLSTATE_SQL: switch (s[0]) { case '`': state = SQLSTATE_IDENTIFIER; quote = '`'; break; case '\'': case '"': state = SQLSTATE_STRING; quote = *s; break; case '/': if (s[1]=='*') { if (mysql_extension == 1 && s[2] == '!') { s += 2; break; } s++; state = SQLSTATE_MLCOMMENT; cnt_comment++; } break; case '-': if (s[1]=='-') { s++; state = SQLSTATE_COMMENT; cnt_comment++; } break; case '#': state = SQLSTATE_COMMENT; cnt_comment++; break; case 'u': case 'U': if (strncasecmp("union", s, 5)==0) { s += 4; cnt_union++; } break; case 's': case 'S': if (strncasecmp("select", s, 6)==0) { s += 5; cnt_select++; } break; } break; case SQLSTATE_STRING: case SQLSTATE_IDENTIFIER: if (s[0] == quote) { if (s[1] == quote) { s++; } else { state = SQLSTATE_SQL; } } if (s[0] == '\\') { s++; } break; case SQLSTATE_COMMENT: while (s[0] && s[0] != '\n') { s++; } state = SQLSTATE_SQL; break; case SQLSTATE_MLCOMMENT: while (s[0] && (s[0] != '*' || s[1] != '/')) { s++; } if (s[0]) { state = SQLSTATE_SQL; } break; } s++; } if (state == SQLSTATE_MLCOMMENT) { cnt_opencomment = 1; } if (cnt_opencomment && SUHOSIN_G(sql_opencomment)>0) { suhosin_log(S_SQL, "Open comment in SQL query: '%*s'", len, query); if (SUHOSIN_G(sql_opencomment)>1) { suhosin_bailout(TSRMLS_C); } } if (cnt_comment && SUHOSIN_G(sql_comment)>0) { suhosin_log(S_SQL, "Comment in SQL query: '%*s'", len, query); if (SUHOSIN_G(sql_comment)>1) { suhosin_bailout(TSRMLS_C); } } if (cnt_union && SUHOSIN_G(sql_union)>0) { suhosin_log(S_SQL, "UNION in SQL query: '%*s'", len, query); if (SUHOSIN_G(sql_union)>1) { suhosin_bailout(TSRMLS_C); } } if (cnt_select>1 && SUHOSIN_G(sql_mselect)>0) { suhosin_log(S_SQL, "Multiple SELECT in SQL query: '%*s'", len, query); if (SUHOSIN_G(sql_mselect)>1) { suhosin_bailout(TSRMLS_C); } } return (0); } int ih_fixusername(IH_HANDLER_PARAMS) { void **p = zend_vm_stack_top(TSRMLS_C) - 1; unsigned long arg_count; zval **arg; char *prefix, *postfix, *user, *user_match, *cp; zval *backup, *my_user; int prefix_len, postfix_len, len; SDEBUG("function (fixusername): %s", ih->name); prefix = SUHOSIN_G(sql_user_prefix); postfix = SUHOSIN_G(sql_user_postfix); user_match = SUHOSIN_G(sql_user_match); arg_count = (unsigned long) *p; if (ht < (long) ih->arg1) { return (0); } arg = (zval **) p - (arg_count - (long) ih->arg1 + 1); /* count from 0 */ backup = *arg; if (Z_TYPE_P(backup) != IS_STRING) { user = ""; len = 0; } else { len = Z_STRLEN_P(backup); user = Z_STRVAL_P(backup); } cp = user; while (cp < user+len) { if (*cp < 32) { suhosin_log(S_SQL, "SQL username contains invalid characters"); if (!SUHOSIN_G(simulation)) { RETVAL_FALSE; return (1); } break; } cp++; } if ((prefix != NULL && prefix[0]) || (postfix != NULL && postfix[0])) { if (prefix == NULL) { prefix = ""; } if (postfix == NULL) { postfix = ""; } prefix_len = strlen(prefix); postfix_len = strlen(postfix); MAKE_STD_ZVAL(my_user); my_user->type = IS_STRING; my_user->value.str.len = spprintf(&my_user->value.str.val, 0, "%s%s%s", prefix, user, postfix); /* XXX: memory_leak? */ *arg = my_user; len = Z_STRLEN_P(my_user); user = Z_STRVAL_P(my_user); } if (user_match && user_match[0]) { #ifdef HAVE_FNMATCH if (fnmatch(user_match, user, 0) != 0) { suhosin_log(S_SQL, "SQL username ('%s') does not match suhosin.sql.user_match ('%s')", user, user_match); if (!SUHOSIN_G(simulation)) { RETVAL_FALSE; return (1); } } #else #warning no support for fnmatch() - setting suhosin.sql.user_match will always fail. suhosin_log(S_SQL, "suhosin.sql.user_match specified, but system does not support fnmatch()"); if (!SUHOSIN_G(simulation)) { RETVAL_FALSE; return (1); } #endif } SDEBUG("function: %s - user: %s", ih->name, user); return (0); } static int ih_function_exists(IH_HANDLER_PARAMS) { char *name; int name_len; zend_function *func; char *lcname; zend_bool retval; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { return 1; } if (name_len <= 0) { RETVAL_BOOL(0); return 1; } lcname = zend_str_tolower_dup(name, name_len); /* Ignore leading "\" */ name = lcname; if (lcname[0] == '\\') { name = &lcname[1]; name_len--; } retval = (zend_hash_find(EG(function_table), name, name_len+1, (void **)&func) == SUCCESS); /* * A bit of a hack, but not a bad one: we see if the handler of the function * is actually one that displays "function is disabled" message. */ if (retval && func->type == ZEND_INTERNAL_FUNCTION && func->internal_function.handler == zif_display_disabled_function) { retval = 0; goto ret; } /* Now check if function is forbidden by Suhosin */ if (SUHOSIN_G(in_code_type) == SUHOSIN_EVAL) { if (SUHOSIN_G(eval_whitelist) != NULL) { if (!zend_hash_exists(SUHOSIN_G(eval_whitelist), name, name_len+1)) { retval = 0; goto ret; } } else if (SUHOSIN_G(eval_blacklist) != NULL) { if (zend_hash_exists(SUHOSIN_G(eval_blacklist), name, name_len+1)) { retval = 0; goto ret; } } } if (SUHOSIN_G(func_whitelist) != NULL) { if (!zend_hash_exists(SUHOSIN_G(func_whitelist), name, name_len+1)) { retval = 0; goto ret; } } else if (SUHOSIN_G(func_blacklist) != NULL) { if (zend_hash_exists(SUHOSIN_G(func_blacklist), name, name_len+1)) { retval = 0; goto ret; } } ret: efree(lcname); RETVAL_BOOL(retval); return 1; } /* MT RAND FUNCTIONS */ /* The following php_mt_...() functions are based on a C++ class MTRand by Richard J. Wagner. For more information see the web page at http://www-personal.engin.umich.edu/~wagnerr/MersenneTwister.html Mersenne Twister random number generator -- a C++ class MTRand Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus Richard J. Wagner v1.0 15 May 2003 rjwagner@writeme.com The Mersenne Twister is an algorithm for generating random numbers. It was designed with consideration of the flaws in various other generators. The period, 2^19937-1, and the order of equidistribution, 623 dimensions, are far greater. The generator is also fast; it avoids multiplication and division, and it benefits from caches and pipelines. For more information see the inventors' web page at http://www.math.keio.ac.jp/~matumoto/emt.html Reference M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30. Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, Copyright (C) 2000 - 2003, Richard J. Wagner All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of its contributors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The original code included the following notice: When you use this, send an email to: matumoto@math.keio.ac.jp with an appropriate reference to your work. It would be nice to CC: rjwagner@writeme.com and Cokus@math.washington.edu when you write. */ #define N 624 /* length of state vector */ #define M (397) /* a period parameter */ #define hiBit(u) ((u) & 0x80000000U) /* mask all but highest bit of u */ #define loBit(u) ((u) & 0x00000001U) /* mask all but lowest bit of u */ #define loBits(u) ((u) & 0x7FFFFFFFU) /* mask the highest bit of u */ #define mixBits(u, v) (hiBit(u)|loBits(v)) /* move hi bit of u to hi bit of v */ #define twist(m,u,v) (m ^ (mixBits(u,v)>>1) ^ ((php_uint32)(-(php_int32)(loBit(v))) & 0x9908b0dfU)) /* {{{ php_mt_initialize */ static inline void suhosin_mt_initialize(php_uint32 seed, php_uint32 *state) { /* Initialize generator state with seed See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier. In previous versions, most significant bits (MSBs) of the seed affect only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto. */ register php_uint32 *s = state; register php_uint32 *r = state; register int i = 1; *s++ = seed & 0xffffffffU; for( ; i < N; ++i ) { *s++ = ( 1812433253U * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffU; r++; } } /* }}} */ static inline void suhosin_mt_init_by_array(php_uint32 *key, int keylen, php_uint32 *state) { int i, j, k; suhosin_mt_initialize(19650218U, state); i = 1; j = 0; k = (N > keylen ? N : keylen); for (; k; k--) { state[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1664525U)) + key[j] + j; i++; j = (j+1) % keylen; if (i >= N) { state[0] = state[N-1]; i=1; } } for (k=N-1; k; k--) { state[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1566083941U)) - i; i++; if (i >= N) { state[0] = state[N-1]; i=1; } } state[0] = 0x80000000U; } /* }}} */ /* {{{ suhosin_mt_reload */ static inline void suhosin_mt_reload(php_uint32 *state, php_uint32 **next, int *left) { /* Generate N new values in state Made clearer and faster by Matthew Bellew (matthew.bellew@home.com) */ register php_uint32 *p = state; register int i; for (i = N - M; i--; ++p) *p = twist(p[M], p[0], p[1]); for (i = M; --i; ++p) *p = twist(p[M-N], p[0], p[1]); *p = twist(p[M-N], p[0], state[0]); *left = N; *next = state; } /* }}} */ /* {{{ suhosin_mt_srand */ static void suhosin_mt_srand(php_uint32 seed TSRMLS_DC) { /* Seed the generator with a simple uint32 */ suhosin_mt_initialize(seed, SUHOSIN_G(mt_state)); suhosin_mt_reload(SUHOSIN_G(mt_state), &SUHOSIN_G(mt_next), &SUHOSIN_G(mt_left)); /* Seed only once */ SUHOSIN_G(mt_is_seeded) = 1; } /* }}} */ /* {{{ suhosin_mt_rand */ static php_uint32 suhosin_mt_rand(TSRMLS_D) { /* Pull a 32-bit integer from the generator state Every other access function simply transforms the numbers extracted here */ register php_uint32 s1; if (SUHOSIN_G(mt_left) == 0) { suhosin_mt_reload(SUHOSIN_G(mt_state), &SUHOSIN_G(mt_next), &SUHOSIN_G(mt_left)); } --SUHOSIN_G(mt_left); s1 = *SUHOSIN_G(mt_next)++; s1 ^= (s1 >> 11); s1 ^= (s1 << 7) & 0x9d2c5680U; s1 ^= (s1 << 15) & 0xefc60000U; return ( s1 ^ (s1 >> 18) ); } /* }}} */ /* {{{ suhosin_gen_entropy */ static void suhosin_gen_entropy(php_uint32 *entropybuf TSRMLS_DC) { php_uint32 seedbuf[20]; /* On a modern OS code, stack and heap base are randomized */ unsigned long code_value = (unsigned long)suhosin_gen_entropy; unsigned long stack_value = (unsigned long)&code_value; unsigned long heap_value = (unsigned long)SUHOSIN_G(r_state); suhosin_SHA256_CTX context; int fd; code_value ^= code_value >> 32; stack_value ^= stack_value >> 32; heap_value ^= heap_value >> 32; seedbuf[0] = code_value; seedbuf[1] = stack_value; seedbuf[2] = heap_value; seedbuf[3] = time(0); #ifdef PHP_WIN32 seedbuf[4] = GetCurrentProcessId(); #else seedbuf[4] = getpid(); #endif seedbuf[5] = (php_uint32) 0x7fffffff * php_combined_lcg(TSRMLS_C); #ifndef PHP_WIN32 fd = VCWD_OPEN("/dev/urandom", O_RDONLY); if (fd >= 0) { /* ignore error case - if urandom doesn't give us any/enough random bytes */ read(fd, &seedbuf[6], 8 * sizeof(php_uint32)); close(fd); } #else /* we have to live with the possibility that this call fails */ php_win32_get_random_bytes((unsigned char*)&seedbuf[6], 8 * sizeof(php_uint32)); #endif suhosin_SHA256Init(&context); /* to our friends from Debian: yes this will add unitialized stack values to the entropy DO NOT REMOVE */ suhosin_SHA256Update(&context, (void *) seedbuf, sizeof(seedbuf)); if (SUHOSIN_G(seedingkey) != NULL && *SUHOSIN_G(seedingkey) != 0) { suhosin_SHA256Update(&context, (unsigned char*)SUHOSIN_G(seedingkey), strlen(SUHOSIN_G(seedingkey))); } suhosin_SHA256Final((void *)entropybuf, &context); } /* }}} */ /* {{{ suhosin_srand_auto */ static void suhosin_srand_auto(TSRMLS_D) { php_uint32 seed[8]; suhosin_gen_entropy(&seed[0] TSRMLS_CC); suhosin_mt_init_by_array(seed, 8, SUHOSIN_G(r_state)); suhosin_mt_reload(SUHOSIN_G(r_state), &SUHOSIN_G(r_next), &SUHOSIN_G(r_left)); /* Seed only once */ SUHOSIN_G(r_is_seeded) = 1; } /* }}} */ /* {{{ suhosin_mt_srand_auto */ static void suhosin_mt_srand_auto(TSRMLS_D) { php_uint32 seed[8]; suhosin_gen_entropy(&seed[0] TSRMLS_CC); suhosin_mt_init_by_array(seed, 8, SUHOSIN_G(mt_state)); suhosin_mt_reload(SUHOSIN_G(mt_state), &SUHOSIN_G(mt_next), &SUHOSIN_G(mt_left)); /* Seed only once */ SUHOSIN_G(mt_is_seeded) = 1; } /* }}} */ /* {{{ suhosin_srand */ static void suhosin_srand(php_uint32 seed TSRMLS_DC) { /* Seed the generator with a simple uint32 */ suhosin_mt_initialize(seed+0x12345, SUHOSIN_G(r_state)); suhosin_mt_reload(SUHOSIN_G(r_state), &SUHOSIN_G(r_next), &SUHOSIN_G(r_left)); /* Seed only once */ SUHOSIN_G(r_is_seeded) = 1; } /* }}} */ /* {{{ suhosin_mt_rand */ static php_uint32 suhosin_rand(TSRMLS_D) { /* Pull a 32-bit integer from the generator state Every other access function simply transforms the numbers extracted here */ register php_uint32 s1; if (SUHOSIN_G(r_left) == 0) { suhosin_mt_reload(SUHOSIN_G(r_state), &SUHOSIN_G(r_next), &SUHOSIN_G(r_left)); } --SUHOSIN_G(r_left); s1 = *SUHOSIN_G(r_next)++; s1 ^= (s1 >> 11); s1 ^= (s1 << 7) & 0x9d2c5680U; s1 ^= (s1 << 15) & 0xefc60000U; return ( s1 ^ (s1 >> 18) ); } /* }}} */ static int ih_srand(IH_HANDLER_PARAMS) { int argc = ZEND_NUM_ARGS(); long seed; if (SUHOSIN_G(srand_ignore)) { SUHOSIN_G(r_is_seeded) = 0; return 1; } if (zend_parse_parameters(argc TSRMLS_CC, "|l", &seed) == FAILURE) { return 1; } if (argc) { suhosin_srand(seed TSRMLS_CC); } else { suhosin_srand_auto(TSRMLS_C); } return (1); } static int ih_mt_srand(IH_HANDLER_PARAMS) { int argc = ZEND_NUM_ARGS(); long seed; if (SUHOSIN_G(mt_srand_ignore)) { SUHOSIN_G(mt_is_seeded) = 0; return 1; } if (zend_parse_parameters(argc TSRMLS_CC, "|l", &seed) == FAILURE) { return 1; } if (argc) { suhosin_mt_srand(seed TSRMLS_CC); } else { suhosin_mt_srand_auto(TSRMLS_C); } return 1; } static int ih_mt_rand(IH_HANDLER_PARAMS) { int argc = ZEND_NUM_ARGS(); long min; long max; long number; if (argc != 0 && zend_parse_parameters(argc TSRMLS_CC, "ll", &min, &max) == FAILURE) { return (1); } if (!SUHOSIN_G(mt_is_seeded)) { suhosin_mt_srand_auto(TSRMLS_C); } number = (long) (suhosin_mt_rand(TSRMLS_C) >> 1); if (argc == 2) { RAND_RANGE(number, min, max, PHP_MT_RAND_MAX); } RETVAL_LONG(number); return (1); } static int ih_rand(IH_HANDLER_PARAMS) { int argc = ZEND_NUM_ARGS(); long min; long max; long number; if (argc != 0 && zend_parse_parameters(argc TSRMLS_CC, "ll", &min, &max) == FAILURE) { return (1); } if (!SUHOSIN_G(r_is_seeded)) { suhosin_srand_auto(TSRMLS_C); } number = (long) (suhosin_rand(TSRMLS_C) >> 1); if (argc == 2) { RAND_RANGE(number, min, max, PHP_MT_RAND_MAX); } RETVAL_LONG(number); return (1); } static int ih_getrandmax(IH_HANDLER_PARAMS) { if (zend_parse_parameters_none() == FAILURE) { return (1); } RETVAL_LONG(PHP_MT_RAND_MAX); return (1); } internal_function_handler ihandlers[] = { { "preg_replace", ih_preg_replace, NULL, NULL, NULL }, { "mail", ih_mail, NULL, NULL, NULL }, { "symlink", ih_symlink, NULL, NULL, NULL }, { "srand", ih_srand, NULL, NULL, NULL }, { "mt_srand", ih_mt_srand, NULL, NULL, NULL }, { "rand", ih_rand, NULL, NULL, NULL }, { "mt_rand", ih_mt_rand, NULL, NULL, NULL }, { "getrandmax", ih_getrandmax, NULL, NULL, NULL }, { "mt_getrandmax", ih_getrandmax, NULL, NULL, NULL }, { "function_exists", ih_function_exists, NULL, NULL, NULL }, /* Mysqli */ { "mysqli::mysqli", ih_fixusername, (void *)2, NULL, NULL }, { "mysqli_connect", ih_fixusername, (void *)2, NULL, NULL }, { "mysqli::real_connect", ih_fixusername, (void *)2, NULL, NULL }, { "mysqli_real_connect", ih_fixusername, (void *)3, NULL, NULL }, { "mysqli_change_user", ih_fixusername, (void *)2, NULL, NULL }, { "mysqli::change_user", ih_fixusername, (void *)1, NULL, NULL }, { "mysqli::query", ih_querycheck, (void *)1, (void *)1, NULL }, { "mysqli_query", ih_querycheck, (void *)2, (void *)1, NULL }, { "mysqli::multi_query", ih_querycheck, (void *)1, (void *)1, NULL }, { "mysqli_multi_query", ih_querycheck, (void *)2, (void *)1, NULL }, { "mysqli::prepare", ih_querycheck, (void *)1, (void *)1, NULL }, { "mysqli_prepare", ih_querycheck, (void *)2, (void *)1, NULL }, { "mysqli::real_query", ih_querycheck, (void *)1, (void *)1, NULL }, { "mysqli_real_query", ih_querycheck, (void *)2, (void *)1, NULL }, { "mysqli::send_query", ih_querycheck, (void *)1, (void *)1, NULL }, { "mysqli_send_query", ih_querycheck, (void *)2, (void *)1, NULL }, // removed in PHP 5.3 { "mysqli_master_query", ih_querycheck, (void *)2, (void *)1, NULL }, { "mysqli_slave_query", ih_querycheck, (void *)2, (void *)1, NULL }, // ---- /* Mysql API - deprecated in PHP 5.5 */ { "mysql_connect", ih_fixusername, (void *)2, NULL, NULL }, { "mysql_pconnect", ih_fixusername, (void *)2, NULL, NULL }, { "mysql_query", ih_querycheck, (void *)1, (void *)1, NULL }, { "mysql_db_query", ih_querycheck, (void *)2, (void *)1, NULL }, { "mysql_unbuffered_query", ih_querycheck, (void *)1, (void *)1, NULL }, #ifdef SUHOSIN_EXPERIMENTAL /* MaxDB */ { "maxdb::maxdb", ih_fixusername, (void *)2, NULL, NULL }, { "maxdb_connect", ih_fixusername, (void *)2, NULL, NULL }, { "maxdb::real_connect", ih_fixusername, (void *)2, NULL, NULL }, { "maxdb_real_connect", ih_fixusername, (void *)3, NULL, NULL }, { "maxdb::change_user", ih_fixusername, (void *)1, NULL, NULL }, { "maxdb_change_user", ih_fixusername, (void *)2, NULL, NULL }, { "maxdb_master_query", ih_querycheck, (void *)2, NULL, NULL }, { "maxdb::multi_query", ih_querycheck, (void *)1, NULL, NULL }, { "maxdb_multi_query", ih_querycheck, (void *)2, NULL, NULL }, { "maxdb::query", ih_querycheck, (void *)1, NULL, NULL }, { "maxdb_query", ih_querycheck, (void *)2, NULL, NULL }, { "maxdb::real_query", ih_querycheck, (void *)1, NULL, NULL }, { "maxdb_real_query", ih_querycheck, (void *)2, NULL, NULL }, { "maxdb::send_query", ih_querycheck, (void *)1, NULL, NULL }, { "maxdb_send_query", ih_querycheck, (void *)2, NULL, NULL }, { "maxdb::prepare", ih_querycheck, (void *)1, NULL, NULL }, { "maxdb_prepare", ih_querycheck, (void *)2, NULL, NULL }, /* PDO */ /* note: mysql conditional comments not supported here */ { "pdo::__construct", ih_fixusername, (void *)2, NULL, NULL }, /* note: username may come from dsn (param 1) */ { "pdo::query", ih_querycheck, (void *)1, NULL, NULL }, { "pdo::prepare", ih_querycheck, (void *)1, NULL, NULL }, { "pdo::exec", ih_querycheck, (void *)1, NULL, NULL }, /* Oracle OCI8 */ { "ocilogon", ih_fixusername, (void *)1, NULL, NULL }, { "ociplogon", ih_fixusername, (void *)1, NULL, NULL }, { "ocinlogon", ih_fixusername, (void *)1, NULL, NULL }, { "oci_connect", ih_fixusername, (void *)1, NULL, NULL }, { "oci_pconnect", ih_fixusername, (void *)1, NULL, NULL }, { "oci_new_connect", ih_fixusername, (void *)1, NULL, NULL }, /* FrontBase */ { "fbsql_connect", ih_fixusername, (void *)2, NULL, NULL }, { "fbsql_pconnect", ih_fixusername, (void *)2, NULL, NULL }, { "fbsql_change_user", ih_fixusername, (void *)1, NULL, NULL }, { "fbsql_username", ih_fixusername, (void *)2, NULL, NULL }, /* Informix */ { "ifx_connect", ih_fixusername, (void *)2, NULL, NULL }, { "ifx_pconnect", ih_fixusername, (void *)2, NULL, NULL }, /* Firebird/InterBase */ { "ibase_connect", ih_fixusername, (void *)2, NULL, NULL }, { "ibase_pconnect", ih_fixusername, (void *)2, NULL, NULL }, { "ibase_service_attach", ih_fixusername, (void *)2, NULL, NULL }, /* Microsoft SQL Server */ { "mssql_connect", ih_fixusername, (void *)2, NULL, NULL }, { "mssql_pconnect", ih_fixusername, (void *)2, NULL, NULL }, #endif { NULL, NULL, NULL, NULL, NULL } }; #define FUNCTION_WARNING() zend_error(E_WARNING, "%s() has been disabled for security reasons", get_active_function_name(TSRMLS_C)); #define FUNCTION_SIMULATE_WARNING() zend_error(E_WARNING, "SIMULATION - %s() has been disabled for security reasons", get_active_function_name(TSRMLS_C)); /* {{{ void suhosin_execute_internal * This function provides a hook for internal execution */ #if PHP_VERSION_ID >= 50500 #define EX_T(offset) (*EX_TMP_VAR(execute_data_ptr, offset)) static void suhosin_execute_internal(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC) { zval *return_value; zval **return_value_ptr; zval *this_ptr; int ht; if (fci) { return_value = *fci->retval_ptr_ptr; return_value_ptr = fci->retval_ptr_ptr; this_ptr = fci->object_ptr; ht = fci->param_count; } else { temp_variable *ret = &EX_T(execute_data_ptr->opline->result.var); zend_function *fbc = execute_data_ptr->function_state.function; return_value = ret->var.ptr; return_value_ptr = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ? &ret->var.ptr : NULL; this_ptr = execute_data_ptr->object; ht = execute_data_ptr->opline->extended_value; } #else static void suhosin_execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC) { zval *return_value; int ht = execute_data_ptr->opline->extended_value; #endif char *lcname; int function_name_strlen, free_lcname = 0; zend_class_entry *ce = NULL; internal_function_handler *ih; ce = ((zend_internal_function *) execute_data_ptr->function_state.function)->scope; lcname = (char *)((zend_internal_function *) execute_data_ptr->function_state.function)->function_name; function_name_strlen = strlen(lcname); /* handle methodcalls correctly */ if (ce != NULL) { char *tmp = (char *) emalloc(function_name_strlen + 2 + ce->name_length + 1); memcpy(tmp, ce->name, ce->name_length); memcpy(tmp+ce->name_length, "::", 2); memcpy(tmp+ce->name_length+2, lcname, function_name_strlen); lcname = tmp; free_lcname = 1; function_name_strlen += ce->name_length + 2; lcname[function_name_strlen] = 0; zend_str_tolower(lcname, function_name_strlen); } #if PHP_VERSION_ID < 50500 return_value = (*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.var)).var.ptr; #endif SDEBUG("function: %s", lcname); if (SUHOSIN_G(in_code_type) == SUHOSIN_EVAL) { if (SUHOSIN_G(eval_whitelist) != NULL) { if (!zend_hash_exists(SUHOSIN_G(eval_whitelist), lcname, function_name_strlen+1)) { suhosin_log(S_EXECUTOR|S_GETCALLER, "function outside of eval whitelist called: %s()", lcname); if (!SUHOSIN_G(simulation)) { goto execute_internal_bailout; } else { FUNCTION_SIMULATE_WARNING() } } } else if (SUHOSIN_G(eval_blacklist) != NULL) { if (zend_hash_exists(SUHOSIN_G(eval_blacklist), lcname, function_name_strlen+1)) { suhosin_log(S_EXECUTOR|S_GETCALLER, "function within eval blacklist called: %s()", lcname); if (!SUHOSIN_G(simulation)) { goto execute_internal_bailout; } else { FUNCTION_SIMULATE_WARNING() } } } } if (SUHOSIN_G(func_whitelist) != NULL) { if (!zend_hash_exists(SUHOSIN_G(func_whitelist), lcname, function_name_strlen+1)) { suhosin_log(S_EXECUTOR|S_GETCALLER, "function outside of whitelist called: %s()", lcname); if (!SUHOSIN_G(simulation)) { goto execute_internal_bailout; } else { FUNCTION_SIMULATE_WARNING() } } } else if (SUHOSIN_G(func_blacklist) != NULL) { if (zend_hash_exists(SUHOSIN_G(func_blacklist), lcname, function_name_strlen+1)) { suhosin_log(S_EXECUTOR|S_GETCALLER, "function within blacklist called: %s()", lcname); if (!SUHOSIN_G(simulation)) { goto execute_internal_bailout; } else { FUNCTION_SIMULATE_WARNING() } } } if (zend_hash_find(&ihandler_table, lcname, function_name_strlen+1, (void **)&ih) == SUCCESS) { int retval = 0; void *handler = ((zend_internal_function *) execute_data_ptr->function_state.function)->handler; if (handler != ZEND_FN(display_disabled_function)) { retval = ih->handler(IH_HANDLER_PARAM_PASSTHRU); } if (retval == 0) { #if PHP_VERSION_ID >= 50500 old_execute_internal(execute_data_ptr, fci, return_value_used TSRMLS_CC); #else old_execute_internal(execute_data_ptr, return_value_used TSRMLS_CC); #endif } } else { #if PHP_VERSION_ID >= 50500 old_execute_internal(execute_data_ptr, fci, return_value_used TSRMLS_CC); #else old_execute_internal(execute_data_ptr, return_value_used TSRMLS_CC); #endif } if (free_lcname == 1) { efree(lcname); } return; execute_internal_bailout: if (free_lcname == 1) { efree(lcname); } FUNCTION_WARNING() suhosin_bailout(TSRMLS_C); } /* }}} */ /* {{{ int function_lookup(zend_extension *extension) */ static int function_lookup(zend_extension *extension) { if (zo_set_oe_ex != NULL) { return ZEND_HASH_APPLY_STOP; } if (extension->handle != NULL) { zo_set_oe_ex = (void *)DL_FETCH_SYMBOL(extension->handle, "zend_optimizer_set_oe_ex"); } return 0; } /* }}} */ /* {{{ void suhosin_hook_execute() */ void suhosin_hook_execute(TSRMLS_D) { internal_function_handler *ih; #if PHP_VERSION_ID >= 50500 old_execute_ex = zend_execute_ex; zend_execute_ex = suhosin_execute_ex; #else old_execute = zend_execute; zend_execute = suhosin_execute; #endif /* old_compile_file = zend_compile_file; zend_compile_file = suhosin_compile_file; */ #if ZO_COMPATIBILITY_HACK_TEMPORARY_DISABLED if (zo_set_oe_ex == NULL) { zo_set_oe_ex = (void *)DL_FETCH_SYMBOL(NULL, "zend_optimizer_set_oe_ex"); } if (zo_set_oe_ex == NULL) { zend_llist_apply(&zend_extensions, (llist_apply_func_t)function_lookup TSRMLS_CC); } if (zo_set_oe_ex != NULL) { old_execute_ZO = zo_set_oe_ex(suhosin_execute_ZO); } #endif old_execute_internal = zend_execute_internal; if (old_execute_internal == NULL) { old_execute_internal = execute_internal; } zend_execute_internal = suhosin_execute_internal; /* register internal function handlers */ zend_hash_init(&ihandler_table, 16, NULL, NULL, 1); ih = &ihandlers[0]; while (ih->name) { zend_hash_add(&ihandler_table, ih->name, strlen(ih->name)+1, ih, sizeof(internal_function_handler), NULL); ih++; } /* Add additional protection layer, that SHOULD catch ZEND_INCLUDE_OR_EVAL *before* the engine tries to execute */ old_zend_stream_open = zend_stream_open_function; zend_stream_open_function = suhosin_zend_stream_open; } /* }}} */ /* {{{ void suhosin_unhook_execute() */ void suhosin_unhook_execute() { #if ZO_COMPATIBILITY_HACK_TEMPORARY_DISABLED if (zo_set_oe_ex) { zo_set_oe_ex(old_execute_ZO); } #endif #if PHP_VERSION_ID >= 50500 zend_execute_ex = old_execute_ex; #else zend_execute = old_execute; #endif /* zend_compile_file = old_compile_file; */ if (old_execute_internal == execute_internal) { old_execute_internal = NULL; } zend_execute_internal = old_execute_internal; zend_hash_clean(&ihandler_table); /* remove zend_open protection */ zend_stream_open_function = old_zend_stream_open; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ ================================================ FILE: header.c ================================================ /* +----------------------------------------------------------------------+ | Suhosin Version 1 | +----------------------------------------------------------------------+ | Copyright (c) 2006-2007 The Hardened-PHP Project | | Copyright (c) 2007-2015 SektionEins GmbH | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Stefan Esser | +----------------------------------------------------------------------+ */ /* $Id: header.c,v 1.1.1.1 2007-11-28 01:15:35 sesser Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" #include "ext/standard/url.h" #include "php_suhosin.h" #include "SAPI.h" #include "php_variables.h" static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL; char *suhosin_encrypt_single_cookie(char *name, int name_len, char *value, int value_len, char *key TSRMLS_DC) { char *buf, *buf2, *d, *d_url; int l; buf = estrndup(name, name_len); name_len = php_url_decode(buf, name_len); normalize_varname(buf); name_len = strlen(buf); if (SUHOSIN_G(cookie_plainlist)) { if (zend_hash_exists(SUHOSIN_G(cookie_plainlist), buf, name_len+1)) { encrypt_return_plain: efree(buf); return estrndup(value, value_len); } } else if (SUHOSIN_G(cookie_cryptlist)) { if (!zend_hash_exists(SUHOSIN_G(cookie_cryptlist), buf, name_len+1)) { goto encrypt_return_plain; } } buf2 = estrndup(value, value_len); value_len = php_url_decode(buf2, value_len); d = suhosin_encrypt_string(buf2, value_len, buf, name_len, key TSRMLS_CC); d_url = php_url_encode(d, strlen(d), &l); efree(d); efree(buf); efree(buf2); return d_url; } char *suhosin_decrypt_single_cookie(char *name, int name_len, char *value, int value_len, char *key, char **where TSRMLS_DC) { int o_name_len = name_len; char *buf, *buf2, *d, *d_url; int l; buf = estrndup(name, name_len); name_len = php_url_decode(buf, name_len); normalize_varname(buf); name_len = strlen(buf); if (SUHOSIN_G(cookie_plainlist)) { if (zend_hash_exists(SUHOSIN_G(cookie_plainlist), buf, name_len+1)) { decrypt_return_plain: efree(buf); memcpy(*where, name, o_name_len); *where += o_name_len; **where = '='; *where +=1; memcpy(*where, value, value_len); *where += value_len; return *where; } } else if (SUHOSIN_G(cookie_cryptlist)) { if (!zend_hash_exists(SUHOSIN_G(cookie_cryptlist), buf, name_len+1)) { goto decrypt_return_plain; } } buf2 = estrndup(value, value_len); value_len = php_url_decode(buf2, value_len); d = suhosin_decrypt_string(buf2, value_len, buf, name_len, key, &l, SUHOSIN_G(cookie_checkraddr) TSRMLS_CC); if (d == NULL) { goto skip_cookie; } d_url = php_url_encode(d, l, &l); efree(d); memcpy(*where, name, o_name_len); *where += o_name_len; **where = '=';*where += 1; memcpy(*where, d_url, l); *where += l; efree(d_url); skip_cookie: efree(buf); efree(buf2); return *where; } /* {{{ suhosin_cookie_decryptor */ char *suhosin_cookie_decryptor(TSRMLS_D) { char *raw_cookie = SG(request_info).cookie_data; char *decrypted, *ret, *var, *val, *tmp; int j; char cryptkey[33]; /* if (...deactivated...) { return estrdup(raw_cookie); } */ suhosin_generate_key(SUHOSIN_G(cookie_cryptkey), SUHOSIN_G(cookie_cryptua), SUHOSIN_G(cookie_cryptdocroot), SUHOSIN_G(cookie_cryptraddr), (char *)&cryptkey TSRMLS_CC); ret = decrypted = emalloc(strlen(raw_cookie)*4+1); raw_cookie = estrdup(raw_cookie); SUHOSIN_G(raw_cookie) = estrdup(raw_cookie); j = 0; tmp = raw_cookie; while (*tmp) { char *d_url;int varlen; while (*tmp == '\t' || *tmp == ' ') tmp++; var = tmp; while (*tmp && *tmp != ';' && *tmp != '=') tmp++; varlen = tmp-var; /*memcpy(decrypted, var, varlen); decrypted += varlen;*/ if (*tmp == 0) break; if (*tmp++ == ';') { *decrypted++ = ';'; continue; } /**decrypted++ = '=';*/ val = tmp; while (*tmp && *tmp != ';') tmp++; d_url = suhosin_decrypt_single_cookie(var, varlen, val, tmp-val, (char *)&cryptkey, &decrypted TSRMLS_CC); if (*tmp == ';') { *decrypted++ = ';'; } if (*tmp == 0) break; tmp++; } *decrypted++ = 0; ret = erealloc(ret, decrypted-ret); SUHOSIN_G(decrypted_cookie) = ret; efree(raw_cookie); return ret; } /* }}} */ /* {{{ suhosin_header_handler */ int suhosin_header_handler(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC) { int retval = SAPI_HEADER_ADD, i; char *tmp; if (op != SAPI_HEADER_ADD && op != SAPI_HEADER_REPLACE) { goto suhosin_skip_header_handling; } if (sapi_header && sapi_header->header) { tmp = sapi_header->header; for (i=0; iheader_len; i++, tmp++) { if (tmp[0] == 0) { char *fname = (char *)get_active_function_name(TSRMLS_C); if (!fname) { fname = "unknown"; } suhosin_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname); if (!SUHOSIN_G(simulation)) { sapi_header->header_len = i; } } if (SUHOSIN_G(allow_multiheader)) { continue; } else if ((tmp[0] == '\r' && (tmp[1] != '\n' || i == 0)) || (tmp[0] == '\n' && (i == sapi_header->header_len-1 || i == 0 || (tmp[1] != ' ' && tmp[1] != '\t')))) { char *fname = (char *)get_active_function_name(TSRMLS_C); if (!fname) { fname = "unknown"; } suhosin_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname); if (!SUHOSIN_G(simulation)) { sapi_header->header_len = i; tmp[0] = 0; } } } } /* Handle a potential cookie */ if (SUHOSIN_G(cookie_encrypt) && (strncasecmp("Set-Cookie:", sapi_header->header, sizeof("Set-Cookie:")-1) == 0)) { char *start, *end, *rend, *tmp; char *name, *value; int nlen, vlen, len, tlen; char cryptkey[33]; suhosin_generate_key(SUHOSIN_G(cookie_cryptkey), SUHOSIN_G(cookie_cryptua), SUHOSIN_G(cookie_cryptdocroot), SUHOSIN_G(cookie_cryptraddr), (char *)&cryptkey TSRMLS_CC); start = estrndup(sapi_header->header, sapi_header->header_len); rend = end = start + sapi_header->header_len; tmp = memchr(start, ';', end-start); if (tmp != NULL) { end = tmp; } tmp = start + sizeof("Set-Cookie:") - 1; while (tmp < end && tmp[0]==' ') { tmp++; } name = tmp; nlen = end-name; tmp = memchr(name, '=', nlen); if (tmp == NULL) { value = end; } else { value = tmp+1; nlen = tmp-name; } vlen = end-value; value = suhosin_encrypt_single_cookie(name, nlen, value, vlen, (char *)&cryptkey TSRMLS_CC); vlen = strlen(value); len = sizeof("Set-Cookie: ")-1 + nlen + 1 + vlen + rend-end; tmp = emalloc(len + 1); tlen = sprintf(tmp, "Set-Cookie: %.*s=%s", nlen,name, value); memcpy(tmp + tlen, end, rend-end); tmp[len] = 0; efree(sapi_header->header); efree(value); efree(start); sapi_header->header = tmp; sapi_header->header_len = len; } suhosin_skip_header_handling: /* If existing call the sapi header handler */ if (orig_header_handler) { retval = orig_header_handler(sapi_header, op, sapi_headers TSRMLS_CC); } return retval; } /* }}} */ /* {{{ suhosin_hook_header_handler */ void suhosin_hook_header_handler() { if (orig_header_handler == NULL) { orig_header_handler = sapi_module.header_handler; sapi_module.header_handler = suhosin_header_handler; } } /* }}} */ /* {{{ suhosin_unhook_header_handler */ void suhosin_unhook_header_handler() { sapi_module.header_handler = orig_header_handler; orig_header_handler = NULL; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ ================================================ FILE: ifilter.c ================================================ /* +----------------------------------------------------------------------+ | Suhosin Version 1 | +----------------------------------------------------------------------+ | Copyright (c) 2006-2007 The Hardened-PHP Project | | Copyright (c) 2007-2015 SektionEins GmbH | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Stefan Esser | +----------------------------------------------------------------------+ */ /* $Id: ifilter.c,v 1.1.1.1 2007-11-28 01:15:35 sesser Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" #include "php_suhosin.h" #include "php_variables.h" #include "ext/standard/php_var.h" static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL; #if !HAVE_STRNLEN static size_t strnlen(const char *s, size_t maxlen) { char *r = memchr(s, '\0', maxlen); return r ? r-s : maxlen; } #endif size_t suhosin_strnspn(const char *input, size_t n, const char *accept) { size_t count = 0; for (; *input != '\0' && count < n; input++, count++) { if (strchr(accept, *input) == NULL) break; } return count; } size_t suhosin_strncspn(const char *input, size_t n, const char *reject) { size_t count = 0; for (; *input != '\0' && count < n; input++, count++) { if (strchr(reject, *input) != NULL) break; } return count; } /* {{{ normalize_varname */ void normalize_varname(char *varname) { char *s=varname, *index=NULL, *indexend=NULL, *p; /* overjump leading space */ while (*s == ' ') { s++; } /* and remove it */ if (s != varname) { memmove(varname, s, strlen(s)+1); } for (p=varname; *p && *p != '['; p++) { switch(*p) { case ' ': case '.': *p='_'; break; } } /* find index */ index = strchr(varname, '['); if (index) { index++; s=index; } else { return; } /* done? */ while (index) { while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') { index++; } indexend = strchr(index, ']'); indexend = indexend ? indexend + 1 : index + strlen(index); if (s != index) { memmove(s, index, strlen(index)+1); s += indexend-index; } else { s = indexend; } if (*s == '[') { s++; index = s; } else { index = NULL; } } *s++='\0'; } /* }}} */ static unsigned char suhosin_hexchars[] = "0123456789ABCDEF"; static const char suhosin_is_dangerous_char[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* {{{ suhosin_server_encode */ static void suhosin_server_strip(HashTable *arr, char *key, int klen) { zval **tzval; unsigned char *s, *t; if (zend_hash_find(arr, key, klen, (void **) &tzval) == SUCCESS && Z_TYPE_PP(tzval) == IS_STRING) { s = t = (unsigned char *)Z_STRVAL_PP(tzval); for (; *t; t++) { if (suhosin_is_dangerous_char[*t]) { *t = '?'; } } Z_STRLEN_PP(tzval) = t-s; } } /* }}} */ /* {{{ suhosin_server_encode */ static void suhosin_server_encode(HashTable *arr, char *key, int klen) { zval **tzval; unsigned char *temp = NULL, *t, *newv, *n; int extra = 0; if (zend_hash_find(arr, key, klen, (void **) &tzval) == SUCCESS && Z_TYPE_PP(tzval) == IS_STRING) { temp = (unsigned char *)Z_STRVAL_PP(tzval); for (t = temp; *t; t++) { if (suhosin_is_dangerous_char[*t]) { extra += 2; } } /* no extra bytes required */ if (extra == 0) { return; } n = newv = emalloc(t - temp + 1 + extra); t = temp; for (t = temp; *t; t++, n++) { if (suhosin_is_dangerous_char[*t]) { *n++ = '%'; *n++ = suhosin_hexchars[*t >> 4]; *n = suhosin_hexchars[*t & 15]; } else { *n = *t; } } *n = 0; /* XXX: we leak memory here, but only for the duration of the request */ Z_STRVAL_PP(tzval) = (char *)newv; Z_STRLEN_PP(tzval) = n-newv; } } /* }}} */ /* {{{ suhosin_register_server_variables */ void suhosin_register_server_variables(zval *track_vars_array TSRMLS_DC) { HashTable *svars; int retval = 0, failure = 0; orig_register_server_variables(track_vars_array TSRMLS_CC); svars = Z_ARRVAL_P(track_vars_array); if (!SUHOSIN_G(simulation)) { retval = zend_hash_del(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS")); if (retval == SUCCESS) failure = 1; retval = zend_hash_del(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS")); if (retval == SUCCESS) failure = 1; retval = zend_hash_del(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS")); if (retval == SUCCESS) failure = 1; retval = zend_hash_del(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS")); if (retval == SUCCESS) failure = 1; retval = zend_hash_del(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS")); if (retval == SUCCESS) failure = 1; retval = zend_hash_del(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS")); if (retval == SUCCESS) failure = 1; retval = zend_hash_del(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES")); if (retval == SUCCESS) failure = 1; retval = zend_hash_del(svars, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA")); if (retval == SUCCESS) failure = 1; } else { retval = zend_hash_exists(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS")); retval+= zend_hash_exists(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS")); retval+= zend_hash_exists(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS")); retval+= zend_hash_exists(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS")); retval+= zend_hash_exists(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS")); retval+= zend_hash_exists(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS")); retval+= zend_hash_exists(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES")); retval+= zend_hash_exists(svars, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA")); if (retval > 0) failure = 1; } if (failure) { suhosin_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header"); } if (SUHOSIN_G(raw_cookie)) { zval *z; MAKE_STD_ZVAL(z); ZVAL_STRING(z, SUHOSIN_G(raw_cookie), 1); zend_hash_add(svars, "RAW_HTTP_COOKIE", sizeof("RAW_HTTP_COOKIE"), (void **)&z, sizeof(zval *), NULL); } if (SUHOSIN_G(decrypted_cookie)) { zval *z; MAKE_STD_ZVAL(z); ZVAL_STRING(z, SUHOSIN_G(decrypted_cookie), 0); zend_hash_update(svars, "HTTP_COOKIE", sizeof("HTTP_COOKIE"), (void **)&z, sizeof(zval *), NULL); SUHOSIN_G(decrypted_cookie) = NULL; } if (SUHOSIN_G(server_encode)) { /* suhosin_server_encode(svars, "argv", sizeof("argv")); */ suhosin_server_encode(svars, "REQUEST_URI", sizeof("REQUEST_URI")); suhosin_server_encode(svars, "QUERY_STRING", sizeof("QUERY_STRING")); } if (SUHOSIN_G(server_strip)) { suhosin_server_strip(svars, "PHP_SELF", sizeof("PHP_SELF")); suhosin_server_strip(svars, "PATH_INFO", sizeof("PATH_INFO")); suhosin_server_strip(svars, "PATH_TRANSLATED", sizeof("PATH_TRANSLATED")); suhosin_server_strip(svars, "HTTP_USER_AGENT", sizeof("HTTP_USER_AGENT")); } } /* }}} */ /* Old Input filter */ unsigned int (*old_input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC) = NULL; /* {{{ suhosin_input_filter_wrapper */ unsigned int suhosin_input_filter_wrapper(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC) { zend_bool already_scanned = SUHOSIN_G(already_scanned); SUHOSIN_G(already_scanned) = 0; if (SUHOSIN_G(do_not_scan)) { if (new_val_len) { *new_val_len = val_len; } return 1; } if (!already_scanned) { if (suhosin_input_filter(arg, var, val, val_len, new_val_len TSRMLS_CC)==0) { SUHOSIN_G(abort_request)=1; return 0; } if (new_val_len) { val_len = *new_val_len; } } if (old_input_filter) { return old_input_filter(arg, var, val, val_len, new_val_len TSRMLS_CC); } else { return 1; } } /* {{{ suhosin_input_filter */ unsigned int suhosin_input_filter(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC) { char *index, *prev_index = NULL; unsigned int var_len, total_len, depth = 0; /* Mark that we were called */ SUHOSIN_G(already_scanned) = 1; if (new_val_len) { *new_val_len = 0; } /* Drop this variable if the limit was reached */ switch (arg) { case PARSE_GET: SUHOSIN_G(att_get_vars)++; SUHOSIN_G(att_request_variables)++; if (SUHOSIN_G(no_more_get_variables)) { return 0; } break; case PARSE_POST: SUHOSIN_G(att_post_vars)++; SUHOSIN_G(att_request_variables)++; if (SUHOSIN_G(no_more_post_variables)) { return 0; } break; case PARSE_COOKIE: SUHOSIN_G(att_cookie_vars)++; SUHOSIN_G(att_request_variables)++; if (SUHOSIN_G(no_more_cookie_variables)) { return 0; } break; default: /* we do not want to protect parse_str() and friends */ if (new_val_len) { *new_val_len = val_len; } return 1; } /* Drop this variable if the limit is now reached */ switch (arg) { case PARSE_GET: if (SUHOSIN_G(max_get_vars) && SUHOSIN_G(max_get_vars) <= SUHOSIN_G(cur_get_vars)) { suhosin_log(S_VARS, "configured GET variable limit exceeded - dropped variable '%s' - all further GET variables are dropped", var); if (!SUHOSIN_G(simulation)) { SUHOSIN_G(no_more_get_variables) = 1; return 0; } } break; case PARSE_COOKIE: if (SUHOSIN_G(max_cookie_vars) && SUHOSIN_G(max_cookie_vars) <= SUHOSIN_G(cur_cookie_vars)) { suhosin_log(S_VARS, "configured COOKIE variable limit exceeded - dropped variable '%s' - all further COOKIE variables are dropped", var); if (!SUHOSIN_G(simulation)) { SUHOSIN_G(no_more_cookie_variables) = 1; return 0; } } break; case PARSE_POST: if (SUHOSIN_G(max_post_vars) && SUHOSIN_G(max_post_vars) <= SUHOSIN_G(cur_post_vars)) { suhosin_log(S_VARS, "configured POST variable limit exceeded - dropped variable '%s' - all further POST variables are dropped", var); if (!SUHOSIN_G(simulation)) { SUHOSIN_G(no_more_post_variables) = 1; return 0; } } break; } /* Drop this variable if it begins with whitespace which is disallowed */ if (isspace(*var)) { if (SUHOSIN_G(disallow_ws)) { suhosin_log(S_VARS, "request variable name begins with disallowed whitespace - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } switch (arg) { case PARSE_GET: if (SUHOSIN_G(disallow_get_ws)) { suhosin_log(S_VARS, "GET variable name begins with disallowed whitespace - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } break; case PARSE_POST: if (SUHOSIN_G(disallow_post_ws)) { suhosin_log(S_VARS, "POST variable name begins with disallowed whitespace - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } break; case PARSE_COOKIE: if (SUHOSIN_G(disallow_cookie_ws)) { suhosin_log(S_VARS, "COOKIE variable name begins with disallowed whitespace - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } break; } } /* Drop this variable if it exceeds the value length limit */ if (SUHOSIN_G(max_value_length) && SUHOSIN_G(max_value_length) < val_len) { suhosin_log(S_VARS, "configured request variable value length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } switch (arg) { case PARSE_GET: if (SUHOSIN_G(max_get_value_length) && SUHOSIN_G(max_get_value_length) < val_len) { suhosin_log(S_VARS, "configured GET variable value length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } break; case PARSE_COOKIE: if (SUHOSIN_G(max_cookie_value_length) && SUHOSIN_G(max_cookie_value_length) < val_len) { suhosin_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } break; case PARSE_POST: if (SUHOSIN_G(max_post_value_length) && SUHOSIN_G(max_post_value_length) < val_len) { suhosin_log(S_VARS, "configured POST variable value length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } break; } /* Normalize the variable name */ normalize_varname(var); /* Find length of variable name */ index = strchr(var, '['); total_len = strlen(var); var_len = index ? index-var : total_len; /* Drop this variable if it exceeds the varname/total length limit */ if (SUHOSIN_G(max_varname_length) && SUHOSIN_G(max_varname_length) < var_len) { suhosin_log(S_VARS, "configured request variable name length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } if (SUHOSIN_G(max_totalname_length) && SUHOSIN_G(max_totalname_length) < total_len) { suhosin_log(S_VARS, "configured request variable total name length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } switch (arg) { case PARSE_GET: if (SUHOSIN_G(max_get_name_length) && SUHOSIN_G(max_get_name_length) < var_len) { suhosin_log(S_VARS, "configured GET variable name length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } if (SUHOSIN_G(max_get_totalname_length) && SUHOSIN_G(max_get_totalname_length) < total_len) { suhosin_log(S_VARS, "configured GET variable total name length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } break; case PARSE_COOKIE: if (SUHOSIN_G(max_cookie_name_length) && SUHOSIN_G(max_cookie_name_length) < var_len) { suhosin_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } if (SUHOSIN_G(max_cookie_totalname_length) && SUHOSIN_G(max_cookie_totalname_length) < total_len) { suhosin_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } break; case PARSE_POST: if (SUHOSIN_G(max_post_name_length) && SUHOSIN_G(max_post_name_length) < var_len) { suhosin_log(S_VARS, "configured POST variable name length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } if (SUHOSIN_G(max_post_totalname_length) && SUHOSIN_G(max_post_totalname_length) < total_len) { suhosin_log(S_VARS, "configured POST variable total name length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } break; } /* Find out array depth */ while (index) { char *index_end; unsigned int index_length; /* overjump '[' */ index++; /* increase array depth */ depth++; index_end = strchr(index, ']'); if (index_end == NULL) { index_end = index+strlen(index); } index_length = index_end - index; /* max. array index length */ if (SUHOSIN_G(max_array_index_length) && SUHOSIN_G(max_array_index_length) < index_length) { suhosin_log(S_VARS, "configured request variable array index length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } switch (arg) { case PARSE_GET: if (SUHOSIN_G(max_get_array_index_length) && SUHOSIN_G(max_get_array_index_length) < index_length) { suhosin_log(S_VARS, "configured GET variable array index length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } break; case PARSE_COOKIE: if (SUHOSIN_G(max_cookie_array_index_length) && SUHOSIN_G(max_cookie_array_index_length) < index_length) { suhosin_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } break; case PARSE_POST: if (SUHOSIN_G(max_post_array_index_length) && SUHOSIN_G(max_post_array_index_length) < index_length) { suhosin_log(S_VARS, "configured POST variable array index length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } break; } /* index whitelist/blacklist */ if (SUHOSIN_G(array_index_whitelist) && *(SUHOSIN_G(array_index_whitelist))) { if (suhosin_strnspn(index, index_length, SUHOSIN_G(array_index_whitelist)) != index_length) { suhosin_log(S_VARS, "array index contains not whitelisted characters - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } } else if (SUHOSIN_G(array_index_blacklist) && *(SUHOSIN_G(array_index_blacklist))) { if (suhosin_strncspn(index, index_length, SUHOSIN_G(array_index_blacklist)) != index_length) { suhosin_log(S_VARS, "array index contains blacklisted characters - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } } index = strchr(index, '['); } /* Drop this variable if it exceeds the array depth limit */ if (SUHOSIN_G(max_array_depth) && SUHOSIN_G(max_array_depth) < depth) { suhosin_log(S_VARS, "configured request variable array depth limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } switch (arg) { case PARSE_GET: if (SUHOSIN_G(max_get_array_depth) && SUHOSIN_G(max_get_array_depth) < depth) { suhosin_log(S_VARS, "configured GET variable array depth limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } break; case PARSE_COOKIE: if (SUHOSIN_G(max_cookie_array_depth) && SUHOSIN_G(max_cookie_array_depth) < depth) { suhosin_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } break; case PARSE_POST: if (SUHOSIN_G(max_post_array_depth) && SUHOSIN_G(max_post_array_depth) < depth) { suhosin_log(S_VARS, "configured POST variable array depth limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } break; } /* Check if variable value is truncated by a \0 */ if (val && *val && val_len != strnlen(*val, val_len)) { if (SUHOSIN_G(disallow_nul)) { suhosin_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } switch (arg) { case PARSE_GET: if (SUHOSIN_G(disallow_get_nul)) { suhosin_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } break; case PARSE_COOKIE: if (SUHOSIN_G(disallow_cookie_nul)) { suhosin_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } break; case PARSE_POST: if (SUHOSIN_G(disallow_post_nul)) { suhosin_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { return 0; } } break; } } /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ /* This is to protect several silly scripts that do globalizing themself */ if (suhosin_is_protected_varname(var, var_len)) { suhosin_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE"); if (!SUHOSIN_G(simulation)) { return 0; } } /* Okay let PHP register this variable */ SUHOSIN_G(cur_request_variables)++; switch (arg) { case PARSE_GET: SUHOSIN_G(cur_get_vars)++; break; case PARSE_COOKIE: SUHOSIN_G(cur_cookie_vars)++; break; case PARSE_POST: SUHOSIN_G(cur_post_vars)++; break; } if (new_val_len) { *new_val_len = val_len; } return 1; } /* }}} */ /* {{{ suhosin_hook_register_server_variables */ void suhosin_hook_register_server_variables() { if (sapi_module.register_server_variables) { orig_register_server_variables = sapi_module.register_server_variables; sapi_module.register_server_variables = suhosin_register_server_variables; } } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ ================================================ FILE: log.c ================================================ /* +----------------------------------------------------------------------+ | Suhosin Version 1 | +----------------------------------------------------------------------+ | Copyright (c) 2006-2007 The Hardened-PHP Project | | Copyright (c) 2007-2015 SektionEins GmbH | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Stefan Esser | +----------------------------------------------------------------------+ */ /* $Id: log.c,v 1.1.1.1 2007-11-28 01:15:35 sesser Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_ini.h" #include "php_suhosin.h" #include #include "SAPI.h" #include "ext/standard/datetime.h" #include "ext/standard/flock_compat.h" #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_SYS_TIME_H #include #elif defined(PHP_WIN32) #include "win32/time.h" #endif #if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE) #undef AF_UNIX #endif #if defined(AF_UNIX) #include #endif #define SYSLOG_PATH "/dev/log" #include "snprintf.h" #ifdef PHP_WIN32 static HANDLE log_source = 0; #endif #include static char *loglevel2string(int loglevel) { switch (loglevel) { case S_FILES: return "FILES"; case S_INCLUDE: return "INCLUDE"; case S_MEMORY: return "MEMORY"; case S_MISC: return "MISC"; case S_MAIL: return "MAIL"; case S_SESSION: return "SESSION"; case S_SQL: return "SQL"; case S_EXECUTOR: return "EXECUTOR"; case S_VARS: return "VARS"; default: return "UNKNOWN"; } } static char *month_names[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; PHP_SUHOSIN_API void suhosin_log(int loglevel, char *fmt, ...) { int s, r, i=0, fd; long written, towrite; int getcaller=0; char *wbuf; struct timeval tv; time_t now; struct tm tm; #if defined(AF_UNIX) struct sockaddr_un saun; #endif #ifdef PHP_WIN32 LPTSTR strs[2]; unsigned short etype; DWORD evid; #endif char buf[5000] = {0}; char error[5000] = {0}; char *ip_address; char *fname; char *alertstring; int lineno = 0; va_list ap; TSRMLS_FETCH(); #if PHP_VERSION_ID >= 50500 getcaller = (loglevel & S_GETCALLER) == S_GETCALLER; #endif /* remove the S_GETCALLER flag */ loglevel = loglevel & ~S_GETCALLER; SDEBUG("(suhosin_log) loglevel: %d log_syslog: %ld - log_sapi: %ld - log_script: %ld", loglevel, SUHOSIN_G(log_syslog), SUHOSIN_G(log_sapi), SUHOSIN_G(log_script)); /* dump core if wanted */ if (SUHOSIN_G(coredump) && loglevel == S_MEMORY) { volatile unsigned int *x = 0; volatile int y = *x; } if (SUHOSIN_G(log_use_x_forwarded_for)) { ip_address = suhosin_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC); if (ip_address == NULL) { ip_address = "X-FORWARDED-FOR not set"; } } else { ip_address = suhosin_getenv("REMOTE_ADDR", 11 TSRMLS_CC); if (ip_address == NULL) { ip_address = "REMOTE_ADDR not set"; } } va_start(ap, fmt); ap_php_vsnprintf(error, sizeof(error), fmt, ap); va_end(ap); if (SUHOSIN_G(log_max_error_length) > 0 && SUHOSIN_G(log_max_error_length) < (sizeof(error) - 4)) { memcpy(error + SUHOSIN_G(log_max_error_length), "...", 4); } while (error[i]) { if (error[i] < 32) error[i] = '.'; i++; } if (SUHOSIN_G(simulation)) { alertstring = "ALERT-SIMULATION"; } else { alertstring = "ALERT"; } if (zend_is_executing(TSRMLS_C)) { zend_execute_data *exdata = EG(current_execute_data); if (exdata) { if (getcaller && exdata->prev_execute_data && exdata->prev_execute_data->opline && exdata->prev_execute_data->op_array) { lineno = exdata->prev_execute_data->opline->lineno; fname = (char *)exdata->prev_execute_data->op_array->filename; } else if (exdata->opline && exdata->op_array) { lineno = exdata->opline->lineno; fname = (char *)exdata->op_array->filename; } else { lineno = 0; fname = "[unknown filename]"; } } else { lineno = zend_get_executed_lineno(TSRMLS_C); fname = (char *)zend_get_executed_filename(TSRMLS_C); } ap_php_snprintf(buf, sizeof(buf), "%s - %s (attacker '%s', file '%s', line %u)", alertstring, error, ip_address, fname, lineno); } else { fname = suhosin_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC); if (fname==NULL) { fname = "unknown"; } ap_php_snprintf(buf, sizeof(buf), "%s - %s (attacker '%s', file '%s')", alertstring, error, ip_address, fname); } /* Syslog-Logging disabled? */ if (((SUHOSIN_G(log_syslog)|S_INTERNAL) & loglevel)==0) { goto log_file; } #if defined(AF_UNIX) ap_php_snprintf(error, sizeof(error), "<%u>suhosin[%u]: %s\n", (unsigned int)(SUHOSIN_G(log_syslog_facility)|SUHOSIN_G(log_syslog_priority)),getpid(),buf); s = socket(AF_UNIX, SOCK_DGRAM, 0); if (s == -1) { goto log_file; } memset(&saun, 0, sizeof(saun)); saun.sun_family = AF_UNIX; strcpy(saun.sun_path, SYSLOG_PATH); /*saun.sun_len = sizeof(saun);*/ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); if (r) { close(s); s = socket(AF_UNIX, SOCK_STREAM, 0); if (s == -1) { goto log_file; } memset(&saun, 0, sizeof(saun)); saun.sun_family = AF_UNIX; strcpy(saun.sun_path, SYSLOG_PATH); /*saun.sun_len = sizeof(saun);*/ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); if (r) { close(s); goto log_file; } } send(s, error, strlen(error), 0); close(s); #endif #ifdef PHP_WIN32 ap_php_snprintf(error, sizeof(error), "suhosin[%u]: %s", getpid(),buf); switch (SUHOSIN_G(log_syslog_priority)) { /* translate UNIX type into NT type */ case 1: /*LOG_ALERT:*/ etype = EVENTLOG_ERROR_TYPE; break; case 6: /*LOG_INFO:*/ etype = EVENTLOG_INFORMATION_TYPE; break; default: etype = EVENTLOG_WARNING_TYPE; } evid = loglevel; strs[0] = error; /* report the event */ if (log_source == NULL) { log_source = RegisterEventSource(NULL, "Suhosin-" SUHOSIN_EXT_VERSION); } ReportEvent(log_source, etype, (unsigned short) SUHOSIN_G(log_syslog_priority), evid, NULL, 1, 0, strs, NULL); #endif log_file: /* File-Logging disabled? */ if ((SUHOSIN_G(log_file) & loglevel)==0) { goto log_sapi; } if (!SUHOSIN_G(log_filename) || !SUHOSIN_G(log_filename)[0]) { goto log_sapi; } fd = open(SUHOSIN_G(log_filename), O_CREAT|O_APPEND|O_WRONLY, 0640); if (fd == -1) { suhosin_log(S_INTERNAL, "Unable to open logfile: %s", SUHOSIN_G(log_filename)); return; } if (SUHOSIN_G(log_file_time)) { gettimeofday(&tv, NULL); now = tv.tv_sec; php_localtime_r(&now, &tm); ap_php_snprintf(error, sizeof(error), "%s %2d %02d:%02d:%02d [%u] %s\n", month_names[tm.tm_mon], tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, getpid(),buf); } else { ap_php_snprintf(error, sizeof(error), "%s\n", buf); } towrite = strlen(error); wbuf = error; php_flock(fd, LOCK_EX); while (towrite > 0) { written = write(fd, wbuf, towrite); if (written < 0) { break; } towrite -= written; wbuf += written; } php_flock(fd, LOCK_UN); close(fd); log_sapi: /* SAPI Logging activated? */ SDEBUG("(suhosin_log) log_syslog: %ld - log_sapi: %ld - log_script: %ld - log_phpscript: %ld", SUHOSIN_G(log_syslog), SUHOSIN_G(log_sapi), SUHOSIN_G(log_script), SUHOSIN_G(log_phpscript)); if (((SUHOSIN_G(log_sapi)|S_INTERNAL) & loglevel)!=0) { sapi_module.log_message(buf TSRMLS_CC); } if ((SUHOSIN_G(log_stdout) & loglevel)!=0) { fprintf(stdout, "%s\n", buf); } /*log_script:*/ /* script logging activaed? */ if (((SUHOSIN_G(log_script) & loglevel)!=0) && SUHOSIN_G(log_scriptname)!=NULL) { char cmd[8192], *cmdpos, *bufpos; FILE *in; int space; struct stat st; char *sname = SUHOSIN_G(log_scriptname); while (isspace(*sname)) ++sname; if (*sname == 0) goto log_phpscript; if (VCWD_STAT(sname, &st) < 0) { suhosin_log(S_INTERNAL, "unable to find logging shell script %s - file dropped", sname); goto log_phpscript; } if (access(sname, X_OK|R_OK) < 0) { suhosin_log(S_INTERNAL, "logging shell script %s is not executable - file dropped", sname); goto log_phpscript; } /* TODO: clean up this code to calculate size of output dynamically */ ap_php_snprintf(cmd, sizeof(cmd) - 20, "%s %s \'", sname, loglevel2string(loglevel)); space = sizeof(cmd) - strlen(cmd) - 20; cmdpos = cmd + strlen(cmd); bufpos = buf; if (space <= 1) return; while (space > 2 && *bufpos) { if (*bufpos == '\'') { if (space<=5) break; *cmdpos++ = '\''; *cmdpos++ = '\\'; *cmdpos++ = '\''; *cmdpos++ = '\''; bufpos++; space-=4; } else { *cmdpos++ = *bufpos++; space--; } } *cmdpos++ = '\''; *cmdpos++ = ' '; *cmdpos++ = '2'; *cmdpos++ = '>'; *cmdpos++ = '&'; *cmdpos++ = '1'; *cmdpos = 0; if ((in=VCWD_POPEN(cmd, "r"))==NULL) { suhosin_log(S_INTERNAL, "Unable to execute logging shell script: %s", sname); goto log_phpscript; } /* read and forget the result */ while (1) { int readbytes = fread(cmd, 1, sizeof(cmd), in); if (readbytes<=0) { break; } if (strncmp(cmd, "sh: ", 4) == 0) { /* assume this is an error */ suhosin_log(S_INTERNAL, "Error while executing logging shell script: %s", sname); pclose(in); goto log_phpscript; } } pclose(in); } log_phpscript: if ((SUHOSIN_G(log_phpscript) & loglevel)!=0 && EG(in_execution) && SUHOSIN_G(log_phpscriptname) && SUHOSIN_G(log_phpscriptname)[0]) { zend_file_handle file_handle; zend_op_array *new_op_array; zval *result = NULL; long orig_execution_depth = SUHOSIN_G(execution_depth); char *orig_basedir = PG(open_basedir); char *phpscript = SUHOSIN_G(log_phpscriptname); SDEBUG("scriptname %s", SUHOSIN_G(log_phpscriptname)); if (zend_stream_open(phpscript, &file_handle TSRMLS_CC) == SUCCESS) { if (!file_handle.opened_path) { file_handle.opened_path = estrndup(phpscript, strlen(phpscript)); } new_op_array = zend_compile_file(&file_handle, ZEND_REQUIRE TSRMLS_CC); zend_destroy_file_handle(&file_handle TSRMLS_CC); if (new_op_array) { HashTable *active_symbol_table = EG(active_symbol_table); zval *zerror, *zerror_class; if (active_symbol_table == NULL) { active_symbol_table = &EG(symbol_table); } EG(return_value_ptr_ptr) = &result; EG(active_op_array) = new_op_array; MAKE_STD_ZVAL(zerror); MAKE_STD_ZVAL(zerror_class); ZVAL_STRING(zerror, buf, 1); ZVAL_LONG(zerror_class, loglevel); zend_hash_update(active_symbol_table, "SUHOSIN_ERROR", sizeof("SUHOSIN_ERROR"), (void **)&zerror, sizeof(zval *), NULL); zend_hash_update(active_symbol_table, "SUHOSIN_ERRORCLASS", sizeof("SUHOSIN_ERRORCLASS"), (void **)&zerror_class, sizeof(zval *), NULL); SUHOSIN_G(execution_depth) = 0; if (SUHOSIN_G(log_phpscript_is_safe)) { PG(open_basedir) = NULL; } zend_execute(new_op_array TSRMLS_CC); SUHOSIN_G(execution_depth) = orig_execution_depth; PG(open_basedir) = orig_basedir; destroy_op_array(new_op_array TSRMLS_CC); efree(new_op_array); if (!EG(exception)) { if (EG(return_value_ptr_ptr)) { zval_ptr_dtor(EG(return_value_ptr_ptr)); EG(return_value_ptr_ptr) = NULL; } } } else { suhosin_log(S_INTERNAL, "Unable to execute logging PHP script: %s", SUHOSIN_G(log_phpscriptname)); return; } } else { suhosin_log(S_INTERNAL, "Unable to execute logging PHP script: %s", SUHOSIN_G(log_phpscriptname)); return; } } } /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ ================================================ FILE: mbregex/COPYING.LIB ================================================ GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. ^L Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. ^L GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. ^L Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. ^L 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. ^L 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. ^L 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. ^L 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS ^L How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! ================================================ FILE: mbregex/mbregex.h ================================================ /* Definitions for data structures and routines for the regular expression library, version 0.12. Copyright (C) 1985,89,90,91,92,93,95,96,97,98 Free Software Foundation, Inc. This file is part of the GNU C Library. Its master source is NOT part of the C library, however. The master source lives in /gd/gnu/lib. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Multi-byte extension added May, 1993 by t^2 (Takahiro Tanimoto) Last change: May 21, 1993 by t^2 */ /* modified for Ruby by matz@netlab.co.jp */ #ifndef __MB_REGEXP_LIBRARY #define __MB_REGEXP_LIBRARY #include /* Define number of parens for which we record the beginnings and ends. This affects how much space the `struct re_registers' type takes up. */ #ifndef MBRE_NREGS #define MBRE_NREGS 10 #endif #define MBRE_BYTEWIDTH 8 #define MBRE_REG_MAX ((1< | +----------------------------------------------------------------------+ */ /* $Id: mbregex.h,v 1.1.1.1 2007-11-28 01:15:35 sesser Exp $ */ #if HAVE_MBREGEX #include "mbregex/mbregex.h" #endif ================================================ FILE: memory_limit.c ================================================ /* +----------------------------------------------------------------------+ | Suhosin Version 1 | +----------------------------------------------------------------------+ | Copyright (c) 2006-2007 The Hardened-PHP Project | | Copyright (c) 2007-2015 SektionEins GmbH | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Stefan Esser | +----------------------------------------------------------------------+ */ /* $Id: memory_limit.c,v 1.1.1.1 2007-11-28 01:15:35 sesser Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" #include "php_suhosin.h" /* {{{ PHP_INI_MH */ static PHP_INI_MH(suhosin_OnChangeMemoryLimit) { #if SIZEOF_LONG==8 long hard_memory_limit = 0x7fffffffffffffff; #elif SIZEOF_LONG==4 long hard_memory_limit = 0x7fffffff; #endif /* will produce a compile error or SIZEOF_LONG is not 4 or 8 */ if (stage == ZEND_INI_STAGE_RUNTIME) { if (SUHOSIN_G(memory_limit) > 0) { SUHOSIN_G(hard_memory_limit) = SUHOSIN_G(memory_limit); } else if (SUHOSIN_G(hard_memory_limit) == 0) { SUHOSIN_G(hard_memory_limit) = PG(memory_limit); } hard_memory_limit = SUHOSIN_G(hard_memory_limit); } else { SUHOSIN_G(hard_memory_limit) = 0; } if (new_value) { PG(memory_limit) = zend_atol(new_value, new_value_length); if (hard_memory_limit > 0) { if (PG(memory_limit) > hard_memory_limit) { suhosin_log(S_MISC, "script tried to increase memory_limit to %lu bytes which is above the allowed value", PG(memory_limit)); if (!SUHOSIN_G(simulation)) { PG(memory_limit) = hard_memory_limit; return FAILURE; } } else if (PG(memory_limit) < 0) { suhosin_log(S_MISC, "script tried to disable memory_limit by setting it to a negative value %ld bytes which is not allowed", PG(memory_limit)); if (!SUHOSIN_G(simulation)) { PG(memory_limit) = hard_memory_limit; return FAILURE; } } } } else { PG(memory_limit) = hard_memory_limit; } return zend_set_memory_limit(PG(memory_limit)); } /* }}} */ void suhosin_hook_memory_limit(TSRMLS_D) { zend_ini_entry *ini_entry; /* check if we are compiled against memory_limit */ if (zend_hash_find(EG(ini_directives), "memory_limit", sizeof("memory_limit"), (void **) &ini_entry)==FAILURE) { return; } /* replace OnUpdateMemoryLimit handler */ ini_entry->on_modify = suhosin_OnChangeMemoryLimit; } /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ ================================================ FILE: php_suhosin.h ================================================ /* +----------------------------------------------------------------------+ | Suhosin Version 1 | +----------------------------------------------------------------------+ | Copyright (c) 2006-2007 The Hardened-PHP Project | | Copyright (c) 2007-2015 SektionEins GmbH | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Stefan Esser | +----------------------------------------------------------------------+ */ /* $Id: php_suhosin.h,v 1.4 2008-01-13 22:50:37 sesser Exp $ */ #ifndef PHP_SUHOSIN_H #define PHP_SUHOSIN_H #define SUHOSIN_EXT_VERSION "0.9.39dev2" /*#define SUHOSIN_DEBUG*/ #define SUHOSIN_LOG "/tmp/suhosin_log.txt" #ifdef PHP_WIN32 #define SDEBUG #else #ifdef SUHOSIN_DEBUG #define SDEBUG(msg...) \ {FILE *f;f=fopen(SUHOSIN_LOG, "a+");if(f){fprintf(f,"[%u] ",getpid());fprintf(f, msg);fprintf(f,"\n");fclose(f);}} #else #define SDEBUG(msg...) #endif #endif #ifndef PHP_VERSION_ID #define PHP_VERSION_ID (PHP_MAJOR_VERSION * 10000 + PHP_MINOR_VERSION * 100 + PHP_RELEASE_VERSION) #endif extern zend_module_entry suhosin_module_entry; #define phpext_suhosin_ptr &suhosin_module_entry #ifdef PHP_WIN32 #define PHP_SUHOSIN_API __declspec(dllexport) #else #define PHP_SUHOSIN_API #endif #ifdef ZTS #include "TSRM.h" #endif /*#define STATIC static*/ #define STATIC #define BYTE unsigned char /* 8 bits */ #define WORD unsigned int /* 32 bits */ PHP_MINIT_FUNCTION(suhosin); PHP_MSHUTDOWN_FUNCTION(suhosin); PHP_RINIT_FUNCTION(suhosin); PHP_RSHUTDOWN_FUNCTION(suhosin); PHP_MINFO_FUNCTION(suhosin); #include "ext/standard/basic_functions.h" static inline int suhosin_is_protected_varname(char *var, int var_len) { switch (var_len) { case 18: if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname; break; case 17: if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname; break; case 16: if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname; if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname; break; case 15: if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname; break; case 14: if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname; break; case 13: if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname; if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname; break; case 8: if (memcmp(var, "_SESSION", 8)==0) goto protected_varname; if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname; break; case 7: if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname; if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname; if (memcmp(var, "_SERVER", 7)==0) goto protected_varname; break; case 6: if (memcmp(var, "_FILES", 6)==0) goto protected_varname; break; case 5: if (memcmp(var, "_POST", 5)==0) goto protected_varname; break; case 4: if (memcmp(var, "_ENV", 4)==0) goto protected_varname; if (memcmp(var, "_GET", 4)==0) goto protected_varname; break; } return 0; protected_varname: return 1; } ZEND_BEGIN_MODULE_GLOBALS(suhosin) zend_uint in_code_type; long execution_depth; zend_bool simulation; zend_bool stealth; zend_bool protectkey; zend_bool executor_allow_symlink; char *filter_action; char *sql_user_prefix; char *sql_user_postfix; char *sql_user_match; long sql_comment; long sql_opencomment; long sql_union; long sql_mselect; long max_execution_depth; zend_bool abort_request; long executor_include_max_traversal; zend_bool executor_include_allow_writable_files; HashTable *include_whitelist; HashTable *include_blacklist; HashTable *func_whitelist; HashTable *func_blacklist; HashTable *eval_whitelist; HashTable *eval_blacklist; zend_bool executor_disable_eval; zend_bool executor_disable_emod; /* request variables */ long max_request_variables; long cur_request_variables; long att_request_variables; long max_varname_length; long max_totalname_length; long max_value_length; long max_array_depth; long max_array_index_length; char* array_index_whitelist; char* array_index_blacklist; zend_bool disallow_nul; zend_bool disallow_ws; /* cookie variables */ long max_cookie_vars; long cur_cookie_vars; long att_cookie_vars; long max_cookie_name_length; long max_cookie_totalname_length; long max_cookie_value_length; long max_cookie_array_depth; long max_cookie_array_index_length; zend_bool disallow_cookie_nul; zend_bool disallow_cookie_ws; /* get variables */ long max_get_vars; long cur_get_vars; long att_get_vars; long max_get_name_length; long max_get_totalname_length; long max_get_value_length; long max_get_array_depth; long max_get_array_index_length; zend_bool disallow_get_nul; zend_bool disallow_get_ws; /* post variables */ long max_post_vars; long cur_post_vars; long att_post_vars; long max_post_name_length; long max_post_totalname_length; long max_post_value_length; long max_post_array_depth; long max_post_array_index_length; zend_bool disallow_post_nul; zend_bool disallow_post_ws; /* fileupload */ long upload_limit; long upload_max_newlines; long num_uploads; zend_bool upload_disallow_elf; zend_bool upload_disallow_binary; zend_bool upload_remove_binary; #ifdef SUHOSIN_EXPERIMENTAL zend_bool upload_allow_utf8; #endif char *upload_verification_script; zend_bool no_more_variables; zend_bool no_more_get_variables; zend_bool no_more_post_variables; zend_bool no_more_cookie_variables; zend_bool no_more_uploads; /* log */ zend_bool log_use_x_forwarded_for; long log_syslog; long log_syslog_facility; long log_syslog_priority; long log_script; long log_sapi; long log_stdout; char *log_scriptname; long log_phpscript; char *log_phpscriptname; zend_bool log_phpscript_is_safe; long log_file; char *log_filename; zend_bool log_file_time; long log_max_error_length; /* header handler */ zend_bool allow_multiheader; /* mailprotect */ long mailprotect; /* memory_limit */ long memory_limit; long hard_memory_limit; /* sqlprotect */ zend_bool sql_bailout_on_error; int (*old_php_body_write)(const char *str, unsigned int str_length TSRMLS_DC); /* session */ void *s_module; void *s_original_mod; int (*old_s_read)(void **mod_data, const char *key, char **val, int *vallen TSRMLS_DC); int (*old_s_write)(void **mod_data, const char *key, const char *val, const int vallen TSRMLS_DC); int (*old_s_destroy)(void **mod_data, const char *key TSRMLS_DC); BYTE fi[24],ri[24]; WORD fkey[120]; WORD rkey[120]; zend_bool session_encrypt; char* session_cryptkey; zend_bool session_cryptua; zend_bool session_cryptdocroot; long session_cryptraddr; long session_checkraddr; long session_max_id_length; char* decrypted_cookie; char* raw_cookie; zend_bool cookie_encrypt; char* cookie_cryptkey; zend_bool cookie_cryptua; zend_bool cookie_cryptdocroot; long cookie_cryptraddr; long cookie_checkraddr; HashTable *cookie_plainlist; HashTable *cookie_cryptlist; zend_bool coredump; zend_bool apc_bug_workaround; zend_bool already_scanned; zend_bool do_not_scan; zend_bool server_encode; zend_bool server_strip; zend_bool disable_display_errors; php_uint32 r_state[625]; php_uint32 *r_next; int r_left; zend_bool srand_ignore; zend_bool mt_srand_ignore; php_uint32 mt_state[625]; php_uint32 *mt_next; int mt_left; char *seedingkey; zend_bool reseed_every_request; zend_bool r_is_seeded; zend_bool mt_is_seeded; /* PERDIR Handling */ char *perdir; zend_bool log_perdir; zend_bool exec_perdir; zend_bool get_perdir; zend_bool post_perdir; zend_bool cookie_perdir; zend_bool request_perdir; zend_bool upload_perdir; zend_bool sql_perdir; zend_bool misc_perdir; ZEND_END_MODULE_GLOBALS(suhosin) #ifdef ZTS #define SUHOSIN_G(v) TSRMG(suhosin_globals_id, zend_suhosin_globals *, v) #else #define SUHOSIN_G(v) (suhosin_globals.v) #endif #ifndef ZEND_INI_STAGE_HTACCESS #define ZEND_INI_STAGE_HTACCESS (1<<5) #endif /* Error Constants */ #ifndef S_MEMORY #define S_MEMORY (1<<0L) #define S_MISC (1<<1L) #define S_VARS (1<<2L) #define S_FILES (1<<3L) #define S_INCLUDE (1<<4L) #define S_SQL (1<<5L) #define S_EXECUTOR (1<<6L) #define S_MAIL (1<<7L) #define S_SESSION (1<<8L) #define S_INTERNAL (1<<29L) #define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MAIL | S_SESSION | S_MISC | S_SQL | S_EXECUTOR) #endif #ifndef S_GETCALLER #define S_GETCALLER (1<<30L) #endif #define SUHOSIN_NORMAL 0 #define SUHOSIN_EVAL 1 #define SUHOSIN_FLAG_CREATED_BY_EVAL 1 #define SUHOSIN_FLAG_NOT_EVALED_CODE 2 ZEND_EXTERN_MODULE_GLOBALS(suhosin) static inline char * suhosin_str_tolower_dup(const char *source, unsigned int length) { register char *dup = estrndup(source, length); zend_str_tolower(dup, length); return dup; } /* functions */ PHP_SUHOSIN_API void suhosin_log(int loglevel, char *fmt, ...); char *suhosin_encrypt_string(char *str, int len, char *var, int vlen, char *key TSRMLS_DC); char *suhosin_decrypt_string(char *str, int padded_len, char *var, int vlen, char *key, int *orig_len, int check_ra TSRMLS_DC); char *suhosin_generate_key(char *key, zend_bool ua, zend_bool dr, long raddr, char *cryptkey TSRMLS_DC); char *suhosin_cookie_decryptor(TSRMLS_D); char *suhosin_getenv(char *name, size_t name_len TSRMLS_DC); void suhosin_hook_post_handlers(TSRMLS_D); void suhosin_unhook_post_handlers(TSRMLS_D); void suhosin_hook_register_server_variables(); void suhosin_hook_header_handler(); void suhosin_unhook_header_handler(); void suhosin_hook_session(TSRMLS_D); void suhosin_unhook_session(TSRMLS_D); void suhosin_hook_sha256(TSRMLS_D); #if defined(__OpenBSD__) && defined(SUHOSIN_EXPERIMENTAL) void suhosin_hook_pledge(TSRMLS_D); #endif void suhosin_hook_ex_imp(TSRMLS_D); void suhosin_hook_treat_data(); void suhosin_hook_memory_limit(TSRMLS_D); void suhosin_hook_execute(TSRMLS_D); void suhosin_unhook_execute(); void suhosin_aes_gentables(); void suhosin_aes_gkey(int nb,int nk,char *key TSRMLS_DC); void suhosin_aes_encrypt(char *buff TSRMLS_DC); void suhosin_aes_decrypt(char *buff TSRMLS_DC); unsigned int suhosin_input_filter(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC); unsigned int suhosin_input_filter_wrapper(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC); extern unsigned int (*old_input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC); void normalize_varname(char *varname); int suhosin_rfc1867_filter(unsigned int event, void *event_data, void **extra TSRMLS_DC); void suhosin_bailout(TSRMLS_D); size_t suhosin_strnspn(const char *input, size_t n, const char *accept); size_t suhosin_strncspn(const char *input, size_t n, const char *reject); #endif /* PHP_SUHOSIN_H */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ ================================================ FILE: pkg/build_deb.sh ================================================ #!/bin/bash _exit() { echo "[E] bye." exit 1 } yn_or_exit() { echo -n "[?] OK? [y] " read yn if [ "$yn" != "" -a "$yn" != "y" ]; then _exit fi } ## echo "[*] checking prerequisites..." for i in phpize make install fakeroot php-config dpkg-deb dpkg-architecture; do if [ "`which $i`" == "" ]; then echo "[E] please install '$i' and try again." _exit fi done ## HERE=`(cd $(dirname $0); pwd)` SUHOSIN=$HERE/.. ROOT=$HERE/tmp PKGDIR=$HERE PHP_EX=`php-config --extension-dir` eval `dpkg-architecture -l` VERSION=${SUHOSIN_VERSION:-$1} if [ "$VERSION" == "" ]; then echo "[E] please set SUHOSIN_VERSION, e.g. $0 0.9.36-1~dev1" _exit fi echo "[*] -----------------------------------------------------------" echo "[+] suhosin dir: $SUHOSIN" echo "[+] tmp dir: $ROOT" echo "[+] PHP extension dir: $PHP_EX" echo "[+] architecture: $DEB_HOST_ARCH" echo "[+] suhosin deb version: $VERSION" echo "[+] pkg output dir: $PKGDIR" yn_or_exit if [ ! -f "$SUHOSIN/modules/suhosin.so" ]; then echo "[+] Cannot find suhosin.so. I will try to build it." yn_or_exit eval `dpkg-buildflags --export=sh` if [ ! -f "$SUHOSIN/configure" ]; then echo "[*] phpize" cd $SUHOSIN phpize || _exit fi if [ ! -f "$SUHOSIN/Makefile" ]; then echo "[*] configure" cd $SUHOSIN ./configure --enable-suhosin-experimental fi echo "[*] make" make clean make -C $SUHOSIN || _exit fi ## echo "[*] deb" if [ -d "$ROOT" ]; then echo "[+] tmp dir $ROOT already exists. Delete?" yn_or_exit rm -rf $ROOT fi ## mkdir -p $ROOT/DEBIAN #echo "9" >$ROOT/DEBIAN/compat cat >$ROOT/DEBIAN/control < Homepage: http://www.suhosin.org/ Conflicts: php5-suhosin Depends: php5-common Description: advanced protection system for PHP5 This package provides a PHP hardening module. . Suhosin is an advanced protection system for PHP installations. It was designed to protect servers and users from known and unknown flaws in PHP applications and the PHP core. Suhosin comes in two independent parts, that can be used separately or in combination. The first part is a small patch against the PHP core, that implements a few low-level protections against bufferoverflows or format string vulnerabilities and the second part is a powerful PHP extension that implements all the other protections. . This Package provides the suhosin extension only. EOF echo "Architecture: $DEB_HOST_ARCH" >>$ROOT/DEBIAN/control echo "Version: $VERSION" >>$ROOT/DEBIAN/control echo "/etc/php5/mods-available/suhosin.ini" >$ROOT/DEBIAN/conffiles install -d -g 0 -o 0 $ROOT$PHP_EX install -g 0 -o 0 -m 644 $SUHOSIN/modules/suhosin.so $ROOT$PHP_EX install -d -g 0 -o 0 $ROOT/usr/share/doc/php5-suhosin-extension install -g 0 -o 0 -m 644 $SUHOSIN/suhosin.ini $ROOT/usr/share/doc/php5-suhosin-extension/suhosin.ini.example install -d -g 0 -o 0 $ROOT/etc/php5/mods-available ( echo '; priority=70' ; sed -e 's/^;extension=/extension=/' $SUHOSIN/suhosin.ini ) >$ROOT/etc/php5/mods-available/suhosin.ini chown root:root $ROOT/etc/php5/mods-available/suhosin.ini fakeroot dpkg-deb -b $ROOT $PKGDIR echo "[*] done." ================================================ FILE: pledge.c ================================================ /* +----------------------------------------------------------------------+ | Suhosin Version 1 | +----------------------------------------------------------------------+ | Copyright (c) 2006-2007 The Hardened-PHP Project | | Copyright (c) 2007-2015 SektionEins GmbH | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: David Carlier | +----------------------------------------------------------------------+ */ #if defined(__OpenBSD__) && defined(SUHOSIN_EXPERIMENTAL) #include #include #include "php.h" #include "ext/standard/info.h" #include "ext/standard/php_string.h" #include "ext/standard/php_smart_str.h" #include "pledge.h" const char *promises_defined[] = { "rpath", "wpath", "cpath", "tmppath", "inet", "flock", "unix", "dns", "sendfd", "recvfd", "proc", "exec", NULL }; /* {{{ proto string pledge(string str [, bool raw_output]) Wrapper around pledge call. Hence subsequent calls are allowed only to diminish the permissions. */ static PHP_FUNCTION(suhosin_pledge) { zval *promises, **current; HashTable *hashp; HashPosition hashpos; const char *pm; int ret; smart_str promisesbuf = { 0 }; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &promises) == FAILURE) { return; } /* PHP needs at least few functions from this promise */ smart_str_appends(&promisesbuf, "stdio"); hashp = Z_ARRVAL_P(promises); for (zend_hash_internal_pointer_reset_ex(hashp, &hashpos); zend_hash_get_current_data_ex(hashp, (void **)¤t, &hashpos) == SUCCESS; zend_hash_move_forward_ex(hashp, &hashpos)) { if (Z_TYPE_PP(current) != IS_STRING) continue; pm = NULL; const char **ptr = promises_defined; char *pp = Z_STRVAL_PP(current); char *p = php_trim(pp, strlen(pp), " ", 1, NULL, 3); while (*ptr) { if (strcmp(*ptr, p) == 0) { pm = *ptr; break; } ptr ++; } if (pm == NULL) { if (strcmp(p, "stdio") != 0) php_error_docref(NULL TSRMLS_CC, E_WARNING, "pledge: %s invalid or forbidden promise", p); efree(p); continue; } efree(p); smart_str_appends(&promisesbuf, " "); smart_str_appends(&promisesbuf, pm); } smart_str_0(&promisesbuf); ret = pledge(promisesbuf.c, NULL); smart_str_free(&promisesbuf); if (ret == -1) php_error_docref(NULL TSRMLS_CC, E_ERROR, "pledge failed: %s", strerror(errno)); RETVAL_LONG(ret); } /* }}} */ /* {{{ suhosin_pledge_functions[] */ static zend_function_entry suhosin_pledge_functions[] = { PHP_NAMED_FE(pledge, PHP_FN(suhosin_pledge), NULL) {NULL, NULL, NULL} }; /* }}} */ void suhosin_hook_pledge(TSRMLS_D) { zend_register_functions(NULL, suhosin_pledge_functions, NULL, MODULE_PERSISTENT TSRMLS_CC); } /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */ #endif ================================================ FILE: pledge.h ================================================ /* +----------------------------------------------------------------------+ | Suhosin Version 1 | +----------------------------------------------------------------------+ | Copyright (c) 2006-2007 The Hardened-PHP Project | | Copyright (c) 2007-2015 SektionEins GmbH | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: David Carlier | +----------------------------------------------------------------------+ */ /* $Id: pledge.h $ */ #ifndef PLEDGE_H #define PLEDGE_H #include "ext/standard/basic_functions.h" #ifdef __OpenBSD__ #endif #endif ================================================ FILE: post_handler.c ================================================ /* +----------------------------------------------------------------------+ | Suhosin Version 1 | +----------------------------------------------------------------------+ | Copyright (c) 2006-2007 The Hardened-PHP Project | | Copyright (c) 2007-2015 SektionEins GmbH | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Stefan Esser | +----------------------------------------------------------------------+ */ /* $Id: post_handler.c,v 1.1.1.1 2007-11-28 01:15:35 sesser Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_ini.h" #include "php_suhosin.h" #include "SAPI.h" #include "php_variables.h" #include "php_content_types.h" #include "suhosin_rfc1867.h" #include "ext/standard/url.h" #include "ext/standard/php_smart_str.h" #if defined(PHP_WIN32) && PHP_VERSION_ID >= 50600 #include "win32/php_inttypes.h" #endif SAPI_POST_HANDLER_FUNC(suhosin_rfc1867_post_handler); #if PHP_VERSION_ID < 50600 SAPI_POST_HANDLER_FUNC(suhosin_std_post_handler) { char *var, *val, *e, *s, *p; zval *array_ptr = (zval *) arg; long count = 0; if (SG(request_info).post_data == NULL) { return; } s = SG(request_info).post_data; e = s + SG(request_info).post_data_length; while (s < e && (p = memchr(s, '&', (e - s)))) { last_value: if ((val = memchr(s, '=', (p - s)))) { /* have a value */ unsigned int val_len, new_val_len; if (++count > PG(max_input_vars)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars)); return; } var = s; php_url_decode(var, (val - s)); val++; val_len = php_url_decode(val, (p - val)); val = estrndup(val, val_len); if (suhosin_input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) { if (sapi_module.input_filter(PARSE_POST, var, &val, new_val_len, &new_val_len TSRMLS_CC)) { php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); } } else { SUHOSIN_G(abort_request)=1; } efree(val); } s = p + 1; } if (s < e) { p = e; goto last_value; } } #else typedef struct post_var_data { smart_str str; char *ptr; char *end; uint64_t cnt; } post_var_data_t; static zend_bool add_post_var(zval *arr, post_var_data_t *var, zend_bool eof TSRMLS_DC) { char *ksep, *vsep, *val; size_t klen, vlen; /* FIXME: string-size_t */ unsigned int new_vlen; if (var->ptr >= var->end) { return 0; } vsep = memchr(var->ptr, '&', var->end - var->ptr); if (!vsep) { if (!eof) { return 0; } else { vsep = var->end; } } ksep = memchr(var->ptr, '=', vsep - var->ptr); if (ksep) { *ksep = '\0'; /* "foo=bar&" or "foo=&" */ klen = ksep - var->ptr; vlen = vsep - ++ksep; } else { ksep = ""; /* "foo&" */ klen = vsep - var->ptr; vlen = 0; } /* do not forget that value needs to be allocated for the filters */ val = estrndup(ksep, vlen); php_url_decode(var->ptr, klen); if (vlen) { vlen = php_url_decode(val, vlen); } if (suhosin_input_filter(PARSE_POST, var->ptr, &val, vlen, &new_vlen TSRMLS_CC)) { if (sapi_module.input_filter(PARSE_POST, var->ptr, &val, new_vlen, &new_vlen TSRMLS_CC)) { php_register_variable_safe(var->ptr, val, new_vlen, arr TSRMLS_CC); } } else { SUHOSIN_G(abort_request)=1; } efree(val); var->ptr = vsep + (vsep != var->end); return 1; } static inline int add_post_vars(zval *arr, post_var_data_t *vars, zend_bool eof TSRMLS_DC) { uint64_t max_vars = PG(max_input_vars); vars->ptr = vars->str.c; vars->end = vars->str.c + vars->str.len; while (add_post_var(arr, vars, eof TSRMLS_CC)) { if (++vars->cnt > max_vars) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %" PRIu64 ". " "To increase the limit change max_input_vars in php.ini.", max_vars); return FAILURE; } } if (!eof) { memmove(vars->str.c, vars->ptr, vars->str.len = vars->end - vars->ptr); } return SUCCESS; } SAPI_POST_HANDLER_FUNC(suhosin_std_post_handler) { zval *arr = (zval *) arg; php_stream *s = SG(request_info).request_body; post_var_data_t post_data; if (s && SUCCESS == php_stream_rewind(s)) { memset(&post_data, 0, sizeof(post_data)); while (!php_stream_eof(s)) { char buf[BUFSIZ] = {0}; size_t len = php_stream_read(s, buf, BUFSIZ); if (len && len != (size_t) -1) { smart_str_appendl(&post_data.str, buf, len); if (SUCCESS != add_post_vars(arr, &post_data, 0 TSRMLS_CC)) { if (post_data.str.c) { efree(post_data.str.c); } return; } } if (len != BUFSIZ){ break; } } add_post_vars(arr, &post_data, 1 TSRMLS_CC); if (post_data.str.c) { efree(post_data.str.c); } } } #endif static void suhosin_post_handler_modification(sapi_post_entry *spe) { char *content_type = estrndup(spe->content_type, spe->content_type_len); suhosin_log(S_VARS, "some extension replaces the POST handler for %s - Suhosin's protection might be incomplete", content_type); efree(content_type); } static int (*old_OnUpdate_mbstring_encoding_translation)(zend_ini_entry *entry, char *new_value, uint new_value_length, void *mh_arg1, void *mh_arg2, void *mh_arg3, int stage TSRMLS_DC) = NULL; /* {{{ static PHP_INI_MH(suhosin_OnUpdate_mbstring_encoding_translation) */ static PHP_INI_MH(suhosin_OnUpdate_mbstring_encoding_translation) { zend_bool *p; #ifndef ZTS char *base = (char *) mh_arg2; #else char *base; base = (char *) ts_resource(*((int *) mh_arg2)); #endif p = (zend_bool *) (base+(size_t) mh_arg1); if (new_value_length == 2 && strcasecmp("on", new_value) == 0) { *p = (zend_bool) 1; } else if (new_value_length == 3 && strcasecmp("yes", new_value) == 0) { *p = (zend_bool) 1; } else if (new_value_length == 4 && strcasecmp("true", new_value) == 0) { *p = (zend_bool) 1; } else { *p = (zend_bool) atoi(new_value); } if (*p) { suhosin_log(S_VARS, "Dynamic configuration (maybe a .htaccess file) tried to activate mbstring.encoding_translation which is incompatible with suhosin"); } return SUCCESS; } /* }}} */ /* {{{ php_post_entries[] */ static sapi_post_entry suhosin_post_entries[] = { { DEFAULT_POST_CONTENT_TYPE, sizeof(DEFAULT_POST_CONTENT_TYPE)-1, sapi_read_standard_form_data, suhosin_std_post_handler }, { MULTIPART_CONTENT_TYPE, sizeof(MULTIPART_CONTENT_TYPE)-1, NULL, suhosin_rfc1867_post_handler }, { NULL, 0, NULL, NULL } }; /* }}} */ void suhosin_hook_post_handlers(TSRMLS_D) { HashTable tempht; zend_ini_entry *ini_entry; sapi_unregister_post_entry(&suhosin_post_entries[0] TSRMLS_CC); sapi_unregister_post_entry(&suhosin_post_entries[1] TSRMLS_CC); sapi_register_post_entries(suhosin_post_entries TSRMLS_CC); /* we want to get notified if another extension deregisters the suhosin post handlers */ /* we need to tell suhosin patch that there is a new valid destructor */ /* therefore we have create HashTable that has this destructor */ zend_hash_init(&tempht, 0, NULL, (dtor_func_t)suhosin_post_handler_modification, 0); zend_hash_destroy(&tempht); /* And now we can overwrite the destructor for post entries */ SG(known_post_content_types).pDestructor = (dtor_func_t)suhosin_post_handler_modification; /* we have to stop mbstring from replacing our post handler */ if (zend_hash_find(EG(ini_directives), "mbstring.encoding_translation", sizeof("mbstring.encoding_translation"), (void **) &ini_entry) == FAILURE) { return; } /* replace OnUpdate_mbstring_encoding_translation handler */ old_OnUpdate_mbstring_encoding_translation = ini_entry->on_modify; ini_entry->on_modify = suhosin_OnUpdate_mbstring_encoding_translation; } void suhosin_unhook_post_handlers(TSRMLS_D) { zend_ini_entry *ini_entry; /* Restore to an empty destructor */ SG(known_post_content_types).pDestructor = NULL; /* Now restore the ini entry handler */ if (zend_hash_find(EG(ini_directives), "mbstring.encoding_translation", sizeof("mbstring.encoding_translation"), (void **) &ini_entry) == FAILURE) { return; } /* replace OnUpdate_mbstring_encoding_translation handler */ ini_entry->on_modify = old_OnUpdate_mbstring_encoding_translation; old_OnUpdate_mbstring_encoding_translation = NULL; } /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ ================================================ FILE: rfc1867_new.c ================================================ /* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2016 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Jani Taskinen | +----------------------------------------------------------------------+ */ /* $Id$ */ /* * This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/). * */ #include #include "php.h" #include "php_open_temporary_file.h" #include "zend_globals.h" #include "php_globals.h" #include "php_variables.h" #include "php_suhosin.h" #include "suhosin_rfc1867.h" #include "ext/standard/php_string.h" #include "ext/standard/php_smart_str.h" #if defined(PHP_WIN32) && !defined(HAVE_ATOLL) # define atoll(s) _atoi64(s) # define HAVE_ATOLL 1 #endif #define DEBUG_FILE_UPLOAD ZEND_DEBUG static int dummy_encoding_translation(TSRMLS_D) { return 0; } static char *php_ap_getword(const zend_encoding *encoding, char **line, char stop TSRMLS_DC); static char *php_ap_getword_conf(const zend_encoding *encoding, char *str TSRMLS_DC); static php_rfc1867_encoding_translation_t php_rfc1867_encoding_translation = dummy_encoding_translation; static php_rfc1867_get_detect_order_t php_rfc1867_get_detect_order = NULL; static php_rfc1867_set_input_encoding_t php_rfc1867_set_input_encoding = NULL; static php_rfc1867_getword_t php_rfc1867_getword = php_ap_getword; static php_rfc1867_getword_conf_t php_rfc1867_getword_conf = php_ap_getword_conf; static php_rfc1867_basename_t php_rfc1867_basename = NULL; static void safe_php_register_variable(char *var, char *strval, int val_len, zval *track_vars_array, zend_bool override_protection TSRMLS_DC); /* The longest property name we use in an uploaded file array */ #define MAX_SIZE_OF_INDEX sizeof("[tmp_name]") /* The longest anonymous name */ #define MAX_SIZE_ANONNAME 33 /* Errors */ #define UPLOAD_ERROR_OK 0 /* File upload successful */ #define UPLOAD_ERROR_A 1 /* Uploaded file exceeded upload_max_filesize */ #define UPLOAD_ERROR_B 2 /* Uploaded file exceeded MAX_FILE_SIZE */ #define UPLOAD_ERROR_C 3 /* Partially uploaded */ #define UPLOAD_ERROR_D 4 /* No file uploaded */ #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */ #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */ #define UPLOAD_ERROR_X 8 /* File upload stopped by extension */ static void normalize_protected_variable(char *varname TSRMLS_DC) /* {{{ */ { char *s = varname, *index = NULL, *indexend = NULL, *p; /* overjump leading space */ while (*s == ' ') { s++; } /* and remove it */ if (s != varname) { memmove(varname, s, strlen(s)+1); } for (p = varname; *p && *p != '['; p++) { switch(*p) { case ' ': case '.': *p = '_'; break; } } /* find index */ index = strchr(varname, '['); if (index) { index++; s = index; } else { return; } /* done? */ while (index) { while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') { index++; } indexend = strchr(index, ']'); indexend = indexend ? indexend + 1 : index + strlen(index); if (s != index) { memmove(s, index, strlen(index)+1); s += indexend-index; } else { s = indexend; } if (*s == '[') { s++; index = s; } else { index = NULL; } } *s = '\0'; } /* }}} */ static void add_protected_variable(char *varname TSRMLS_DC) /* {{{ */ { int dummy = 1; normalize_protected_variable(varname TSRMLS_CC); zend_hash_add(&PG(rfc1867_protected_variables), varname, strlen(varname)+1, &dummy, sizeof(int), NULL); } /* }}} */ static zend_bool is_protected_variable(char *varname TSRMLS_DC) /* {{{ */ { normalize_protected_variable(varname TSRMLS_CC); return zend_hash_exists(&PG(rfc1867_protected_variables), varname, strlen(varname)+1); } /* }}} */ static void safe_php_register_variable(char *var, char *strval, int val_len, zval *track_vars_array, zend_bool override_protection TSRMLS_DC) /* {{{ */ { if (override_protection || !is_protected_variable(var TSRMLS_CC)) { php_register_variable_safe(var, strval, val_len, track_vars_array TSRMLS_CC); } } /* }}} */ static void safe_php_register_variable_ex(char *var, zval *val, zval *track_vars_array, zend_bool override_protection TSRMLS_DC) /* {{{ */ { if (override_protection || !is_protected_variable(var TSRMLS_CC)) { php_register_variable_ex(var, val, track_vars_array TSRMLS_CC); } } /* }}} */ static void register_http_post_files_variable(char *strvar, char *val, zval *http_post_files, zend_bool override_protection TSRMLS_DC) /* {{{ */ { safe_php_register_variable(strvar, val, strlen(val), http_post_files, override_protection TSRMLS_CC); } /* }}} */ static void register_http_post_files_variable_ex(char *var, zval *val, zval *http_post_files, zend_bool override_protection TSRMLS_DC) /* {{{ */ { safe_php_register_variable_ex(var, val, http_post_files, override_protection TSRMLS_CC); } /* }}} */ static int unlink_filename(char **filename TSRMLS_DC) /* {{{ */ { VCWD_UNLINK(*filename); return 0; } /* }}} */ // void destroy_uploaded_files_hash(TSRMLS_D) /* {{{ */ // { // zend_hash_apply(SG(rfc1867_uploaded_files), (apply_func_t) unlink_filename TSRMLS_CC); // zend_hash_destroy(SG(rfc1867_uploaded_files)); // FREE_HASHTABLE(SG(rfc1867_uploaded_files)); // } /* }}} */ /* {{{ Following code is based on apache_multipart_buffer.c from libapreq-0.33 package. */ #define FILLUNIT (1024 * 5) typedef struct { /* read buffer */ char *buffer; char *buf_begin; int bufsize; int bytes_in_buffer; /* boundary info */ char *boundary; char *boundary_next; int boundary_next_len; const zend_encoding *input_encoding; const zend_encoding **detect_order; size_t detect_order_size; } multipart_buffer; typedef struct { char *key; char *value; } mime_header_entry; /* * Fill up the buffer with client data. * Returns number of bytes added to buffer. */ static int fill_buffer(multipart_buffer *self TSRMLS_DC) { int bytes_to_read, total_read = 0, actual_read = 0; /* shift the existing data if necessary */ if (self->bytes_in_buffer > 0 && self->buf_begin != self->buffer) { memmove(self->buffer, self->buf_begin, self->bytes_in_buffer); } self->buf_begin = self->buffer; /* calculate the free space in the buffer */ bytes_to_read = self->bufsize - self->bytes_in_buffer; /* read the required number of bytes */ while (bytes_to_read > 0) { char *buf = self->buffer + self->bytes_in_buffer; actual_read = sapi_module.read_post(buf, bytes_to_read TSRMLS_CC); /* update the buffer length */ if (actual_read > 0) { self->bytes_in_buffer += actual_read; SG(read_post_bytes) += actual_read; total_read += actual_read; bytes_to_read -= actual_read; } else { break; } } return total_read; } /* eof if we are out of bytes, or if we hit the final boundary */ static int multipart_buffer_eof(multipart_buffer *self TSRMLS_DC) { if ( (self->bytes_in_buffer == 0 && fill_buffer(self TSRMLS_CC) < 1) ) { return 1; } else { return 0; } } /* create new multipart_buffer structure */ static multipart_buffer *multipart_buffer_new(char *boundary, int boundary_len TSRMLS_DC) { multipart_buffer *self = (multipart_buffer *) ecalloc(1, sizeof(multipart_buffer)); int minsize = boundary_len + 6; if (minsize < FILLUNIT) minsize = FILLUNIT; self->buffer = (char *) ecalloc(1, minsize + 1); self->bufsize = minsize; spprintf(&self->boundary, 0, "--%s", boundary); self->boundary_next_len = spprintf(&self->boundary_next, 0, "\n--%s", boundary); self->buf_begin = self->buffer; self->bytes_in_buffer = 0; if (php_rfc1867_encoding_translation(TSRMLS_C)) { php_rfc1867_get_detect_order(&self->detect_order, &self->detect_order_size TSRMLS_CC); } else { self->detect_order = NULL; self->detect_order_size = 0; } self->input_encoding = NULL; return self; } /* * Gets the next CRLF terminated line from the input buffer. * If it doesn't find a CRLF, and the buffer isn't completely full, returns * NULL; otherwise, returns the beginning of the null-terminated line, * minus the CRLF. * * Note that we really just look for LF terminated lines. This works * around a bug in internet explorer for the macintosh which sends mime * boundaries that are only LF terminated when you use an image submit * button in a multipart/form-data form. */ static char *next_line(multipart_buffer *self) { /* look for LF in the data */ char* line = self->buf_begin; char* ptr = memchr(self->buf_begin, '\n', self->bytes_in_buffer); if (ptr) { /* LF found */ /* terminate the string, remove CRLF */ if ((ptr - line) > 0 && *(ptr-1) == '\r') { *(ptr-1) = 0; } else { *ptr = 0; } /* bump the pointer */ self->buf_begin = ptr + 1; self->bytes_in_buffer -= (self->buf_begin - line); } else { /* no LF found */ /* buffer isn't completely full, fail */ if (self->bytes_in_buffer < self->bufsize) { return NULL; } /* return entire buffer as a partial line */ line[self->bufsize] = 0; self->buf_begin = ptr; self->bytes_in_buffer = 0; } return line; } /* Returns the next CRLF terminated line from the client */ static char *get_line(multipart_buffer *self TSRMLS_DC) { char* ptr = next_line(self); if (!ptr) { fill_buffer(self TSRMLS_CC); ptr = next_line(self); } return ptr; } /* Free header entry */ static void php_free_hdr_entry(mime_header_entry *h) { if (h->key) { efree(h->key); } if (h->value) { efree(h->value); } } /* finds a boundary */ static int find_boundary(multipart_buffer *self, char *boundary TSRMLS_DC) { char *line; /* loop thru lines */ while( (line = get_line(self TSRMLS_CC)) ) { /* finished if we found the boundary */ if (!strcmp(line, boundary)) { return 1; } } /* didn't find the boundary */ return 0; } /* parse headers */ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header TSRMLS_DC) { char *line; mime_header_entry entry = {0}; smart_str buf_value = {0}; char *key = NULL; // mime_header_entry prev_entry = {0}; // int prev_len, cur_len; int newlines = 0; /* didn't find boundary, abort */ if (!find_boundary(self, self->boundary TSRMLS_CC)) { return 0; } /* get lines of text, or CRLF_CRLF */ while( (line = get_line(self TSRMLS_CC)) && line[0] != '\0' ) { /* add header to table */ char *value = NULL; if (php_rfc1867_encoding_translation(TSRMLS_C)) { self->input_encoding = zend_multibyte_encoding_detector((unsigned char *)line, strlen(line), self->detect_order, self->detect_order_size TSRMLS_CC); } /* space in the beginning means same header */ if (!isspace(line[0])) { value = strchr(line, ':'); } if (value) { if(buf_value.c && key) { /* new entry, add the old one to the list */ smart_str_0(&buf_value); entry.key = key; entry.value = buf_value.c; zend_llist_add_element(header, &entry); buf_value.c = NULL; key = NULL; } *value = '\0'; do { value++; } while(isspace(*value)); key = estrdup(line); smart_str_appends(&buf_value, value); newlines = 0; } else if (buf_value.c) { /* If no ':' on the line, add to previous line */ newlines++; if (newlines > SUHOSIN_G(upload_max_newlines)) { SUHOSIN_G(abort_request) = 1; suhosin_log(S_FILES, "configured maximum number of newlines in RFC1867 MIME headers limit exceeded - dropping rest of upload"); smart_str_free(&buf_value); return 0; } smart_str_appends(&buf_value, line); } else { continue; } } if(buf_value.c && key) { /* add the last one to the list */ smart_str_0(&buf_value); entry.key = key; entry.value = buf_value.c; zend_llist_add_element(header, &entry); } return 1; } static char *php_mime_get_hdr_value(zend_llist header, char *key) { mime_header_entry *entry; if (key == NULL) { return NULL; } entry = zend_llist_get_first(&header); while (entry) { if (!strcasecmp(entry->key, key)) { return entry->value; } entry = zend_llist_get_next(&header); } return NULL; } static char *php_ap_getword(const zend_encoding *encoding, char **line, char stop TSRMLS_DC) { char *pos = *line, quote; char *res; while (*pos && *pos != stop) { if ((quote = *pos) == '"' || quote == '\'') { ++pos; while (*pos && *pos != quote) { if (*pos == '\\' && pos[1] && pos[1] == quote) { pos += 2; } else { ++pos; } } if (*pos) { ++pos; } } else ++pos; } if (*pos == '\0') { res = estrdup(*line); *line += strlen(*line); return res; } res = estrndup(*line, pos - *line); while (*pos == stop) { ++pos; } *line = pos; return res; } static char *substring_conf(char *start, int len, char quote) { char *result = emalloc(len + 1); char *resp = result; int i; for (i = 0; i < len && start[i] != quote; ++i) { if (start[i] == '\\' && (start[i + 1] == '\\' || (quote && start[i + 1] == quote))) { *resp++ = start[++i]; } else { *resp++ = start[i]; } } *resp = '\0'; return result; } static char *php_ap_getword_conf(const zend_encoding *encoding, char *str TSRMLS_DC) { while (*str && isspace(*str)) { ++str; } if (!*str) { return estrdup(""); } if (*str == '"' || *str == '\'') { char quote = *str; str++; return substring_conf(str, strlen(str), quote); } else { char *strend = str; while (*strend && !isspace(*strend)) { ++strend; } return substring_conf(str, strend - str, 0); } } static char *php_ap_basename(const zend_encoding *encoding, char *path TSRMLS_DC) { char *s = strrchr(path, '\\'); char *s2 = strrchr(path, '/'); if (s && s2) { if (s > s2) { ++s; } else { s = ++s2; } return s; } else if (s) { return ++s; } else if (s2) { return ++s2; } return path; } /* * Search for a string in a fixed-length byte string. * If partial is true, partial matches are allowed at the end of the buffer. * Returns NULL if not found, or a pointer to the start of the first match. */ static void *php_ap_memstr(char *haystack, int haystacklen, char *needle, int needlen, int partial) { int len = haystacklen; char *ptr = haystack; /* iterate through first character matches */ while( (ptr = memchr(ptr, needle[0], len)) ) { /* calculate length after match */ len = haystacklen - (ptr - (char *)haystack); /* done if matches up to capacity of buffer */ if (memcmp(needle, ptr, needlen < len ? needlen : len) == 0 && (partial || len >= needlen)) { break; } /* next character */ ptr++; len--; } return ptr; } /* read until a boundary condition */ static int multipart_buffer_read(multipart_buffer *self, char *buf, int bytes, int *end TSRMLS_DC) { int len, max; char *bound; /* fill buffer if needed */ if (bytes > self->bytes_in_buffer) { fill_buffer(self TSRMLS_CC); } /* look for a potential boundary match, only read data up to that point */ if ((bound = php_ap_memstr(self->buf_begin, self->bytes_in_buffer, self->boundary_next, self->boundary_next_len, 1))) { max = bound - self->buf_begin; if (end && php_ap_memstr(self->buf_begin, self->bytes_in_buffer, self->boundary_next, self->boundary_next_len, 0)) { *end = 1; } } else { max = self->bytes_in_buffer; } /* maximum number of bytes we are reading */ len = max < bytes-1 ? max : bytes-1; /* if we read any data... */ if (len > 0) { /* copy the data */ memcpy(buf, self->buf_begin, len); buf[len] = 0; if (bound && len > 0 && buf[len-1] == '\r') { buf[--len] = 0; } /* update the buffer */ self->bytes_in_buffer -= len; self->buf_begin += len; } return len; } /* XXX: this is horrible memory-usage-wise, but we only expect to do this on small pieces of form data. */ static char *multipart_buffer_read_body(multipart_buffer *self, unsigned int *len TSRMLS_DC) { char buf[FILLUNIT], *out=NULL; int total_bytes=0, read_bytes=0; while((read_bytes = multipart_buffer_read(self, buf, sizeof(buf), NULL TSRMLS_CC))) { out = erealloc(out, total_bytes + read_bytes + 1); memcpy(out + total_bytes, buf, read_bytes); total_bytes += read_bytes; } if (out) { out[total_bytes] = '\0'; } *len = total_bytes; return out; } /* }}} */ /* * The combined READER/HANDLER * */ SAPI_POST_HANDLER_FUNC(suhosin_rfc1867_post_handler) /* {{{ */ { char *boundary, *s = NULL, *boundary_end = NULL, *start_arr = NULL, *array_index = NULL; char *temp_filename = NULL, *lbuf = NULL, *abuf = NULL; int boundary_len = 0, cancel_upload = 0, is_arr_upload = 0, array_len = 0; int64_t total_bytes = 0, max_file_size = 0; int skip_upload = 0, anonindex = 0, is_anonymous; zval *http_post_files = NULL; HashTable *uploaded_files = NULL; multipart_buffer *mbuff; zval *array_ptr = (zval *) arg; int fd = -1; zend_llist header; void *event_extra_data = NULL; unsigned int llen = 0; int upload_cnt = INI_INT("max_file_uploads"); const zend_encoding *internal_encoding = zend_multibyte_get_internal_encoding(TSRMLS_C); php_rfc1867_getword_t getword; php_rfc1867_getword_conf_t getword_conf; php_rfc1867_basename_t _basename; long count = 0; if (php_rfc1867_encoding_translation(TSRMLS_C) && internal_encoding) { getword = php_rfc1867_getword; getword_conf = php_rfc1867_getword_conf; _basename = php_rfc1867_basename; } else { getword = php_ap_getword; getword_conf = php_ap_getword_conf; _basename = php_ap_basename; } if (SG(post_max_size) > 0 && SG(request_info).content_length > SG(post_max_size)) { sapi_module.sapi_error(E_WARNING, "POST Content-Length of %ld bytes exceeds the limit of %ld bytes", SG(request_info).content_length, SG(post_max_size)); return; } /* Get the boundary */ boundary = strstr(content_type_dup, "boundary"); if (!boundary) { int content_type_len = strlen(content_type_dup); char *content_type_lcase = estrndup(content_type_dup, content_type_len); php_strtolower(content_type_lcase, content_type_len); boundary = strstr(content_type_lcase, "boundary"); if (boundary) { boundary = content_type_dup + (boundary - content_type_lcase); } efree(content_type_lcase); } if (!boundary || !(boundary = strchr(boundary, '='))) { sapi_module.sapi_error(E_WARNING, "Missing boundary in multipart/form-data POST data"); return; } boundary++; boundary_len = strlen(boundary); if (boundary[0] == '"') { boundary++; boundary_end = strchr(boundary, '"'); if (!boundary_end) { sapi_module.sapi_error(E_WARNING, "Invalid boundary in multipart/form-data POST data"); return; } } else { /* search for the end of the boundary */ boundary_end = strpbrk(boundary, ",;"); } if (boundary_end) { boundary_end[0] = '\0'; boundary_len = boundary_end-boundary; } /* Initialize the buffer */ if (!(mbuff = multipart_buffer_new(boundary, boundary_len TSRMLS_CC))) { sapi_module.sapi_error(E_WARNING, "Unable to initialize the input buffer"); return; } /* Initialize $_FILES[] */ zend_hash_init(&PG(rfc1867_protected_variables), 5, NULL, NULL, 0); ALLOC_HASHTABLE(uploaded_files); zend_hash_init(uploaded_files, 5, NULL, (dtor_func_t) free_estring, 0); SG(rfc1867_uploaded_files) = uploaded_files; ALLOC_ZVAL(http_post_files); array_init(http_post_files); INIT_PZVAL(http_post_files); PG(http_globals)[TRACK_VARS_FILES] = http_post_files; zend_llist_init(&header, sizeof(mime_header_entry), (llist_dtor_func_t) php_free_hdr_entry, 0); if (&suhosin_rfc1867_filter != NULL) { multipart_event_start event_start; event_start.content_length = SG(request_info).content_length; if (suhosin_rfc1867_filter(MULTIPART_EVENT_START, &event_start, &event_extra_data TSRMLS_CC) == FAILURE) { goto fileupload_done; } } while (!multipart_buffer_eof(mbuff TSRMLS_CC)) { char buff[FILLUNIT]; char *cd = NULL, *param = NULL, *filename = NULL, *tmp = NULL; size_t blen = 0, wlen = 0; off_t offset; zend_llist_clean(&header); if (!multipart_buffer_headers(mbuff, &header TSRMLS_CC)) { goto fileupload_done; } if ((cd = php_mime_get_hdr_value(header, "Content-Disposition"))) { char *pair = NULL; int end = 0; while (isspace(*cd)) { ++cd; } while (*cd && (pair = getword(mbuff->input_encoding, &cd, ';' TSRMLS_CC))) { char *key = NULL, *word = pair; while (isspace(*cd)) { ++cd; } if (strchr(pair, '=')) { key = getword(mbuff->input_encoding, &pair, '=' TSRMLS_CC); if (!strcasecmp(key, "name")) { if (param) { efree(param); } param = getword_conf(mbuff->input_encoding, pair TSRMLS_CC); if (mbuff->input_encoding && internal_encoding) { unsigned char *new_param; size_t new_param_len; if ((size_t)-1 != zend_multibyte_encoding_converter(&new_param, &new_param_len, (unsigned char *)param, strlen(param), internal_encoding, mbuff->input_encoding TSRMLS_CC)) { efree(param); param = (char *)new_param; } } } else if (!strcasecmp(key, "filename")) { if (filename) { efree(filename); } filename = getword_conf(mbuff->input_encoding, pair TSRMLS_CC); if (mbuff->input_encoding && internal_encoding) { unsigned char *new_filename; size_t new_filename_len; if ((size_t)-1 != zend_multibyte_encoding_converter(&new_filename, &new_filename_len, (unsigned char *)filename, strlen(filename), internal_encoding, mbuff->input_encoding TSRMLS_CC)) { efree(filename); filename = (char *)new_filename; } } } } if (key) { efree(key); } efree(word); } /* Normal form variable, safe to read all data into memory */ if (!filename && param) { unsigned int value_len; char *value = multipart_buffer_read_body(mbuff, &value_len TSRMLS_CC); unsigned int new_val_len; /* Dummy variable */ if (!value) { value = estrdup(""); value_len = 0; } if (mbuff->input_encoding && internal_encoding) { unsigned char *new_value; size_t new_value_len; if ((size_t)-1 != zend_multibyte_encoding_converter(&new_value, &new_value_len, (unsigned char *)value, value_len, internal_encoding, mbuff->input_encoding TSRMLS_CC)) { efree(value); value = (char *)new_value; value_len = new_value_len; } } if (suhosin_input_filter(PARSE_POST, param, &value, value_len, &new_val_len TSRMLS_CC) == 0) { SUHOSIN_G(abort_request)=1; efree(param); efree(value); continue; } if (++count <= PG(max_input_vars) && sapi_module.input_filter(PARSE_POST, param, &value, new_val_len, &new_val_len TSRMLS_CC)) { if (&suhosin_rfc1867_filter != NULL) { multipart_event_formdata event_formdata; size_t newlength = new_val_len; event_formdata.post_bytes_processed = SG(read_post_bytes); event_formdata.name = param; event_formdata.value = &value; event_formdata.length = new_val_len; event_formdata.newlength = &newlength; if (suhosin_rfc1867_filter(MULTIPART_EVENT_FORMDATA, &event_formdata, &event_extra_data TSRMLS_CC) == FAILURE) { efree(param); efree(value); continue; } new_val_len = newlength; } safe_php_register_variable(param, value, new_val_len, array_ptr, 0 TSRMLS_CC); } else { if (count == PG(max_input_vars) + 1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars)); } if (&suhosin_rfc1867_filter != NULL) { multipart_event_formdata event_formdata; event_formdata.post_bytes_processed = SG(read_post_bytes); event_formdata.name = param; event_formdata.value = &value; event_formdata.length = value_len; event_formdata.newlength = NULL; suhosin_rfc1867_filter(MULTIPART_EVENT_FORMDATA, &event_formdata, &event_extra_data TSRMLS_CC); } } if (!strcasecmp(param, "MAX_FILE_SIZE")) { #ifdef HAVE_ATOLL max_file_size = atoll(value); #else max_file_size = strtoll(value, NULL, 10); #endif } efree(param); efree(value); continue; } /* If file_uploads=off, skip the file part */ if (!PG(file_uploads)) { skip_upload = 1; } else if (upload_cnt <= 0) { skip_upload = 1; sapi_module.sapi_error(E_WARNING, "Maximum number of allowable file uploads has been exceeded"); } /* Return with an error if the posted data is garbled */ if (!param && !filename) { sapi_module.sapi_error(E_WARNING, "File Upload Mime headers garbled"); goto fileupload_done; } if (!param) { is_anonymous = 1; param = emalloc(MAX_SIZE_ANONNAME); snprintf(param, MAX_SIZE_ANONNAME, "%u", anonindex++); } else { is_anonymous = 0; } /* New Rule: never repair potential malicious user input */ if (!skip_upload) { long c = 0; tmp = param; while (*tmp) { if (*tmp == '[') { c++; } else if (*tmp == ']') { c--; if (tmp[1] && tmp[1] != '[') { skip_upload = 1; break; } } if (c < 0) { skip_upload = 1; break; } tmp++; } /* Brackets should always be closed */ if(c != 0) { skip_upload = 1; } } total_bytes = cancel_upload = 0; temp_filename = NULL; fd = -1; if (!skip_upload && (&suhosin_rfc1867_filter != NULL)) { multipart_event_file_start event_file_start; event_file_start.post_bytes_processed = SG(read_post_bytes); event_file_start.name = param; event_file_start.filename = &filename; if (suhosin_rfc1867_filter(MULTIPART_EVENT_FILE_START, &event_file_start, &event_extra_data TSRMLS_CC) == FAILURE) { temp_filename = ""; efree(param); efree(filename); continue; } } if (skip_upload) { efree(param); efree(filename); continue; } if (filename[0] == '\0') { #if DEBUG_FILE_UPLOAD sapi_module.sapi_error(E_NOTICE, "No file uploaded"); #endif cancel_upload = UPLOAD_ERROR_D; } offset = 0; end = 0; if (!cancel_upload) { /* only bother to open temp file if we have data */ blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC); #if DEBUG_FILE_UPLOAD if (blen > 0) { #else /* in non-debug mode we have no problem with 0-length files */ { #endif fd = php_open_temporary_fd_ex(PG(upload_tmp_dir), "php", &temp_filename, 1 TSRMLS_CC); upload_cnt--; if (fd == -1) { sapi_module.sapi_error(E_WARNING, "File upload error - unable to create a temporary file"); cancel_upload = UPLOAD_ERROR_E; } } } while (!cancel_upload && (blen > 0)) { if (&suhosin_rfc1867_filter != NULL) { multipart_event_file_data event_file_data; event_file_data.post_bytes_processed = SG(read_post_bytes); event_file_data.offset = offset; event_file_data.data = buff; event_file_data.length = blen; event_file_data.newlength = &blen; if (suhosin_rfc1867_filter(MULTIPART_EVENT_FILE_DATA, &event_file_data, &event_extra_data TSRMLS_CC) == FAILURE) { cancel_upload = UPLOAD_ERROR_X; continue; } } if (PG(upload_max_filesize) > 0 && (long)(total_bytes+blen) > PG(upload_max_filesize)) { #if DEBUG_FILE_UPLOAD sapi_module.sapi_error(E_NOTICE, "upload_max_filesize of %ld bytes exceeded - file [%s=%s] not saved", PG(upload_max_filesize), param, filename); #endif cancel_upload = UPLOAD_ERROR_A; } else if (max_file_size && ((long)(total_bytes+blen) > max_file_size)) { #if DEBUG_FILE_UPLOAD sapi_module.sapi_error(E_NOTICE, "MAX_FILE_SIZE of %ld bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename); #endif cancel_upload = UPLOAD_ERROR_B; } else if (blen > 0) { wlen = write(fd, buff, blen); if (wlen == -1) { /* write failed */ #if DEBUG_FILE_UPLOAD sapi_module.sapi_error(E_NOTICE, "write() failed - %s", strerror(errno)); #endif cancel_upload = UPLOAD_ERROR_F; } else if (wlen < blen) { #if DEBUG_FILE_UPLOAD sapi_module.sapi_error(E_NOTICE, "Only %d bytes were written, expected to write %d", wlen, blen); #endif cancel_upload = UPLOAD_ERROR_F; } else { total_bytes += wlen; } offset += wlen; } /* read data for next iteration */ blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC); } if (fd != -1) { /* may not be initialized if file could not be created */ close(fd); } if (!cancel_upload && !end) { #if DEBUG_FILE_UPLOAD sapi_module.sapi_error(E_NOTICE, "Missing mime boundary at the end of the data for file %s", filename[0] != '\0' ? filename : ""); #endif cancel_upload = UPLOAD_ERROR_C; } #if DEBUG_FILE_UPLOAD if (filename[0] != '\0' && total_bytes == 0 && !cancel_upload) { sapi_module.sapi_error(E_WARNING, "Uploaded file size 0 - file [%s=%s] not saved", param, filename); cancel_upload = 5; } #endif if (&suhosin_rfc1867_filter != NULL) { multipart_event_file_end event_file_end; event_file_end.post_bytes_processed = SG(read_post_bytes); event_file_end.temp_filename = temp_filename; event_file_end.cancel_upload = cancel_upload; if (suhosin_rfc1867_filter(MULTIPART_EVENT_FILE_END, &event_file_end, &event_extra_data TSRMLS_CC) == FAILURE) { cancel_upload = UPLOAD_ERROR_X; } } if (cancel_upload) { if (temp_filename) { if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */ unlink(temp_filename); } efree(temp_filename); } temp_filename = ""; } else { zend_hash_add(SG(rfc1867_uploaded_files), temp_filename, strlen(temp_filename) + 1, &temp_filename, sizeof(char *), NULL); } /* is_arr_upload is true when name of file upload field * ends in [.*] * start_arr is set to point to 1st [ */ is_arr_upload = (start_arr = strchr(param,'[')) && (param[strlen(param)-1] == ']'); if (is_arr_upload) { array_len = strlen(start_arr); if (array_index) { efree(array_index); } array_index = estrndup(start_arr + 1, array_len - 2); } /* Add $foo_name */ if (llen < strlen(param) + MAX_SIZE_OF_INDEX + 1) { llen = strlen(param); lbuf = (char *) safe_erealloc(lbuf, llen, 1, MAX_SIZE_OF_INDEX + 1); llen += MAX_SIZE_OF_INDEX + 1; } if (is_arr_upload) { if (abuf) efree(abuf); abuf = estrndup(param, strlen(param)-array_len); snprintf(lbuf, llen, "%s_name[%s]", abuf, array_index); } else { snprintf(lbuf, llen, "%s_name", param); } /* The \ check should technically be needed for win32 systems only where * it is a valid path separator. However, IE in all it's wisdom always sends * the full path of the file on the user's filesystem, which means that unless * the user does basename() they get a bogus file name. Until IE's user base drops * to nill or problem is fixed this code must remain enabled for all systems. */ s = _basename(internal_encoding, filename TSRMLS_CC); if (!s) { s = filename; } if (!is_anonymous) { safe_php_register_variable(lbuf, s, strlen(s), NULL, 0 TSRMLS_CC); } /* Add $foo[name] */ if (is_arr_upload) { snprintf(lbuf, llen, "%s[name][%s]", abuf, array_index); } else { snprintf(lbuf, llen, "%s[name]", param); } register_http_post_files_variable(lbuf, s, http_post_files, 0 TSRMLS_CC); efree(filename); s = NULL; /* Possible Content-Type: */ if (cancel_upload || !(cd = php_mime_get_hdr_value(header, "Content-Type"))) { cd = ""; } else { /* fix for Opera 6.01 */ s = strchr(cd, ';'); if (s != NULL) { *s = '\0'; } } /* Add $foo_type */ if (is_arr_upload) { snprintf(lbuf, llen, "%s_type[%s]", abuf, array_index); } else { snprintf(lbuf, llen, "%s_type", param); } if (!is_anonymous) { safe_php_register_variable(lbuf, cd, strlen(cd), NULL, 0 TSRMLS_CC); } /* Add $foo[type] */ if (is_arr_upload) { snprintf(lbuf, llen, "%s[type][%s]", abuf, array_index); } else { snprintf(lbuf, llen, "%s[type]", param); } register_http_post_files_variable(lbuf, cd, http_post_files, 0 TSRMLS_CC); /* Restore Content-Type Header */ if (s != NULL) { *s = ';'; } s = ""; { /* store temp_filename as-is (in case upload_tmp_dir * contains escapeable characters. escape only the variable name.) */ zval zfilename; /* Initialize variables */ add_protected_variable(param TSRMLS_CC); /* if param is of form xxx[.*] this will cut it to xxx */ if (!is_anonymous) { ZVAL_STRING(&zfilename, temp_filename, 1); safe_php_register_variable_ex(param, &zfilename, NULL, 1 TSRMLS_CC); } /* Add $foo[tmp_name] */ if (is_arr_upload) { snprintf(lbuf, llen, "%s[tmp_name][%s]", abuf, array_index); } else { snprintf(lbuf, llen, "%s[tmp_name]", param); } add_protected_variable(lbuf TSRMLS_CC); ZVAL_STRING(&zfilename, temp_filename, 1); register_http_post_files_variable_ex(lbuf, &zfilename, http_post_files, 1 TSRMLS_CC); } { zval file_size, error_type; int size_overflow = 0; char file_size_buf[65]; ZVAL_LONG(&error_type, cancel_upload); /* Add $foo[error] */ if (cancel_upload) { ZVAL_LONG(&file_size, 0); } else { if (total_bytes > LONG_MAX) { #ifdef PHP_WIN32 if (_i64toa_s(total_bytes, file_size_buf, 65, 10)) { file_size_buf[0] = '0'; file_size_buf[1] = '\0'; } #else { int __len = snprintf(file_size_buf, 65, "%lld", total_bytes); file_size_buf[__len] = '\0'; } #endif size_overflow = 1; } else { ZVAL_LONG(&file_size, total_bytes); } } if (is_arr_upload) { snprintf(lbuf, llen, "%s[error][%s]", abuf, array_index); } else { snprintf(lbuf, llen, "%s[error]", param); } register_http_post_files_variable_ex(lbuf, &error_type, http_post_files, 0 TSRMLS_CC); /* Add $foo_size */ if (is_arr_upload) { snprintf(lbuf, llen, "%s_size[%s]", abuf, array_index); } else { snprintf(lbuf, llen, "%s_size", param); } if (!is_anonymous) { if (size_overflow) { ZVAL_STRING(&file_size, file_size_buf, 1); } safe_php_register_variable_ex(lbuf, &file_size, NULL, size_overflow TSRMLS_CC); } /* Add $foo[size] */ if (is_arr_upload) { snprintf(lbuf, llen, "%s[size][%s]", abuf, array_index); } else { snprintf(lbuf, llen, "%s[size]", param); } if (size_overflow) { ZVAL_STRING(&file_size, file_size_buf, 1); } register_http_post_files_variable_ex(lbuf, &file_size, http_post_files, size_overflow TSRMLS_CC); } efree(param); } } fileupload_done: if (&suhosin_rfc1867_filter != NULL) { multipart_event_end event_end; event_end.post_bytes_processed = SG(read_post_bytes); suhosin_rfc1867_filter(MULTIPART_EVENT_END, &event_end, &event_extra_data TSRMLS_CC); } if (lbuf) efree(lbuf); if (abuf) efree(abuf); if (array_index) efree(array_index); zend_hash_destroy(&PG(rfc1867_protected_variables)); zend_llist_destroy(&header); if (mbuff->boundary_next) efree(mbuff->boundary_next); if (mbuff->boundary) efree(mbuff->boundary); if (mbuff->buffer) efree(mbuff->buffer); if (mbuff) efree(mbuff); } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */ ================================================ FILE: session.c ================================================ /* +----------------------------------------------------------------------+ | Suhosin Version 1 | +----------------------------------------------------------------------+ | Copyright (c) 2006-2007 The Hardened-PHP Project | | Copyright (c) 2007-2015 SektionEins GmbH | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Stefan Esser | | Ben Fuhrmannek | +----------------------------------------------------------------------+ */ /* $Id: session.c,v 1.1.1.1 2007-11-28 01:15:35 sesser Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "TSRM.h" #include "SAPI.h" #include "php_ini.h" #include "php_suhosin.h" #include "ext/standard/php_smart_str.h" #include "ext/standard/php_var.h" #include #if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH) # include "ext/hash/php_hash.h" #endif #ifdef HAVE_PHP_SESSION #include "ext/session/php_session.h" #ifdef ZTS static ts_rsrc_id session_globals_id = 0; #define SESSION_G(v) TSRMG(session_globals_id, php_ps_globals *, v) #else static php_ps_globals *session_globals = NULL; #define SESSION_G(v) (session_globals->v) #endif ps_serializer *(*suhosin_find_ps_serializer)(char *name TSRMLS_DC) = NULL; #define PS_DELIMITER '|' #define PS_UNDEF_MARKER '!' int suhosin_session_encode(char **newstr, int *newlen TSRMLS_DC) { smart_str buf = {0}; php_serialize_data_t var_hash; PS_ENCODE_VARS; PHP_VAR_SERIALIZE_INIT(var_hash); PS_ENCODE_LOOP( smart_str_appendl(&buf, key, key_length); if (key[0] == PS_UNDEF_MARKER || memchr(key, PS_DELIMITER, key_length)) { PHP_VAR_SERIALIZE_DESTROY(var_hash); smart_str_free(&buf); return FAILURE; } smart_str_appendc(&buf, PS_DELIMITER); php_var_serialize(&buf, struc, &var_hash TSRMLS_CC); } else { smart_str_appendc(&buf, PS_UNDEF_MARKER); smart_str_appendl(&buf, key, key_length); smart_str_appendc(&buf, PS_DELIMITER); ); if (newlen) { *newlen = buf.len; } smart_str_0(&buf); *newstr = buf.c; PHP_VAR_SERIALIZE_DESTROY(var_hash); return SUCCESS; } static void suhosin_send_cookie(TSRMLS_D) { int * session_send_cookie = &SESSION_G(send_cookie); char * base; zend_ini_entry *ini_entry; /* The following is requires to be 100% compatible to PHP versions where the hash extension is not available by default */ if (zend_hash_find(EG(ini_directives), "session.hash_bits_per_character", sizeof("session.hash_bits_per_character"), (void **) &ini_entry) == SUCCESS) { #ifndef ZTS base = (char *) ini_entry->mh_arg2; #else base = (char *) ts_resource(*((int *) ini_entry->mh_arg2)); #endif session_send_cookie = (int *) (base+(size_t) ini_entry->mh_arg1+sizeof(long)); } *session_send_cookie = 1; } static int (*old_OnUpdateSaveHandler)(zend_ini_entry *entry, char *new_value, uint new_value_length, void *mh_arg1, void *mh_arg2, void *mh_arg3, int stage TSRMLS_DC) = NULL; static int (*old_SessionRINIT)(INIT_FUNC_ARGS) = NULL; static int suhosin_hook_s_read(void **mod_data, const char *key, char **val, int *vallen TSRMLS_DC) { int r; int i;char *v,*KEY=(char *)key; /* protect session vars */ /* if (SESSION_G(http_session_vars) && SESSION_G(http_session_vars)->type == IS_ARRAY) { SESSION_G(http_session_vars)->refcount++; }*/ /* protect dumb session handlers */ if (key == NULL || !key[0] || (*mod_data == NULL && !SESSION_G(mod_user_implemented) )) { regenerate: SDEBUG("regenerating key is %s", key); KEY = SESSION_G(id) = SESSION_G(mod)->s_create_sid(&SESSION_G(mod_data), NULL TSRMLS_CC); suhosin_send_cookie(TSRMLS_C); } else if (strlen(key) > SUHOSIN_G(session_max_id_length)) { suhosin_log(S_SESSION, "session id ('%s') exceeds maximum length - regenerating", KEY); if (!SUHOSIN_G(simulation)) { goto regenerate; } } r = SUHOSIN_G(old_s_read)(mod_data, KEY, val, vallen TSRMLS_CC); if (r == SUCCESS && SUHOSIN_G(session_encrypt) && *vallen > 0) { char cryptkey[33]; SUHOSIN_G(do_not_scan) = 1; suhosin_generate_key(SUHOSIN_G(session_cryptkey), SUHOSIN_G(session_cryptua), SUHOSIN_G(session_cryptdocroot), SUHOSIN_G(session_cryptraddr), (char *)&cryptkey TSRMLS_CC); v = *val; i = *vallen; *val = suhosin_decrypt_string(v, i, "", 0, (char *)&cryptkey, vallen, SUHOSIN_G(session_checkraddr) TSRMLS_CC); SUHOSIN_G(do_not_scan) = 0; if (*val == NULL) { *val = estrndup("", 0); *vallen = 0; } efree(v); } return r; } static int suhosin_hook_s_write(void **mod_data, const char *key, const char *val, const int vallen TSRMLS_DC) { int r; /* int nullify = 0;*/ char *v = (char *)val; /* protect dumb session handlers */ if (key == NULL || !key[0] || val == NULL || strlen(key) > SUHOSIN_G(session_max_id_length) || (*mod_data == NULL && !SESSION_G(mod_user_implemented) )) { r = FAILURE; goto return_write; } r = vallen; if (r > 0 && SUHOSIN_G(session_encrypt)) { char cryptkey[33]; SUHOSIN_G(do_not_scan) = 1; suhosin_generate_key(SUHOSIN_G(session_cryptkey), SUHOSIN_G(session_cryptua), SUHOSIN_G(session_cryptdocroot), SUHOSIN_G(session_cryptraddr), (char *)&cryptkey TSRMLS_CC); v = suhosin_encrypt_string(v, vallen, "", 0, (char *)&cryptkey TSRMLS_CC); SUHOSIN_G(do_not_scan) = 0; r = strlen(v); } r = SUHOSIN_G(old_s_write)(mod_data, key, v, r TSRMLS_CC); return_write: /* protect session vars */ /* if (SESSION_G(http_session_vars) && SESSION_G(http_session_vars)->type == IS_ARRAY) { if (SESSION_G(http_session_vars)->refcount==1) { nullify = 1; } zval_ptr_dtor(&SESSION_G(http_session_vars)); if (nullify) { suhosin_log(S_SESSION, "possible session variables double free attack stopped"); SESSION_G(http_session_vars) = NULL; } }*/ return r; } static int suhosin_hook_s_destroy(void **mod_data, const char *key TSRMLS_DC) { int r; /* protect dumb session handlers */ if (key == NULL || !key[0] || strlen(key) > SUHOSIN_G(session_max_id_length) || (*mod_data == NULL && !SESSION_G(mod_user_implemented) )) { return FAILURE; } r = SUHOSIN_G(old_s_destroy)(mod_data, key TSRMLS_CC); return r; } static void suhosin_hook_session_module(TSRMLS_D) { ps_module *old_mod = SESSION_G(mod), *mod; if (old_mod == NULL || SUHOSIN_G(s_module) == old_mod) { return; } if (SUHOSIN_G(s_module) == NULL) { SUHOSIN_G(s_module) = mod = malloc(sizeof(ps_module)); if (mod == NULL) { return; } } SUHOSIN_G(s_original_mod) = old_mod; mod = SUHOSIN_G(s_module); memcpy(mod, old_mod, sizeof(ps_module)); SUHOSIN_G(old_s_read) = mod->s_read; mod->s_read = suhosin_hook_s_read; SUHOSIN_G(old_s_write) = mod->s_write; mod->s_write = suhosin_hook_s_write; SUHOSIN_G(old_s_destroy) = mod->s_destroy; mod->s_destroy = suhosin_hook_s_destroy; SESSION_G(mod) = mod; } static PHP_INI_MH(suhosin_OnUpdateSaveHandler) { int r; if (stage == PHP_INI_STAGE_RUNTIME && SESSION_G(session_status) == php_session_none && SUHOSIN_G(s_original_mod) && strcmp(new_value, "user") == 0 && strcmp(((ps_module*)SUHOSIN_G(s_original_mod))->s_name, "user") == 0) { return SUCCESS; } SESSION_G(mod) = SUHOSIN_G(s_original_mod); r = old_OnUpdateSaveHandler(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); suhosin_hook_session_module(TSRMLS_C); return r; } static int suhosin_hook_session_RINIT(INIT_FUNC_ARGS) { if (SESSION_G(mod) == NULL) { char *value = zend_ini_string("session.save_handler", sizeof("session.save_handler"), 0); if (value) { suhosin_OnUpdateSaveHandler(NULL, value, strlen(value), NULL, NULL, NULL, 0 TSRMLS_CC); } } return old_SessionRINIT(INIT_FUNC_ARGS_PASSTHRU); } void suhosin_hook_session(TSRMLS_D) { ps_serializer *serializer; zend_ini_entry *ini_entry; zend_module_entry *module; #ifdef ZTS ts_rsrc_id *ps_globals_id_ptr; #endif if (zend_hash_find(&module_registry, "session", sizeof("session"), (void**)&module) == FAILURE) { return; } /* retrieve globals from module entry struct if possible */ #ifdef ZTS if (session_globals_id == 0) { session_globals_id = *module->globals_id_ptr; } #else if (session_globals == NULL) { session_globals = module->globals_ptr; } #endif if (old_OnUpdateSaveHandler != NULL) { return; } /* hook request startup function of session module */ old_SessionRINIT = module->request_startup_func; module->request_startup_func = suhosin_hook_session_RINIT; /* retrieve pointer to session.save_handler ini entry */ if (zend_hash_find(EG(ini_directives), "session.save_handler", sizeof("session.save_handler"), (void **) &ini_entry) == FAILURE) { return; } SUHOSIN_G(s_module) = NULL; /* replace OnUpdateMemoryLimit handler */ old_OnUpdateSaveHandler = ini_entry->on_modify; ini_entry->on_modify = suhosin_OnUpdateSaveHandler; suhosin_hook_session_module(TSRMLS_C); /* Protect the PHP serializer from ! attacks */ serializer = (ps_serializer *) SESSION_G(serializer); if (serializer != NULL && strcmp(serializer->name, "php")==0) { serializer->encode = suhosin_session_encode; } /* increase session identifier entropy */ if (SESSION_G(entropy_length) == 0 || SESSION_G(entropy_file) == NULL) { #ifndef PHP_WIN32 /* ensure that /dev/urandom exists */ int fd = VCWD_OPEN("/dev/urandom", O_RDONLY); if (fd >= 0) { close(fd); SESSION_G(entropy_length) = 16; SESSION_G(entropy_file) = pestrdup("/dev/urandom", 1); } #endif } } void suhosin_unhook_session(TSRMLS_D) { if (old_OnUpdateSaveHandler != NULL) { zend_ini_entry *ini_entry; /* retrieve pointer to session.save_handler ini entry */ if (zend_hash_find(EG(ini_directives), "session.save_handler", sizeof("session.save_handler"), (void **) &ini_entry) == FAILURE) { return; } ini_entry->on_modify = old_OnUpdateSaveHandler; old_OnUpdateSaveHandler = NULL; } } #else /* HAVE_PHP_SESSION */ #warning BUILDING SUHOSIN WITHOUT SESSION SUPPORT void suhosin_hook_session(TSRMLS_D) { } void suhosin_unhook_session(TSRMLS_D) { } #endif /* HAVE_PHP_SESSION */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */ ================================================ FILE: sha256.c ================================================ /* +----------------------------------------------------------------------+ | Suhosin Version 1 | +----------------------------------------------------------------------+ | Copyright (c) 2006-2007 The Hardened-PHP Project | | Copyright (c) 2007-2015 SektionEins GmbH | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Stefan Esser | +----------------------------------------------------------------------+ */ /* $Id: sha256.c,v 1.1.1.1 2007-11-28 01:15:35 sesser Exp $ */ #include #include "php.h" /* This code is heavily based on the PHP md5/sha1 implementations */ #include "sha256.h" static void make_sha256_digest(char *sha256str, unsigned char *digest) { int i; for (i = 0; i < 32; i++) { sprintf(sha256str, "%02x", digest[i]); sha256str += 2; } *sha256str = '\0'; } /* {{{ proto string sha256(string str [, bool raw_output]) Calculate the sha256 hash of a string */ static PHP_FUNCTION(suhosin_sha256) { char *arg; int arg_len; zend_bool raw_output = 0; char sha256str[65]; suhosin_SHA256_CTX context; unsigned char digest[32]; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { return; } sha256str[0] = '\0'; suhosin_SHA256Init(&context); suhosin_SHA256Update(&context, (unsigned char *)arg, (unsigned int)arg_len); suhosin_SHA256Final(digest, &context); if (raw_output) { RETURN_STRINGL((char *)digest, 32, 1); } else { make_sha256_digest(sha256str, digest); RETVAL_STRING(sha256str, 1); } } /* }}} */ /* {{{ proto string sha256_file(string filename [, bool raw_output]) Calculate the sha256 hash of given filename */ static PHP_FUNCTION(suhosin_sha256_file) { char *arg; int arg_len; zend_bool raw_output = 0; char sha256str[65]; unsigned char buf[1024]; unsigned char digest[32]; suhosin_SHA256_CTX context; int n; FILE *fp; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { return; } if (php_check_open_basedir(arg TSRMLS_CC)) { RETURN_FALSE; } if ((fp = VCWD_FOPEN(arg, "rb")) == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open file"); RETURN_FALSE; } suhosin_SHA256Init(&context); while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) { suhosin_SHA256Update(&context, buf, n); } suhosin_SHA256Final(digest, &context); if (ferror(fp)) { fclose(fp); RETURN_FALSE; } fclose(fp); if (raw_output) { RETURN_STRINGL((char *)digest, 32, 1); } else { make_sha256_digest(sha256str, digest); RETVAL_STRING(sha256str, 1); } } /* }}} */ static void SHA256Transform(php_uint32[8], const unsigned char[64]); static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int); static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int); static unsigned char PADDING[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* F, G, H and I are basic SHA256 functions. */ #define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22)) #define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x)))) #define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25)) #define I(x, y, z) (((x) & (y)) | ((~x) & z)) /* ROTATE_RIGHT rotates x right n bits. */ #define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n)))) /* W[i] */ #define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) ) /* ROUND function of sha256 */ #define ROUND(a,b,c,d,e,f,g,h,w,k) { \ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \ (h) = F((a)) + G((a), (b), (c)) + t1; \ (d) += t1; \ } /* {{{ suhosin_SHA256Init * SHA256 initialization. Begins an SHA256 operation, writing a new context. */ void suhosin_SHA256Init(suhosin_SHA256_CTX * context) { context->count[0] = context->count[1] = 0; /* Load magic initialization constants. */ context->state[0] = 0x6a09e667; context->state[1] = 0xbb67ae85; context->state[2] = 0x3c6ef372; context->state[3] = 0xa54ff53a; context->state[4] = 0x510e527f; context->state[5] = 0x9b05688c; context->state[6] = 0x1f83d9ab; context->state[7] = 0x5be0cd19; } /* }}} */ /* {{{ suhosin_SHA256Update SHA256 block update operation. Continues an SHA256 message-digest operation, processing another message block, and updating the context. */ void suhosin_SHA256Update(suhosin_SHA256_CTX * context, const unsigned char *input, unsigned int inputLen) { unsigned int i, index, partLen; /* Compute number of bytes mod 64 */ index = (unsigned int) ((context->count[0] >> 3) & 0x3F); /* Update number of bits */ if ((context->count[0] += ((php_uint32) inputLen << 3)) < ((php_uint32) inputLen << 3)) context->count[1]++; context->count[1] += ((php_uint32) inputLen >> 29); partLen = 64 - index; /* Transform as many times as possible. */ if (inputLen >= partLen) { memcpy ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen); SHA256Transform(context->state, context->buffer); for (i = partLen; i + 63 < inputLen; i += 64) SHA256Transform(context->state, &input[i]); index = 0; } else i = 0; /* Buffer remaining input */ memcpy ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i); } /* }}} */ /* {{{ suhosin_SHA256Final SHA256 finalization. Ends an SHA256 message-digest operation, writing the the message digest and zeroizing the context. */ void suhosin_SHA256Final(unsigned char digest[32], suhosin_SHA256_CTX * context) { unsigned char bits[8]; unsigned int index, padLen; /* Save number of bits */ bits[7] = context->count[0] & 0xFF; bits[6] = (context->count[0] >> 8) & 0xFF; bits[5] = (context->count[0] >> 16) & 0xFF; bits[4] = (context->count[0] >> 24) & 0xFF; bits[3] = context->count[1] & 0xFF; bits[2] = (context->count[1] >> 8) & 0xFF; bits[1] = (context->count[1] >> 16) & 0xFF; bits[0] = (context->count[1] >> 24) & 0xFF; /* Pad out to 56 mod 64. */ index = (unsigned int) ((context->count[0] >> 3) & 0x3f); padLen = (index < 56) ? (56 - index) : (120 - index); suhosin_SHA256Update(context, PADDING, padLen); /* Append length (before padding) */ suhosin_SHA256Update(context, bits, 8); /* Store state in digest */ SHA256Encode(digest, context->state, 32); /* Zeroize sensitive information. */ memset((unsigned char*) context, 0, sizeof(*context)); } /* }}} */ /* {{{ SHA256Transform * SHA256 basic transformation. Transforms state based on block. */ static void SHA256Transform(state, block) php_uint32 state[8]; const unsigned char block[64]; { php_uint32 a = state[0], b = state[1], c = state[2]; php_uint32 d = state[3], e = state[4], f = state[5]; php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1; SHA256Decode(x, block, 64); ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98) ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491) ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf) ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5) ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b) ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1) ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4) ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5) ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98) ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01) ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be) ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3) ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74) ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe) ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7) ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174) ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1) ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786) ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6) ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc) ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f) ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa) ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc) ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da) ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152) ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d) ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8) ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7) ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3) ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147) ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351) ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967) ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85) ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138) ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc) ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13) ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354) ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb) ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e) ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85) ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1) ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b) ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70) ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3) ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819) ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624) ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585) ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070) ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116) ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08) ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c) ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5) ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3) ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a) ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f) ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3) ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee) ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f) ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814) ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208) ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa) ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb) ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7) ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2) state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e; state[5] += f; state[6] += g; state[7] += h; /* Zeroize sensitive information. */ memset((unsigned char*) x, 0, sizeof(x)); } /* }}} */ /* {{{ SHA256Encode Encodes input (php_uint32) into output (unsigned char). Assumes len is a multiple of 4. */ static void SHA256Encode(output, input, len) unsigned char *output; php_uint32 *input; unsigned int len; { unsigned int i, j; for (i = 0, j = 0; j < len; i++, j += 4) { output[j] = (unsigned char) ((input[i] >> 24) & 0xff); output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff); output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff); output[j + 3] = (unsigned char) (input[i] & 0xff); } } /* }}} */ /* {{{ SHA256Decode Decodes input (unsigned char) into output (php_uint32). Assumes len is a multiple of 4. */ static void SHA256Decode(output, input, len) php_uint32 *output; const unsigned char *input; unsigned int len; { unsigned int i, j; for (i = 0, j = 0; j < len; i++, j += 4) output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) | (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24); } /* }}} */ /* {{{ suhosin_sha256_functions[] */ static zend_function_entry suhosin_sha256_functions[] = { PHP_NAMED_FE(sha256, PHP_FN(suhosin_sha256), NULL) PHP_NAMED_FE(sha256_file, PHP_FN(suhosin_sha256_file), NULL) {NULL, NULL, NULL} }; /* }}} */ void suhosin_hook_sha256(TSRMLS_D) { /* check if we already have sha256 support */ if (zend_hash_exists(CG(function_table), "sha256", sizeof("sha256"))) { return; } /* add the sha256 functions */ zend_register_functions(NULL, suhosin_sha256_functions, NULL, MODULE_PERSISTENT TSRMLS_CC); } /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */ ================================================ FILE: sha256.h ================================================ /* +----------------------------------------------------------------------+ | Suhosin Version 1 | +----------------------------------------------------------------------+ | Copyright (c) 2006-2007 The Hardened-PHP Project | | Copyright (c) 2007-2015 SektionEins GmbH | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Stefan Esser | +----------------------------------------------------------------------+ */ /* $Id: sha256.h,v 1.1.1.1 2007-11-28 01:15:35 sesser Exp $ */ #ifndef SHA256_H #define SHA256_H #include "ext/standard/basic_functions.h" /* SHA1 context. */ typedef struct { php_uint32 state[8]; /* state (ABCD) */ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */ unsigned char buffer[64]; /* input buffer */ } suhosin_SHA256_CTX; void suhosin_SHA256Init(suhosin_SHA256_CTX *); void suhosin_SHA256Update(suhosin_SHA256_CTX *, const unsigned char *, unsigned int); void suhosin_SHA256Final(unsigned char[32], suhosin_SHA256_CTX *); #endif ================================================ FILE: suhosin.c ================================================ /* +----------------------------------------------------------------------+ | Suhosin Version 1 | +----------------------------------------------------------------------+ | Copyright (c) 2006-2007 The Hardened-PHP Project | | Copyright (c) 2007-2015 SektionEins GmbH | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Stefan Esser | +----------------------------------------------------------------------+ */ /* $Id: suhosin.c,v 1.2 2007-11-28 16:01:50 sesser Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_ini.h" #include "zend_extensions.h" #include "ext/standard/info.h" #include "php_syslog.h" #include "php_variables.h" #include "php_suhosin.h" #include "zend_llist.h" #include "zend_operators.h" #include "SAPI.h" #if PHP_VERSION_ID < 50500 #include "php_logos.h" #endif #include "suhosin_logo.h" #include "ext/standard/php_string.h" #include "ext/standard/url.h" #include "ext/standard/base64.h" ZEND_DECLARE_MODULE_GLOBALS(suhosin) static zend_llist_position lp = NULL; static int (*old_startup)(zend_extension *extension) = NULL; static zend_extension *ze = NULL; static int suhosin_module_startup(zend_extension *extension); static void suhosin_shutdown(zend_extension *extension); static void (*orig_op_array_ctor)(zend_op_array *op_array) = NULL; static void (*orig_op_array_dtor)(zend_op_array *op_array) = NULL; static void (*orig_module_shutdown)(zend_extension *extension) = NULL; static int (*orig_module_startup)(zend_extension *extension) = NULL; static void suhosin_op_array_ctor(zend_op_array *op_array); static void suhosin_op_array_dtor(zend_op_array *op_array); STATIC zend_extension suhosin_zend_extension_entry = { "Suhosin", SUHOSIN_EXT_VERSION, "SektionEins GmbH", "http://www.suhosin.org", "Copyright (c) 2007-2015", suhosin_module_startup, suhosin_shutdown, NULL, NULL, NULL, NULL, NULL, NULL, NULL, suhosin_op_array_ctor, suhosin_op_array_dtor, STANDARD_ZEND_EXTENSION_PROPERTIES }; static void suhosin_op_array_ctor(zend_op_array *op_array) { TSRMLS_FETCH(); if (suhosin_zend_extension_entry.resource_number != -1) { unsigned long suhosin_flags = 0; if (SUHOSIN_G(in_code_type) == SUHOSIN_EVAL) { suhosin_flags |= SUHOSIN_FLAG_CREATED_BY_EVAL; } op_array->reserved[suhosin_zend_extension_entry.resource_number] = (void *)suhosin_flags; } } static void suhosin_op_array_dtor(zend_op_array *op_array) { if (suhosin_zend_extension_entry.resource_number != -1) { op_array->reserved[suhosin_zend_extension_entry.resource_number] = NULL; } } /* Stealth Mode functions */ static void stealth_op_array_ctor(zend_op_array *op_array) { if (orig_op_array_ctor != NULL) { orig_op_array_ctor(op_array); } suhosin_op_array_ctor(op_array); } static void stealth_op_array_dtor(zend_op_array *op_array) { if (orig_op_array_dtor != NULL) { orig_op_array_dtor(op_array); } suhosin_op_array_dtor(op_array); } static int stealth_module_startup(zend_extension *extension) { int r = orig_module_startup == NULL ? SUCCESS : orig_module_startup(extension); suhosin_module_startup(extension); return r; } static void stealth_module_shutdown(zend_extension *extension) { if (orig_module_shutdown != NULL) { orig_module_shutdown(extension); } suhosin_shutdown(extension); } static int suhosin_module_startup(zend_extension *extension) { zend_module_entry *module_entry_ptr; int resid; TSRMLS_FETCH(); /* zend_register_module(&suhosin_module_entry TSRMLS_CC); */ if (zend_hash_find(&module_registry, "suhosin", sizeof("suhosin"), (void **)&module_entry_ptr)==SUCCESS) { if (extension) { extension->handle = module_entry_ptr->handle; } else { zend_extension ext; ext = suhosin_zend_extension_entry; ext.handle = module_entry_ptr->handle; /* zend_llist_add_element(&zend_extensions, &ext); extension = zend_llist_get_last(&zend_extensions); */ extension = &suhosin_zend_extension_entry; } module_entry_ptr->handle = NULL; } else { return FAILURE; } if (SUHOSIN_G(apc_bug_workaround)) { resid = zend_get_resource_handle(extension); } resid = zend_get_resource_handle(extension); suhosin_zend_extension_entry.resource_number = resid; suhosin_hook_treat_data(); suhosin_hook_post_handlers(TSRMLS_C); suhosin_aes_gentables(); suhosin_hook_register_server_variables(); suhosin_hook_header_handler(); suhosin_hook_execute(TSRMLS_C); suhosin_hook_session(TSRMLS_C); return SUCCESS; } static void suhosin_shutdown(zend_extension *extension) { TSRMLS_FETCH(); suhosin_unhook_execute(); suhosin_unhook_header_handler(); suhosin_unhook_post_handlers(TSRMLS_C); /* suhosin_unhook_session(); - enabling this causes compability problems */ if (ze != NULL) { ze->startup = orig_module_startup; ze->shutdown = orig_module_shutdown; ze->op_array_ctor = orig_op_array_ctor; ze->op_array_dtor = orig_op_array_dtor; } } static int suhosin_startup_wrapper(zend_extension *ext) { int res = SUCCESS; zend_extension *ex = &suhosin_zend_extension_entry; char *new_info; int new_info_length; TSRMLS_FETCH(); /* Ugly but working hack */ new_info_length = sizeof("%s\n with %s v%s, %s, by %s\n") + strlen(ext->author) + strlen(ex->name) + strlen(ex->version) + strlen(ex->copyright) + strlen(ex->author); new_info = (char *) malloc(new_info_length+1); sprintf(new_info, "%s\n with %s v%s, %s, by %s", ext->author, ex->name, ex->version, ex->copyright, ex->author); ext->author = new_info; ze->startup = old_startup; /* Stealth Mode */ orig_module_startup = ze->startup; orig_module_shutdown = ze->shutdown; orig_op_array_ctor = ze->op_array_ctor; orig_op_array_dtor = ze->op_array_dtor; /*if (SUHOSIN_G(stealth) != 0) {*/ ze->startup = stealth_module_startup; ze->shutdown = stealth_module_shutdown; ze->op_array_ctor = stealth_op_array_ctor; ze->op_array_dtor = stealth_op_array_dtor; /*}*/ if (old_startup != NULL) { res = old_startup(ext); } /* ex->name = NULL; ex->author = NULL; ex->copyright = NULL; ex->version = NULL;*/ /*zend_extensions.head=NULL;*/ suhosin_module_startup(NULL); return res; } /*static zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG };*/ #define PERDIR_CHECK(upper, lower) \ if (!SUHOSIN_G(lower ## _perdir) && stage == ZEND_INI_STAGE_HTACCESS) { \ return FAILURE; \ } #define LOG_PERDIR_CHECK() PERDIR_CHECK(LOG, log) #define EXEC_PERDIR_CHECK() PERDIR_CHECK(EXEC, exec) #define MISC_PERDIR_CHECK() PERDIR_CHECK(MISC, misc) #define GET_PERDIR_CHECK() PERDIR_CHECK(GET, get) #define POST_PERDIR_CHECK() PERDIR_CHECK(POST, post) #define COOKIE_PERDIR_CHECK() PERDIR_CHECK(COOKIE, cookie) #define REQUEST_PERDIR_CHECK() PERDIR_CHECK(REQUEST, request) #define UPLOAD_PERDIR_CHECK() PERDIR_CHECK(UPLOAD, upload) #define SQL_PERDIR_CHECK() PERDIR_CHECK(SQL, sql) #define ZEND_INI_MH_PASSTHRU entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC static ZEND_INI_MH(OnUpdateSuhosin_perdir) { char *tmp; if (SUHOSIN_G(perdir)) { pefree(SUHOSIN_G(perdir), 1); } SUHOSIN_G(perdir) = NULL; /* Initialize the perdir flags */ SUHOSIN_G(log_perdir) = 0; SUHOSIN_G(exec_perdir) = 0; SUHOSIN_G(get_perdir) = 0; SUHOSIN_G(cookie_perdir) = 0; SUHOSIN_G(post_perdir) = 0; SUHOSIN_G(request_perdir) = 0; SUHOSIN_G(sql_perdir) = 0; SUHOSIN_G(upload_perdir) = 0; SUHOSIN_G(misc_perdir) = 0; if (new_value == NULL) { return SUCCESS; } tmp = SUHOSIN_G(perdir) = pestrdup(new_value,1); /* trim the whitespace */ while (isspace(*tmp)) tmp++; /* should we deactivate perdir completely? */ if (*tmp == 0 || *tmp == '0') { return SUCCESS; } /* no deactivation so check the flags */ while (*tmp) { switch (*tmp) { case 'l': case 'L': SUHOSIN_G(log_perdir) = 1; break; case 'e': case 'E': SUHOSIN_G(exec_perdir) = 1; break; case 'g': case 'G': SUHOSIN_G(get_perdir) = 1; break; case 'c': case 'C': SUHOSIN_G(cookie_perdir) = 1; break; case 'p': case 'P': SUHOSIN_G(post_perdir) = 1; break; case 'r': case 'R': SUHOSIN_G(request_perdir) = 1; break; case 's': case 'S': SUHOSIN_G(sql_perdir) = 1; break; case 'u': case 'U': SUHOSIN_G(upload_perdir) = 1; break; case 'm': case 'M': SUHOSIN_G(misc_perdir) = 1; break; } tmp++; } return SUCCESS; } #define dohandler(handler, name, upper, lower) \ static ZEND_INI_MH(OnUpdate ## name ## handler) \ { \ PERDIR_CHECK(upper, lower) \ return OnUpdate ## handler (ZEND_INI_MH_PASSTHRU); \ } \ #define dohandlers(name, upper, lower) \ dohandler(Bool, name, upper, lower) \ dohandler(String, name, upper, lower) \ dohandler(Long, name, upper, lower) \ dohandlers(Log, LOG, log) dohandlers(Exec, EXEC, exec) dohandlers(Misc, MISC, misc) dohandlers(Get, GET, get) dohandlers(Post, POST, post) dohandlers(Cookie, COOKIE, cookie) dohandlers(Request, REQUEST, request) dohandlers(Upload, UPLOAD, upload) dohandlers(SQL, SQL, sql) static ZEND_INI_MH(OnUpdateSuhosin_log_syslog) { LOG_PERDIR_CHECK() if (!new_value) { SUHOSIN_G(log_syslog) = (S_ALL & ~S_SQL) | S_MEMORY; } else { if (is_numeric_string(new_value, strlen(new_value), NULL, NULL, 0) != IS_LONG) { SUHOSIN_G(log_syslog) = (S_ALL & ~S_SQL) | S_MEMORY; php_error_docref(NULL TSRMLS_CC, E_WARNING, "unknown constant in suhosin.log.syslog=%s", new_value); return FAILURE; } SUHOSIN_G(log_syslog) = atoi(new_value) | S_MEMORY; } return SUCCESS; } static ZEND_INI_MH(OnUpdateSuhosin_log_syslog_facility) { LOG_PERDIR_CHECK() if (!new_value) { SUHOSIN_G(log_syslog_facility) = LOG_USER; } else { SUHOSIN_G(log_syslog_facility) = atoi(new_value); } return SUCCESS; } static ZEND_INI_MH(OnUpdateSuhosin_log_syslog_priority) { LOG_PERDIR_CHECK() if (!new_value) { SUHOSIN_G(log_syslog_priority) = LOG_ALERT; } else { SUHOSIN_G(log_syslog_priority) = atoi(new_value); } return SUCCESS; } static ZEND_INI_MH(OnUpdateSuhosin_log_sapi) { LOG_PERDIR_CHECK() if (!new_value) { SUHOSIN_G(log_sapi) = (S_ALL & ~S_SQL); } else { if (is_numeric_string(new_value, strlen(new_value), NULL, NULL, 0) != IS_LONG) { SUHOSIN_G(log_sapi) = (S_ALL & ~S_SQL); php_error_docref(NULL TSRMLS_CC, E_WARNING, "unknown constant in suhosin.log.sapi=%s", new_value); return FAILURE; } SUHOSIN_G(log_sapi) = atoi(new_value); } return SUCCESS; } static ZEND_INI_MH(OnUpdateSuhosin_log_stdout) { LOG_PERDIR_CHECK() if (!new_value) { SUHOSIN_G(log_stdout) = (S_ALL & ~S_SQL); } else { if (is_numeric_string(new_value, strlen(new_value), NULL, NULL, 0) != IS_LONG) { SUHOSIN_G(log_stdout) = (S_ALL & ~S_SQL); php_error_docref(NULL TSRMLS_CC, E_WARNING, "unknown constant in suhosin.log.stdout=%s", new_value); return FAILURE; } SUHOSIN_G(log_stdout) = atoi(new_value); } return SUCCESS; } static ZEND_INI_MH(OnUpdateSuhosin_log_script) { LOG_PERDIR_CHECK() if (!new_value) { SUHOSIN_G(log_script) = S_ALL & ~S_MEMORY; } else { if (is_numeric_string(new_value, strlen(new_value), NULL, NULL, 0) != IS_LONG) { SUHOSIN_G(log_script) = S_ALL & ~S_MEMORY; php_error_docref(NULL TSRMLS_CC, E_WARNING, "unknown constant in suhosin.log.script=%s", new_value); return FAILURE; } SUHOSIN_G(log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL); } return SUCCESS; } static ZEND_INI_MH(OnUpdateSuhosin_log_scriptname) { LOG_PERDIR_CHECK() if (SUHOSIN_G(log_scriptname)) { pefree(SUHOSIN_G(log_scriptname),1); } SUHOSIN_G(log_scriptname) = NULL; if (new_value) { SUHOSIN_G(log_scriptname) = pestrdup(new_value,1); } return SUCCESS; } static ZEND_INI_MH(OnUpdateSuhosin_log_phpscript) { LOG_PERDIR_CHECK() if (!new_value) { SUHOSIN_G(log_phpscript) = S_ALL & ~S_MEMORY; } else { if (is_numeric_string(new_value, strlen(new_value), NULL, NULL, 0) != IS_LONG) { SUHOSIN_G(log_phpscript) = S_ALL & ~S_MEMORY; php_error_docref(NULL TSRMLS_CC, E_WARNING, "unknown constant in suhosin.log.phpscript=%s", new_value); return FAILURE; } SUHOSIN_G(log_phpscript) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL); } return SUCCESS; } static ZEND_INI_MH(OnUpdateSuhosin_log_file) { LOG_PERDIR_CHECK() if (!new_value) { SUHOSIN_G(log_file) = S_ALL & ~S_MEMORY; } else { if (is_numeric_string(new_value, strlen(new_value), NULL, NULL, 0) != IS_LONG) { SUHOSIN_G(log_file) = S_ALL & ~S_MEMORY; php_error_docref(NULL TSRMLS_CC, E_WARNING, "unknown constant in suhosin.log.file=%s", new_value); return FAILURE; } SUHOSIN_G(log_file) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL); } return SUCCESS; } static void parse_list(HashTable **ht, char *list, zend_bool lc) { char *s = NULL, *e, *val; unsigned long dummy = 1; if (list == NULL) { list_destroy: if (*ht) { zend_hash_destroy(*ht); pefree(*ht, 1); } *ht = NULL; return; } while (*list == ' ' || *list == '\t') list++; if (*list == 0) { goto list_destroy; } *ht = pemalloc(sizeof(HashTable), 1); zend_hash_init(*ht, 5, NULL, NULL, 1); if (lc) { val = suhosin_str_tolower_dup(list, strlen(list)); } else { val = estrndup(list, strlen(list)); } e = val; while (*e) { switch (*e) { case ' ': case ',': if (s) { *e = '\0'; zend_hash_add(*ht, s, e-s+1, &dummy, sizeof(unsigned long), NULL); s = NULL; } break; default: if (!s) { s = e; } break; } e++; } if (s) { zend_hash_add(*ht, s, e-s+1, &dummy, sizeof(unsigned long), NULL); } efree(val); } static ZEND_INI_MH(OnUpdate_include_blacklist) { EXEC_PERDIR_CHECK() parse_list(&SUHOSIN_G(include_blacklist), new_value, 1); return SUCCESS; } static ZEND_INI_MH(OnUpdate_include_whitelist) { EXEC_PERDIR_CHECK() parse_list(&SUHOSIN_G(include_whitelist), new_value, 1); return SUCCESS; } static ZEND_INI_MH(OnUpdate_func_blacklist) { EXEC_PERDIR_CHECK() parse_list(&SUHOSIN_G(func_blacklist), new_value, 1); return SUCCESS; } static ZEND_INI_MH(OnUpdate_func_whitelist) { EXEC_PERDIR_CHECK() parse_list(&SUHOSIN_G(func_whitelist), new_value, 1); return SUCCESS; } static ZEND_INI_MH(OnUpdate_eval_blacklist) { EXEC_PERDIR_CHECK() parse_list(&SUHOSIN_G(eval_blacklist), new_value, 1); return SUCCESS; } static ZEND_INI_MH(OnUpdate_eval_whitelist) { EXEC_PERDIR_CHECK() parse_list(&SUHOSIN_G(eval_whitelist), new_value, 1); return SUCCESS; } static ZEND_INI_MH(OnUpdate_cookie_cryptlist) { COOKIE_PERDIR_CHECK() parse_list(&SUHOSIN_G(cookie_cryptlist), new_value, 0); return SUCCESS; } static ZEND_INI_MH(OnUpdate_cookie_plainlist) { COOKIE_PERDIR_CHECK() parse_list(&SUHOSIN_G(cookie_plainlist), new_value, 0); return SUCCESS; } static ZEND_INI_MH(OnUpdate_disable_display_errors) /* {{{ */ { zend_bool *p; #ifndef ZTS char *base = (char *) mh_arg2; #else char *base; base = (char *) ts_resource(*((int *) mh_arg2)); #endif p = (zend_bool *) (base+(size_t) mh_arg1); if (new_value_length == 2 && strcasecmp("on", new_value) == 0) { *p = (zend_bool) 1; } else if (new_value_length == 3 && strcasecmp("yes", new_value) == 0) { *p = (zend_bool) 1; } else if (new_value_length == 4 && strcasecmp("true", new_value) == 0) { *p = (zend_bool) 1; } else if (new_value_length == 4 && strcasecmp("fail", new_value) == 0) { *p = (zend_bool) 2; } else { *p = (zend_bool) atoi(new_value); } return SUCCESS; } /* }}} */ static ZEND_INI_MH(OnUpdate_fail) { return FAILURE; } /* {{{ proto string suhosin_encrypt_cookie(string name, string value) Encrypts a cookie value according to current cookie encrpytion setting */ static PHP_FUNCTION(suhosin_encrypt_cookie) { char *name, *value; int name_len, value_len; char cryptkey[33]; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &name, &name_len, &value, &value_len) == FAILURE) { return; } if (!SUHOSIN_G(cookie_encrypt)) { return_plain: RETURN_STRINGL(value, value_len, 1); } if (SUHOSIN_G(cookie_plainlist)) { if (zend_hash_exists(SUHOSIN_G(cookie_plainlist), name, name_len+1)) { goto return_plain; } } else if (SUHOSIN_G(cookie_cryptlist)) { if (!zend_hash_exists(SUHOSIN_G(cookie_cryptlist), name, name_len+1)) { goto return_plain; } } suhosin_generate_key(SUHOSIN_G(cookie_cryptkey), SUHOSIN_G(cookie_cryptua), SUHOSIN_G(cookie_cryptdocroot), SUHOSIN_G(cookie_cryptraddr), (char *)&cryptkey TSRMLS_CC); value = suhosin_encrypt_string(value, value_len, name, name_len, (char *)&cryptkey TSRMLS_CC); RETVAL_STRING(value, 0); } /* }}} */ /* {{{ proto mixed suhosin_get_raw_cookies() Returns an array containing the raw cookie values */ static PHP_FUNCTION(suhosin_get_raw_cookies) { char *var, *val, *res; zval *array_ptr = return_value; char *strtok_buf = NULL; int val_len; array_init(array_ptr); if (SUHOSIN_G(raw_cookie)) { res = estrdup(SUHOSIN_G(raw_cookie)); } else { return; } var = NULL; while (var != res) { var = strrchr(res, ';'); if (var) { *var++ = '\0'; } else { var = res; } if (!*var) { continue; } val = strchr(var, '='); if (val) { /* have a value */ *val++ = '\0'; php_url_decode(var, strlen(var)); val_len = php_url_decode(val, strlen(val)); } else { php_url_decode(var, strlen(var)); val_len = 0; val = ""; } php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); } efree(res); } /* }}} */ /* {{{ suhosin_functions[] */ zend_function_entry suhosin_functions[] = { PHP_NAMED_FE(suhosin_encrypt_cookie, PHP_FN(suhosin_encrypt_cookie), NULL) PHP_NAMED_FE(suhosin_get_raw_cookies, PHP_FN(suhosin_get_raw_cookies), NULL) {NULL, NULL, NULL} /* Must be the last line in suhosin_functions[] */ }; /* }}} */ /* {{{ suhosin_module_entry */ zend_module_entry suhosin_module_entry = { #if ZEND_MODULE_API_NO >= 20010901 STANDARD_MODULE_HEADER, #endif "suhosin", suhosin_functions, PHP_MINIT(suhosin), PHP_MSHUTDOWN(suhosin), PHP_RINIT(suhosin), PHP_RSHUTDOWN(suhosin), PHP_MINFO(suhosin), #if ZEND_MODULE_API_NO >= 20010901 SUHOSIN_EXT_VERSION, /* Replace with version number for your extension */ #endif STANDARD_MODULE_PROPERTIES }; /* }}} */ #ifdef COMPILE_DL_SUHOSIN ZEND_GET_MODULE(suhosin) #endif /* {{{ PHP_INI */ static zend_ini_entry shared_ini_entries[] = { ZEND_INI_ENTRY("suhosin.log.syslog", NULL /* S_ALL & ~S_SQL */, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateSuhosin_log_syslog) ZEND_INI_ENTRY("suhosin.log.syslog.facility", NULL /* LOG_USER */, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateSuhosin_log_syslog_facility) ZEND_INI_ENTRY("suhosin.log.syslog.priority", NULL /* LOG_ALERT */, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateSuhosin_log_syslog_priority) ZEND_INI_ENTRY("suhosin.log.sapi", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateSuhosin_log_sapi) ZEND_INI_ENTRY("suhosin.log.stdout", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateSuhosin_log_stdout) ZEND_INI_ENTRY("suhosin.log.script", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateSuhosin_log_script) ZEND_INI_ENTRY("suhosin.log.script.name", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateSuhosin_log_scriptname) STD_ZEND_INI_BOOLEAN("suhosin.log.use-x-forwarded-for", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLogBool, log_use_x_forwarded_for, zend_suhosin_globals, suhosin_globals) ZEND_INI_ENTRY("suhosin.log.phpscript", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateSuhosin_log_phpscript) STD_ZEND_INI_ENTRY("suhosin.log.phpscript.name", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLogString, log_phpscriptname, zend_suhosin_globals, suhosin_globals) ZEND_INI_ENTRY("suhosin.log.file", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateSuhosin_log_file) STD_ZEND_INI_ENTRY("suhosin.log.file.name", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLogString, log_filename, zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_BOOLEAN("suhosin.log.file.time", "1", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLogBool, log_file_time, zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_BOOLEAN("suhosin.log.phpscript.is_safe", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLogBool, log_phpscript_is_safe, zend_suhosin_globals, suhosin_globals) ZEND_INI_END() PHP_INI_BEGIN() STD_PHP_INI_ENTRY("suhosin.log.max_error_length", "0", PHP_INI_SYSTEM, OnUpdateLogLong, log_max_error_length, zend_suhosin_globals, suhosin_globals) ZEND_INI_ENTRY("suhosin.perdir", "0", ZEND_INI_SYSTEM, OnUpdateSuhosin_perdir) STD_ZEND_INI_ENTRY("suhosin.executor.include.max_traversal", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateExecLong, executor_include_max_traversal, zend_suhosin_globals, suhosin_globals) ZEND_INI_ENTRY("suhosin.executor.include.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdate_include_whitelist) ZEND_INI_ENTRY("suhosin.executor.include.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdate_include_blacklist) STD_ZEND_INI_BOOLEAN("suhosin.executor.include.allow_writable_files", "1", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateExecBool, executor_include_allow_writable_files, zend_suhosin_globals, suhosin_globals) ZEND_INI_ENTRY("suhosin.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdate_eval_whitelist) ZEND_INI_ENTRY("suhosin.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdate_eval_blacklist) ZEND_INI_ENTRY("suhosin.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdate_func_whitelist) ZEND_INI_ENTRY("suhosin.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdate_func_blacklist) STD_ZEND_INI_BOOLEAN("suhosin.executor.disable_eval", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateExecBool, executor_disable_eval, zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_BOOLEAN("suhosin.executor.disable_emodifier", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateExecBool, executor_disable_emod, zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_BOOLEAN("suhosin.executor.allow_symlink", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateExecBool, executor_allow_symlink, zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_ENTRY("suhosin.executor.max_depth", "750", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateExecLong, max_execution_depth, zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_BOOLEAN("suhosin.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateMiscBool, allow_multiheader, zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_ENTRY("suhosin.mail.protect", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateMiscLong, mailprotect, zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_ENTRY("suhosin.memory_limit", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateMiscLong, memory_limit, zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_BOOLEAN("suhosin.simulation", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateMiscBool, simulation, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.filter.action", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateMiscString, filter_action, zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_BOOLEAN("suhosin.protectkey", "1", ZEND_INI_SYSTEM, OnUpdateBool, protectkey, zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_BOOLEAN("suhosin.coredump", "0", ZEND_INI_SYSTEM, OnUpdateBool, coredump, zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_BOOLEAN("suhosin.stealth", "1", ZEND_INI_SYSTEM, OnUpdateBool, stealth, zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_BOOLEAN("suhosin.apc_bug_workaround", "0", ZEND_INI_SYSTEM, OnUpdateBool, apc_bug_workaround, zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_BOOLEAN("suhosin.disable.display_errors", "0", ZEND_INI_SYSTEM, OnUpdate_disable_display_errors, disable_display_errors, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.request.max_vars", "1000", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateRequestLong, max_request_variables, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.request.max_varname_length", "64", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateRequestLong, max_varname_length, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.request.max_value_length", "1000000", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateRequestLong, max_value_length, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.request.max_array_depth", "50", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateRequestLong, max_array_depth, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.request.max_totalname_length", "256", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateRequestLong, max_totalname_length, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.request.max_array_index_length", "64", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateRequestLong, max_array_index_length, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.request.array_index_whitelist", "", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateString, array_index_whitelist, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.request.array_index_blacklist", "'\"+<>;()", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateString, array_index_blacklist, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.request.disallow_nul", "1", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateRequestBool, disallow_nul, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.request.disallow_ws", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateRequestBool, disallow_ws, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.cookie.max_vars", "100", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateCookieLong, max_cookie_vars, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.cookie.max_name_length", "64", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateCookieLong, max_cookie_name_length, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.cookie.max_totalname_length", "256", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateCookieLong, max_cookie_totalname_length, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.cookie.max_value_length", "10000", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateCookieLong, max_cookie_value_length, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.cookie.max_array_depth", "50", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateCookieLong, max_cookie_array_depth, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.cookie.max_array_index_length", "64", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateCookieLong, max_cookie_array_index_length, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.cookie.disallow_nul", "1", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateCookieBool, disallow_cookie_nul, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.cookie.disallow_ws", "1", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateCookieBool, disallow_cookie_ws, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.get.max_vars", "100", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateGetLong, max_get_vars, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.get.max_name_length", "64", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateGetLong, max_get_name_length, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.get.max_totalname_length", "256", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateGetLong, max_get_totalname_length, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.get.max_value_length", "512", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateGetLong, max_get_value_length, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.get.max_array_depth", "50", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateGetLong, max_get_array_depth, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.get.max_array_index_length", "64", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateGetLong, max_get_array_index_length, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.get.disallow_nul", "1", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateGetBool, disallow_get_nul, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.get.disallow_ws", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateGetBool, disallow_get_ws, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.post.max_vars", "1000", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdatePostLong, max_post_vars, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.post.max_name_length", "64", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdatePostLong, max_post_name_length, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.post.max_totalname_length", "256", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdatePostLong, max_post_totalname_length, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.post.max_value_length", "1000000", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdatePostLong, max_post_value_length, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.post.max_array_depth", "50", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdatePostLong, max_post_array_depth, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.post.max_array_index_length", "64", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdatePostLong, max_post_array_index_length, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.post.disallow_nul", "1", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdatePostBool, disallow_post_nul, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.post.disallow_ws", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdatePostBool, disallow_post_ws, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.upload.max_uploads", "25", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadLong, upload_limit, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.upload.max_newlines", "100", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadLong, upload_max_newlines, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.upload.disallow_elf", "1", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadBool, upload_disallow_elf, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.upload.disallow_binary", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadBool, upload_disallow_binary, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.upload.remove_binary", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadBool, upload_remove_binary, zend_suhosin_globals, suhosin_globals) #ifdef SUHOSIN_EXPERIMENTAL STD_PHP_INI_BOOLEAN("suhosin.upload.allow_utf8", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadBool, upload_allow_utf8, zend_suhosin_globals, suhosin_globals) #endif STD_PHP_INI_ENTRY("suhosin.upload.verification_script", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateUploadString, upload_verification_script, zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_BOOLEAN("suhosin.sql.bailout_on_error", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateSQLBool, sql_bailout_on_error, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.sql.user_prefix", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateSQLString, sql_user_prefix, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.sql.user_postfix", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateSQLString, sql_user_postfix, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.sql.user_match", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateSQLString, sql_user_match, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.sql.comment", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateSQLLong, sql_comment, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.sql.opencomment", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateSQLLong, sql_opencomment, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.sql.multiselect", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateSQLLong, sql_mselect, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.sql.union", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateSQLLong, sql_union, zend_suhosin_globals, suhosin_globals) #ifdef HAVE_PHP_SESSION STD_ZEND_INI_BOOLEAN("suhosin.session.encrypt", "1", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateMiscBool, session_encrypt, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.session.cryptkey", "", PHP_INI_ALL, OnUpdateMiscString, session_cryptkey, zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_BOOLEAN("suhosin.session.cryptua", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateMiscBool, session_cryptua, zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_BOOLEAN("suhosin.session.cryptdocroot", "1", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateMiscBool, session_cryptdocroot, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.session.cryptraddr", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateMiscLong, session_cryptraddr, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.session.checkraddr", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateMiscLong, session_checkraddr, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.session.max_id_length", "128", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateMiscLong, session_max_id_length, zend_suhosin_globals, suhosin_globals) #else /* HAVE_PHP_SESSION */ #warning BUILDING SUHOSIN WITHOUT SESSION SUPPORT #endif /* HAVE_PHP_SESSION */ STD_ZEND_INI_BOOLEAN("suhosin.cookie.encrypt", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, cookie_encrypt, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.cookie.cryptkey", "", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateString, cookie_cryptkey, zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_BOOLEAN("suhosin.cookie.cryptua", "1", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, cookie_cryptua, zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_BOOLEAN("suhosin.cookie.cryptdocroot", "1", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, cookie_cryptdocroot, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.cookie.cryptraddr", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateLong, cookie_cryptraddr, zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.cookie.checkraddr", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateLong, cookie_checkraddr, zend_suhosin_globals, suhosin_globals) ZEND_INI_ENTRY("suhosin.cookie.cryptlist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdate_cookie_cryptlist) ZEND_INI_ENTRY("suhosin.cookie.plainlist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdate_cookie_plainlist) STD_ZEND_INI_BOOLEAN("suhosin.server.encode", "1", ZEND_INI_SYSTEM, OnUpdateBool, server_encode,zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_BOOLEAN("suhosin.server.strip", "1", ZEND_INI_SYSTEM, OnUpdateBool, server_strip,zend_suhosin_globals, suhosin_globals) STD_PHP_INI_ENTRY("suhosin.rand.seedingkey", "", ZEND_INI_SYSTEM|ZEND_INI_PERDIR, OnUpdateMiscString, seedingkey, zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_BOOLEAN("suhosin.rand.reseed_every_request", "0", ZEND_INI_SYSTEM|ZEND_INI_PERDIR, OnUpdateMiscBool, reseed_every_request, zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_BOOLEAN("suhosin.srand.ignore", "1", ZEND_INI_SYSTEM|ZEND_INI_PERDIR, OnUpdateMiscBool, srand_ignore,zend_suhosin_globals, suhosin_globals) STD_ZEND_INI_BOOLEAN("suhosin.mt_srand.ignore", "1", ZEND_INI_SYSTEM|ZEND_INI_PERDIR, OnUpdateMiscBool, mt_srand_ignore,zend_suhosin_globals, suhosin_globals) PHP_INI_END() /* }}} */ /* {{{ suhosin_getenv */ char *suhosin_getenv(char *name, size_t name_len TSRMLS_DC) { if (sapi_module.getenv) { char *value, *tmp = sapi_module.getenv(name, name_len TSRMLS_CC); if (tmp) { value = estrdup(tmp); } else { return NULL; } return value; } else { /* fallback to the system's getenv() function */ char *tmp; name = estrndup(name, name_len); tmp = getenv(name); efree(name); if (tmp) { return estrdup(tmp); } } return NULL; } /* }}} */ /* {{{ suhosin_bailout */ void suhosin_bailout(TSRMLS_D) { if (!SUHOSIN_G(simulation)) { zend_bailout(); } } /* }}} */ /* {{{ php_suhosin_init_globals */ STATIC void php_suhosin_init_globals(zend_suhosin_globals *suhosin_globals) { memset(suhosin_globals, 0, sizeof(zend_suhosin_globals)); } /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(suhosin) { SDEBUG("(MINIT)"); ZEND_INIT_MODULE_GLOBALS(suhosin, php_suhosin_init_globals, NULL); /* only register constants if they have not previously been registered by a possible patched PHP */ if (zend_hash_exists(EG(zend_constants), "S_MEMORY", sizeof("S_MEMORY"))==0) { REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_LONG_CONSTANT("S_MAIL", S_MAIL, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_LONG_CONSTANT("S_SESSION", S_SESSION, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS); } /* check if shared ini directives are already known (maybe a patched PHP) */ if (zend_hash_exists(EG(ini_directives), "suhosin.log.syslog", sizeof("suhosin.log.syslog"))) { /* and update them */ zend_ini_entry *p = (zend_ini_entry *)&shared_ini_entries; while (p->name) { zend_ini_entry *i; if (zend_hash_find(EG(ini_directives), p->name, p->name_length, (void **) &i)==FAILURE) { /* continue registering them */ zend_register_ini_entries(p, module_number TSRMLS_CC); break; } SDEBUG("updating ini %s=%s", i->name, i->value); i->modifiable = p->modifiable; i->module_number = module_number; i->on_modify = p->on_modify; i->mh_arg1 = p->mh_arg1; i->mh_arg2 = p->mh_arg2; i->mh_arg3 = p->mh_arg3; i->on_modify(i, i->value, i->value_length, i->mh_arg1, i->mh_arg2, i->mh_arg3, ZEND_INI_STAGE_STARTUP TSRMLS_CC); p++; } } else { /* not registered yet, then simply use the API */ zend_register_ini_entries((zend_ini_entry *)&shared_ini_entries, module_number TSRMLS_CC); } /* and register the rest of the ini entries */ REGISTER_INI_ENTRIES(); /* Force display_errors=off */ if (SUHOSIN_G(disable_display_errors)) { zend_ini_entry *i; if (zend_hash_find(EG(ini_directives), "display_errors", sizeof("display_errors"), (void **) &i) == SUCCESS) { if (i->on_modify) { i->on_modify(i, "0", 1, i->mh_arg1, i->mh_arg2, i->mh_arg3, ZEND_INI_STAGE_STARTUP TSRMLS_CC); if (SUHOSIN_G(disable_display_errors) > 1) { i->value = "0"; i->modified = 0; i->value_length = strlen(i->value); i->on_modify = OnUpdate_fail; } else { i->on_modify = NULL; } } } } /* Load invisible to other Zend Extensions */ if (zend_llist_count(&zend_extensions)==0 || SUHOSIN_G(stealth)==0) { zend_extension extension; extension = suhosin_zend_extension_entry; extension.handle = NULL; zend_llist_add_element(&zend_extensions, &extension); ze = NULL; } else { ze = (zend_extension *)zend_llist_get_last_ex(&zend_extensions, &lp); old_startup = ze->startup; ze->startup = suhosin_startup_wrapper; } /* now hook a bunch of stuff */ suhosin_hook_memory_limit(TSRMLS_C); suhosin_hook_sha256(TSRMLS_C); suhosin_hook_ex_imp(TSRMLS_C); #if defined(__OpenBSD__) && defined(SUHOSIN_EXPERIMENTAL) suhosin_hook_pledge(TSRMLS_C); #endif #if PHP_VERSION_ID < 50500 /* register the logo for phpinfo */ php_register_info_logo(SUHOSIN_LOGO_GUID, "image/jpeg", suhosin_logo, sizeof(suhosin_logo)); #endif #if PHP_VERSION_ID < 50400 #error Suhosin Extension is not designed to run with PHP versions lower than 5.4. #endif #if !defined(HAVE_PHP_SESSION) && !defined(SUHOSIN_NO_SESSION_WARNING) php_error_docref(NULL TSRMLS_CC, E_WARNING, "Suhosin was compiled without session support, which is probably not what you want. All session related features will not be available, e.g. session encryption. If session support is really not needed, recompile Suhosin with -DSUHOSIN_NO_SESSION_WARNING=1 to suppress this warning."); #endif return SUCCESS; } /* }}} */ /* {{{ PHP_MSHUTDOWN_FUNCTION */ PHP_MSHUTDOWN_FUNCTION(suhosin) { SDEBUG("(MSHUTDOWN)"); UNREGISTER_INI_ENTRIES(); return SUCCESS; } /* }}} */ /* {{{ PHP_RINIT_FUNCTION */ PHP_RINIT_FUNCTION(suhosin) { SDEBUG("(RINIT)"); SUHOSIN_G(in_code_type) = SUHOSIN_NORMAL; SUHOSIN_G(execution_depth) = 0; return SUCCESS; } /* }}} */ /* {{{ PHP_RSHUTDOWN_FUNCTION */ PHP_RSHUTDOWN_FUNCTION(suhosin) { SDEBUG("(RSHUTDOWN)"); /* We need to clear the input filtering variables in the request shutdown because input filtering is done before RINIT */ SUHOSIN_G(cur_request_variables) = 0; SUHOSIN_G(cur_cookie_vars) = 0; SUHOSIN_G(cur_get_vars) = 0; SUHOSIN_G(cur_post_vars) = 0; SUHOSIN_G(att_request_variables) = 0; SUHOSIN_G(att_cookie_vars) = 0; SUHOSIN_G(att_get_vars) = 0; SUHOSIN_G(att_post_vars) = 0; SUHOSIN_G(num_uploads) = 0; SUHOSIN_G(no_more_variables) = 0; SUHOSIN_G(no_more_get_variables) = 0; SUHOSIN_G(no_more_post_variables) = 0; SUHOSIN_G(no_more_cookie_variables) = 0; SUHOSIN_G(no_more_uploads) = 0; SUHOSIN_G(abort_request) = 0; if (SUHOSIN_G(reseed_every_request)) { SUHOSIN_G(r_is_seeded) = 0; SUHOSIN_G(mt_is_seeded) = 0; } if (SUHOSIN_G(decrypted_cookie)) { efree(SUHOSIN_G(decrypted_cookie)); SUHOSIN_G(decrypted_cookie)=NULL; } if (SUHOSIN_G(raw_cookie)) { efree(SUHOSIN_G(raw_cookie)); SUHOSIN_G(raw_cookie)=NULL; } return SUCCESS; } /* }}} */ /* {{{ suhosin_ini_displayer(zend_ini_entry *ini_entry, int type) */ static void suhosin_ini_displayer(zend_ini_entry *ini_entry, int type) { TSRMLS_FETCH(); PHPWRITE("[ protected ]", strlen("[ protected ]")); } /* }}} */ /* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(suhosin) { php_info_print_box_start(0); if (!sapi_module.phpinfo_as_text) { do { char *enc_logo; int ret; PUTS("\"Suhosin\n"); } while(0); } PUTS("This server is protected with the Suhosin Extension " SUHOSIN_EXT_VERSION); PUTS(!sapi_module.phpinfo_as_text?"

":"\n\n"); if (sapi_module.phpinfo_as_text) { PUTS("Copyright (c) 2006-2007 Hardened-PHP Project\n"); PUTS("Copyright (c) 2007-2015 SektionEins GmbH\n"); } else { PUTS("Copyright (c) 2006-2007 Hardened-PHP Project
\n"); PUTS("Copyright (c) 2007-2015 SektionEins GmbH\n"); } php_info_print_box_end(); if (SUHOSIN_G(protectkey)) { zend_ini_entry *i; if (zend_hash_find(EG(ini_directives), "suhosin.cookie.cryptkey", sizeof("suhosin.cookie.cryptkey"), (void **) &i)==SUCCESS) { i->displayer = suhosin_ini_displayer; } if (zend_hash_find(EG(ini_directives), "suhosin.session.cryptkey", sizeof("suhosin.session.cryptkey"), (void **) &i)==SUCCESS) { i->displayer = suhosin_ini_displayer; } if (zend_hash_find(EG(ini_directives), "suhosin.rand.seedingkey", sizeof("suhosin.rand.seedingkey"), (void **) &i)==SUCCESS) { i->displayer = suhosin_ini_displayer; } } DISPLAY_INI_ENTRIES(); if (SUHOSIN_G(protectkey)) { zend_ini_entry *i; if (zend_hash_find(EG(ini_directives), "suhosin.cookie.cryptkey", sizeof("suhosin.cookie.cryptkey"), (void **) &i)==SUCCESS) { i->displayer = NULL; } if (zend_hash_find(EG(ini_directives), "suhosin.session.cryptkey", sizeof("suhosin.session.cryptkey"), (void **) &i)==SUCCESS) { i->displayer = NULL; } if (zend_hash_find(EG(ini_directives), "suhosin.rand.seedingkey", sizeof("suhosin.rand.seedingkey"), (void **) &i)==SUCCESS) { i->displayer = NULL; } } } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ ================================================ FILE: suhosin.ini ================================================ ;extension=suhosin.so [suhosin] ; ; ===================== ; Logging Configuration ; ===================== ; ; suhosin.log.syslog ; ------------------ ; ; * Type: Integer ; * Default: S_ALL & ~S_SQL ; ; Defines what classes of security alerts are logged to the syslog daemon. ; Logging of errors of the class S_MEMORY are always logged to syslog, no matter ; what this configuration says, because a corrupted heap could mean that the ; other logging options will malfunction during the logging process. ; ; +------------+-----------+----------------------------------------------------+ ; | Constant | Value | Description | ; +============+===========+====================================================+ ; | S_MEMORY | 1 | All canary violations and the safe unlink | ; | | | protection use this class | ; +------------+-----------+----------------------------------------------------+ ; | S_MISC | 2 | All log messages (f.e. format string protection) | ; | | | that do not fit in other classes use this class | ; +------------+-----------+----------------------------------------------------+ ; | S_VARS | 4 | All variable filters trigger this class | ; +------------+-----------+----------------------------------------------------+ ; | S_FILES | 8 | All violations triggered by the uploaded files | ; | | | filter use this class | ; +------------+-----------+----------------------------------------------------+ ; | S_INCLUDE | 16 | The protection against malicious include filenames | ; | | | use this class | ; +------------+-----------+----------------------------------------------------+ ; | S_SQL | 32 | Failed SQL queries are logged with this class | ; | | | (not yet supported in Suhosin BETA) | ; +------------+-----------+----------------------------------------------------+ ; | S_EXECUTOR | 64 | The execution depth protection uses this logging | ; | | | class | ; +------------+-----------+----------------------------------------------------+ ; | S_MAIL | 128 | The mail() header newline protection uses this | ; | | | logging class | ; +------------+-----------+----------------------------------------------------+ ; | S_SESSION | 256 | The transparent session protection uses this | ; | | | logging class | ; +------------+-----------+----------------------------------------------------+ ; | S_ALL | 511 | Combines all classes | ; +------------+-----------+----------------------------------------------------+ ; ; Using constant names is only supported with the Suhosin-Patch. If in doubt, use ; the numeric value, e.g. `suhosin.log.syslog=511`. ; ;suhosin.log.syslog = S_ALL & ~S_SQL ; ; ; suhosin.log.syslog.facility ; --------------------------- ; ; * Type: Integer ; * Default: LOG_USER ; ; Defines the syslog facility that is used when ALERTs are logged to syslog. ; Depending on your system type (syslogd) the following facilities are available. ; Please check your system's include header if the values are the same for your ; syslogd. ; ; +--------------+-------+ ; | Constant | Value | ; +==============+=======+ ; | LOG_KERN | 8 | ; +--------------+-------+ ; | LOG_USER | 9 | ; +--------------+-------+ ; | LOG_MAIL | 10 | ; +--------------+-------+ ; | LOG_DAEMON | 11 | ; +--------------+-------+ ; | LOG_AUTH | 12 | ; +--------------+-------+ ; | LOG_SYSLOG | 13 | ; +--------------+-------+ ; | LOG_LPR | 14 | ; +--------------+-------+ ; | LOG_NEWS | 15 | ; +--------------+-------+ ; | LOG_UUCP | 16 | ; +--------------+-------+ ; | LOG_CRON | 17 | ; +--------------+-------+ ; | LOG_AUTHPRIV | 18 | ; +--------------+-------+ ; | LOG_LOCAL0 | 24 | ; +--------------+-------+ ; | LOG_LOCAL1 | 25 | ; +--------------+-------+ ; | LOG_LOCAL2 | 26 | ; +--------------+-------+ ; | LOG_LOCAL3 | 27 | ; +--------------+-------+ ; | LOG_LOCAL4 | 28 | ; +--------------+-------+ ; | LOG_LOCAL5 | 29 | ; +--------------+-------+ ; | LOG_LOCAL6 | 30 | ; +--------------+-------+ ; | LOG_LOCAL7 | 31 | ; +--------------+-------+ ; ;suhosin.log.syslog.facility = LOG_USER ; ; ; suhosin.log.syslog.priority ; --------------------------- ; ; * Type: Integer ; * Default: LOG_ALERT ; ; Defines the syslog priority that is used when ALERTs are logged to syslog. ; Depending on your system type (syslogd) the following priorities are available. ; Please check your system's include header if the values are the same for your ; syslogd. ; ; +------------+-------+ ; |Constant | Value | ; +============+=======+ ; |LOG_EMERG | 0 | ; +------------+-------+ ; |LOG_ALERT | 1 | ; +------------+-------+ ; |LOG_CRIT | 2 | ; +------------+-------+ ; |LOG_WARNING | 3 | ; +------------+-------+ ; |LOG_NOTICE | 4 | ; +------------+-------+ ; |LOG_INFO | 5 | ; +------------+-------+ ; |LOG_DEBUG | 6 | ; +------------+-------+ ; |LOG_ERR | 7 | ; +------------+-------+ ; ;suhosin.log.syslog.priority = LOG_ALERT ; ; ; suhosin.log.sapi ; ---------------- ; ; * Type: Integer ; * Default: 0 ; ; Defines what classes of security alerts are logged through the SAPI error log. ; For a list of available classes see table 1. ; ; Using constant names is only supported with the Suhosin-Patch. If in doubt, use ; the numeric value. ; ;suhosin.log.sapi = 0 ; ; ; suhosin.log.stdout ; ------------------ ; ; * Type: Integer ; * Default: 0 ; ; Defines what classes of security alerts are logged through STDOUT. For a list ; of available classes see table 1. ; ; Using constant names is only supported with the Suhosin-Patch. If in doubt, use ; the numeric value. ; ; **IMPORTANT NOTE**: This option is meant for debugging purposes and unittests ; only and should not be used in production. ; ;suhosin.log.stdout = 0 ; ; ; suhosin.log.file ; ---------------- ; ; * Type: Integer ; * Default: 0 ; ; Defines what classes of security alerts are logged to a separate Suhosin log ; file set by suhosin.log.file.name. ; ; Using constant names is only supported with the Suhosin-Patch. If in doubt, use ; the numeric value. ; ;suhosin.log.file = 0 ; ; ; suhosin.log.file.name ; --------------------- ; ; * Type: String ; * Default: ; ; Defines the full path to a dedicated Suhosin log file. ; ;suhosin.log.file.name = ; ; ; suhosin.log.file.time ; --------------------- ; ; * Type: Boolean ; * Default: On ; ; Specifies if suhosin.log.file contains timestamp for each log entry. ; ; **IMPORTANT NOTE**: This option is meant for debugging purposes and unittests ; only and should not be used in production. ; ;suhosin.log.file.time = On ; ; ; suhosin.log.script ; ------------------ ; ; * Type: Integer ; * Default: 0 ; ; Defines what classes of security alerts are logged through the external logging ; script. For a list of available classes see table 1. An exception is the ; S_MEMORY class. It cannot be logged by a script, because S_MEMORY is triggered ; by buffer overflows etc... which means the process is in an unstable state. ; ; Using constant names is only supported with the Suhosin-Patch. If in doubt, use ; the numeric value. ; ;suhosin.log.script = 0 ; ; ; suhosin.log.script.name ; ----------------------- ; ; * Type: String ; * Default: ; ; Defines the full path to an external logging script. The script is called with ; 2 parameters. The first one is the alert class in string notation and the ; second parameter is the log message. This can be used for example to mail ; failing MySQL queries to your email address, because on a production system ; these things should never happen (S_SQL not yet supported by Suhosin). ; ;suhosin.log.script.name = ; ; ; suhosin.log.phpscript ; --------------------- ; ; * Type: Integer ; * Default: 0 ; ; Defines what classes of security alerts are logged through the defined PHP ; script. For a list of available classes see table 1. Please notice, that only ; those classes are allowed, that can be triggered during script execution. An ; exception is the S_MEMORY class. It cannot be logged by a PHP script, because ; S_MEMORY is triggered by buffer overflows etc... which means the process is in ; an unstable state. ; ; Using constant names is only supported with the Suhosin-Patch. If in doubt, use ; the numeric value. ; ;suhosin.log.phpscript = 0 ; ; ; suhosin.log.phpscript.name ; -------------------------- ; ; * Type: String ; * Default: ; ; Defines the full path to a PHP logging script. The script is called with 2 ; variables registered in the current scope: SUHOSIN_ERRORCLASS and ; SUHOSIN_ERROR. The first one is the alert class and the second variable is the ; log message. This can be used for example to mail attempted remote URL include ; attacks to your email address. ; ;suhosin.log.phpscript.name = ; ; ; suhosin.log.phpscript.is_safe ; ----------------------------- ; ; * Type: Boolean ; * Default: Off ; ; Disables open_basedir (and safe_mode for older PHP versions < 5.4) when ; executing suhosin.log.phpscript.name. ; ;suhosin.log.phpscript.is_safe = Off ; ; ; suhosin.log.use-x-forwarded-for ; ------------------------------- ; ; * Type: Boolean ; * Default: Off ; ; When the Suhosin logs an error the log message also contains the IP of the ; attacker. Usually this IP is retrieved from the REMOTE_ADDR SAPI environment ; variable. With this switch it is possible to change this behavior to read the ; IP from the X-Forwarded-For HTTP header. This is for example necessary when ; your PHP server runs behind a reverse proxy. ; ;suhosin.log.use-x-forwarded-for = Off ; ; ; ================ ; Executor Options ; ================ ; ; suhosin.executor.max_depth ; -------------------------- ; ; * Type: Integer ; * Default: 750 ; ; Defines the maximum stack depth allowed by the executor before it stops the ; script. Without this function an endless recursion in a PHP script could crash ; the PHP executor or trigger the configured memory_limit. A value of '0' ; disables this feature. ; ; (Before 0.9.37, the default value was 0.) ; ;suhosin.executor.max_depth = 750 ; ; ; suhosin.executor.include.max_traversal ; -------------------------------------- ; ; * Type: Integer ; * Default: 0 ; ; Defines how many '../' an include filename needs to contain to be considered an ; attack and stopped. A value of '2' will block '../../etc/passwd', while a value ; of '3' will allow it. Most PHP applications should work flawlessly with values ; '4' or '5'. A value of '0' disables this feature. ; ;suhosin.executor.include.max_traversal = 0 ; ; ; suhosin.executor.include.whitelist ; ---------------------------------- ; ; * Type: String ; * Default: ; ; Comma separated whitelist of URL schemes that are allowed to be included from ; include or require statements. Additionally to URL schemes it is possible to ; specify the beginning of allowed URLs. (f.e.: php://stdin) If no whitelist is ; specified, then the blacklist is evaluated. ; ; Notes: ; ; * This setting deactivates suhosin.executor.include.blacklist. ; * If both suhosin.executor.include.whitelist and ; suhosin.executor.include.blacklist are unset or empty, all URLs will be ; blocked. This is the default. ; ;suhosin.executor.include.whitelist = ; ; ; suhosin.executor.include.blacklist ; ---------------------------------- ; ; * Type: String ; * Default: ; ; Comma separated blacklist of URL schemes that are not allowed to be included ; from include or require statements. Additionally to URL schemes it is possible ; to specify the beginning of allowed URLs. (f.e.: php://stdin) If no blacklist ; and no whitelist is specified all URL schemes are forbidden. ; ;suhosin.executor.include.blacklist = ; ; ; suhosin.executor.include.allow_writable_files ; --------------------------------------------- ; ; * Type: Boolean ; * Default: On ; ; Turn this flag off to prevent PHP from executing writable PHP files. This can ; prevent attackers from executing code that was uploaded before. ; ; Note: Some software such as web-installers or web-based plugin installers won't ; work out of the box with this flag turned off. ; ;suhosin.executor.include.allow_writable_files = On ; ; ; suhosin.executor.func.whitelist ; ------------------------------- ; ; * Type: String ; * Default: ; ; Comma separated whitelist of functions that are allowed to be called. If the ; whitelist is empty the blacklist is evaluated, otherwise calling a function not ; in the whitelist will terminate the script and get logged. ; ; Note: This setting deactivates suhosin.executor.func.blacklist. ; ;suhosin.executor.func.whitelist = ; ; ; suhosin.executor.func.blacklist ; ------------------------------- ; ; * Type: String ; * Default: ; ; Comma separated blacklist of functions that are not allowed to be called. If no ; whitelist is given, calling a function within the blacklist will terminate the ; script and get logged. ; ;suhosin.executor.func.blacklist = ; ; ; suhosin.executor.eval.whitelist ; ------------------------------- ; ; * Type: String ; * Default: ; ; Comma separated whitelist of functions that are allowed to be called from ; within eval(). If the whitelist is empty the blacklist is evaluated, otherwise ; calling a function not in the whitelist will terminate the script and get ; logged. Please read the instructions carefully. ; ; Note: This setting deactivates suhosin.executor.eval.blacklist. ; ;suhosin.executor.eval.whitelist = ; ; ; suhosin.executor.eval.blacklist ; ------------------------------- ; ; * Type: String ; * Default: ; ; Comma separated blacklist of functions that are not allowed to be called from ; within eval(). If no whitelist is given, calling a function within the ; blacklist will terminate the script and get logged. Please read the ; instructions carefully. ; ;suhosin.executor.eval.blacklist = ; ; ; suhosin.executor.disable_eval ; ----------------------------- ; ; * Type: Boolean ; * Default: Off ; ; eval() is a very dangerous statement and therefore you might want to disable it ; completely. Deactivating it will however break lots of scripts. Because every ; violation is logged, this allows finding all places where eval() is used. ; ;suhosin.executor.disable_eval = Off ; ; ; suhosin.executor.disable_emodifier ; ---------------------------------- ; ; * Type: Boolean ; * Default: Off ; ; The /e modifier inside preg_replace() allows code execution. Often it is the ; cause for remote code execution exploits. It is wise to deactivate this feature ; and test where in the application it is used. The developer using the /e ; modifier should be made aware that he should use preg_replace_callback() ; instead. ; ;suhosin.executor.disable_emodifier = Off ; ; ; suhosin.executor.allow_symlink ; ------------------------------ ; ; * Type: Boolean ; * Default: Off ; ; This flag reactivates symlink() when open_basedir is used, which is disabled by ; default in Suhosin >= 0.9.6. Allowing symlink() while open_basedir is used is ; actually a security risk. ; ;suhosin.executor.allow_symlink = Off ; ; ; ============ ; Misc Options ; ============ ; ; suhosin.simulation ; ------------------ ; ; * Type: Boolean ; * Default: Off ; ; If you fear that Suhosin breaks your application, you can activate Suhosin's ; simulation mode with this flag. When Suhosin runs in simulation mode, ; violations are logged as usual, but nothing is blocked or removed from the ; request. (Transparent Encryptions are NOT deactivated in simulation mode.) ; ;suhosin.simulation = Off ; ; ; suhosin.perdir ; -------------- ; ; * Type: String ; * Default: "0" ; ; Allow certain categories of config directives to be changed by .htaccess for ; each directory individually. Possible values are "l" (log), "e" (exec), "g" ; (get), "c" (cookie), "p" (post), "r" (request), "s" (sql), "u" (upload), "m" ; (misc) or any combination, e.g. "legcprsum" to allow everything. Both "0" and ; no value disable this feature. ; ;suhosin.perdir = "0" ; ; ; suhosin.protectkey ; ------------------ ; ; * Type: Boolean ; * Default: On ; ; Prevent Suhosin's secret key material (suhosin.cookie.cryptkey, ; suhosin.session.cryptkey, suhosin.rand.seedingkey) from being exposed by ; phpinfo(). ; ;suhosin.protectkey = On ; ; ; suhosin.coredump ; ---------------- ; ; * Type: Boolean ; * Default: Off ; ; Controls if suhosin coredumps when the optional suhosin patch detects a buffer ; overflow, memory corruption or double free. This is only for debugging purposes ; and should not be activated. ; ;suhosin.coredump = Off ; ; ; suhosin.stealth ; --------------- ; ; * Type: Boolean ; * Default: On ; ; Controls if suhosin loads in stealth mode when it is not the only ; zend_extension (Required for full compatibility with certain encoders that ; consider open source untrusted. e.g. ionCube, Zend) ; ;suhosin.stealth = On ; ; ; suhosin.apc_bug_workaround ; -------------------------- ; ; * Type: Boolean ; * Default: Off ; ; APC 3.0.12(p1/p2) uses reserved resources without requesting a resource slot ; first. It always uses resource slot 0. If Suhosin got this slot assigned APC ; will overwrite the information Suhosin stores in this slot. When this flag is ; set Suhosin will request 2 Slots and use the second one. This allows working ; correctly with these buggy APC versions. ; ;suhosin.apc_bug_workaround = Off ; ; ; suhosin.disable.display_errors ; ------------------------------ ; ; * Type: String ; * Default: 0 ; ; Prevent PHP from setting display_errors programmatically. "0" means off. Any ; one of "1", "on", "yes", "true" means on. "fail" or "2" (or greater values) ; will let PHP know that the value change failed. ; ;suhosin.disable.display_errors = 0 ; ; ; suhosin.multiheader ; ------------------- ; ; * Type: Boolean ; * Default: Off ; ; This directive controls if multiple headers are allowed or not in a header() ; call. By default the Suhosin forbids this. (HTTP headers spanning multiple ; lines are still allowed). ; ;suhosin.multiheader = Off ; ; ; suhosin.mail.protect ; -------------------- ; ; * Type: Integer ; * Default: 0 ; ; This directive controls if the mail() header protection is activated or not and ; to what degree it is activated. The appended table lists the possible ; activation levels. ; ; +-------+--------------------------------------------------------------------+ ; | Value | Description | ; +=======+====================================================================+ ; | 0 | mail() header protection is disabled | ; +-------+--------------------------------------------------------------------+ ; | 1 | Disallows newlines in Subject:, To: headers and double newlines in | ; | | additional headers | ; +-------+--------------------------------------------------------------------+ ; | 2 | Additionally disallows To:, CC:, BCC: in additional headers | ; +-------+--------------------------------------------------------------------+ ; ; Logging of this class of alerts is controlled by the new S_MAIL constant. ; ;suhosin.mail.protect = 0 ; ; ; suhosin.memory_limit ; -------------------- ; ; * Type: Integer ; * Default: 0 ; ; As long scripts are not running within safe_mode they are free to change the ; memory_limit to whatever value they want. Suhosin changes this fact and ; disallows setting the memory_limit to a value greater than the one the script ; started with, when this option is left at 0. A value greater than 0 means that ; Suhosin will disallow scripts setting the memory_limit to a value above this ; configured hard limit. This is for example useful if you want to run the script ; normally with a limit of 16M but image processing scripts may raise it to 20M. ; ;suhosin.memory_limit = 0 ; ; ; ======================== ; SQL Injection Protection ; ======================== ; This class of features is experimental and still in development. As of Suhosin ; version 0.9.36 only preliminary MySQL and Mysqli support was added. ; ; suhosin.sql.bailout_on_error ; ---------------------------- ; ; * Type: Boolean ; * Default: Off ; ; (Planned feature. This is not yet supported.) When an SQL Query fails scripts ; often spit out a bunch of useful information for possible attackers. When this ; configuration directive is turned on, the script will silently terminate, after ; the problem has been logged. ; ;suhosin.sql.bailout_on_error = Off ; ; ; suhosin.sql.user_match ; ---------------------- ; ; * Type: String ; * Default: ; ; (introduced in 0.9.37) The SQL username must match this wildcard pattern or the ; connect function will fail and return FALSE. Example: `suhosin.sql.user_match = ; public_*` ; ;suhosin.sql.user_match = ; ; ; suhosin.sql.user_prefix ; ----------------------- ; ; * Type: String ; * Default: ; ; This is an experimental feature for shared environments. With this ; configuration option it is possible to specify a prefix that is automatically ; prepended to the database username, whenever a database connection is made. ; (Unless the username starts with the prefix) ; ; With this feature it is possible for shared hosters to disallow customers to ; connect with the usernames of other customers. This feature is experimental, ; because support for PDO and PostgreSQL are not yet implemented. ; ;suhosin.sql.user_prefix = ; ; ; suhosin.sql.user_postfix ; ------------------------ ; ; * Type: String ; * Default: ; ; This is an experimental feature for shared environments. With this ; configuration option it is possible to specify a postfix that is automatically ; appended to the database username, whenever a database connection is made. ; (Unless the username end with the postfix) ; ; With this feature it is possible for shared hosters to disallow customers to ; connect with the usernames of other customers. This feature is experimental, ; because support for PDO and PostgreSQL are not yet implemented. ; ;suhosin.sql.user_postfix = ; ; ; suhosin.sql.comment ; ------------------- ; ; * Type: Integer ; * Default: 0 ; ; This is an experimental feature. Alert if an SQL query contains one or more ; comments starting with --, /* or #. A value of 1 logs the alert; 2 or greater ; let the call fail. ; ; Note: Mysql conditional statements starting with ``/*!`` are exempt if used ; with Mysqli. ; ;suhosin.sql.comment = 0 ; ; ; suhosin.sql.opencomment ; ----------------------- ; ; * Type: Integer ; * Default: 0 ; ; This is an experimental feature. ; Alert if a MySQL comment was started but not closed: ``/*`` without ``*/``. A ; value of 1 logs the alert; 2 or greater let the call fail. ; ;suhosin.sql.opencomment = 0 ; ; ; suhosin.sql.multiselect ; ----------------------- ; ; * Type: Integer ; * Default: 0 ; ; This is an experimental feature. ; Alert if an SQL query contains more than one SELECT statement. A value of 1 ; logs the alert; 2 or greater let the call fail. ; ; Note: This flag will recognise multiple statements as well as subselects, e.g. ; "SELECT 1; SELECT 2" and "SELECT * FROM (SELECT 1)". ; ;suhosin.sql.multiselect = 0 ; ; ; suhosin.sql.union ; ----------------- ; ; * Type: Integer ; * Default: 0 ; ; This is an experimental feature. ; Alert if an SQL query contains one or more UNIONs. ; A value of 1 logs the alert; 2 or greater let the call fail. ; ;suhosin.sql.union = 0 ; ; ; ============================== ; Transparent Encryption Options ; ============================== ; ; suhosin.session.encrypt ; ----------------------- ; ; * Type: Boolean ; * Default: On ; ; Flag that decides if the transparent session encryption is activated or not. ; ;suhosin.session.encrypt = On ; ; ; suhosin.session.cryptkey ; ------------------------ ; ; * Type: String ; * Default: ; ; Session data can be encrypted transparently. The encryption key used consists ; of this user defined string (which can be altered by a script via ini_set()) ; and optionally the User-Agent, the Document-Root and 0-4 octects of the ; REMOTE_ADDR. ; ;suhosin.session.cryptkey = ; ; ; suhosin.session.cryptua ; ----------------------- ; ; * Type: Boolean ; * Default: Off ; ; Flag that decides if the transparent session encryption key depends on the ; User-Agent field. (When activated this feature transparently adds a little bit ; protection against session fixation/hijacking attacks) ; ;suhosin.session.cryptua = Off ; ; ; suhosin.session.cryptdocroot ; ---------------------------- ; ; * Type: Boolean ; * Default: On ; ; Flag that decides if the transparent session encryption key depends on the ; Documentroot field. ; ;suhosin.session.cryptdocroot = On ; ; ; suhosin.session.cryptraddr ; -------------------------- ; ; * Type: Integer ; * Default: 0 ; ; Number of octets (0-4) from the REMOTE_ADDR that the transparent session ; encryption key depends on. Keep in mind that this should not be used on sites ; that have visitors from big ISPs, because their IP address often changes during ; a session. But this feature might be interesting for admin interfaces or ; intranets. When used wisely this is a transparent protection against session ; hijacking/fixation. This feature supports IPv4 only. ; ;suhosin.session.cryptraddr = 0 ; ; ; suhosin.session.checkraddr ; -------------------------- ; ; * Type: Integer ; * Default: 0 ; ; Number of octets (0-4) from the REMOTE_ADDR that have to match to decrypt the ; session. The difference to suhosin.session.cryptaddr is, that the IP is not ; part of the encryption key, so that the same session can be used for different ; areas with different protection levels on the site. This feature supports IPv4 ; only. ; ;suhosin.session.checkraddr = 0 ; ; ; suhosin.cookie.encrypt ; ---------------------- ; ; * Type: Boolean ; * Default: Off ; ; Flag that decides if the transparent cookie encryption is activated or not. ; ;suhosin.cookie.encrypt = Off ; ; ; suhosin.cookie.cryptkey ; ----------------------- ; ; * Type: String ; * Default: ; ; Cookies can be encrypted transparently. The encryption key used consists of ; this user defined string and optionally the User-Agent, the Document-Root and ; 0-4 octects of the REMOTE_ADDR. ; ;suhosin.cookie.cryptkey = ; ; ; suhosin.cookie.cryptua ; ---------------------- ; ; * Type: Boolean ; * Default: On ; ; Flag that decides if the transparent session encryption key depends on the ; User-Agent field. (When activated this feature transparently adds a little bit ; protection against session fixation/hijacking attacks (if only session cookies ; are allowed)) ; ;suhosin.cookie.cryptua = On ; ; ; suhosin.cookie.cryptdocroot ; --------------------------- ; ; * Type: Boolean ; * Default: On ; ; Flag that decides if the transparent cookie encryption key depends on the ; Documentroot field. ; ;suhosin.cookie.cryptdocroot = On ; ; ; suhosin.cookie.cryptraddr ; ------------------------- ; ; * Type: Integer ; * Default: 0 ; ; Number of octets (0-4) from the REMOTE_ADDR that the transparent cookie ; encryption key depends on. Keep in mind that this should not be used on sites ; that have visitors from big ISPs, because their IP address often changes during ; a session. But this feature might be interesting for admin interfaces or ; intranets. When used wisely this is a transparent protection against session ; hijacking/fixation. This feature supports IPv4 only. ; ;suhosin.cookie.cryptraddr = 0 ; ; ; suhosin.cookie.checkraddr ; ------------------------- ; ; * Type: Integer ; * Default: 0 ; ; Number of octets (0-4) from the REMOTE_ADDR that have to match to decrypt the ; cookie. The difference to suhosin.cookie.cryptaddr is, that the IP is not part ; of the encryption key, so that the same cookie can be used for different areas ; with different protection levels on the site. This feature supports IPv4 only. ; ;suhosin.cookie.checkraddr = 0 ; ; ; suhosin.cookie.cryptlist ; ------------------------ ; ; * Type: String ; * Default: ; ; In case not all cookies are supposed to get encrypted this is a comma separated ; list of cookie names that should get encrypted. All other cookies will not get ; touched. ; ; 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. ; ;suhosin.cookie.cryptlist = ; ; ; suhosin.cookie.plainlist ; ------------------------ ; ; * Type: String ; * Default: ; ; In case some cookies should not be encrypted this is a comma separated list of ; cookies that do not get encrypted. All other cookies will be encrypted. ; ; Note: This setting deactivates suhosin.cookie.cryptlist. ; ;suhosin.cookie.plainlist = ; ; ; ================= ; Filtering Options ; ================= ; ; suhosin.filter.action ; --------------------- ; ; * Type: Mixed ; * Default: ; ; Defines the reaction of Suhosin on a filter violation. Following possible ; actions are supported ; ; +-------------------------------+--------------------------------------------+ ; | Type | Description | ; +===============================+============================================+ ; | | Normal action is simply blocking the | ; | | variable from being registered | ; +-------------------------------+--------------------------------------------+ ; | 402 | Do not execute the script and return a | ; | | HTTP 402 response code | ; +-------------------------------+--------------------------------------------+ ; | [302,]http://www.example.com | Redirect to http://www.example.com instead | ; | | of executing. Optionally set a specific | ; | | HTTP response code | ; +-------------------------------+--------------------------------------------+ ; | [402,]/var/scripts/badguy.php | Execute a specific PHP script instead of | ; | | the requested script. Optionally set a | ; | | specific HTTP response code | ; +-------------------------------+--------------------------------------------+ ; ;suhosin.filter.action = ; ; ; suhosin.cookie.max_array_depth ; ------------------------------ ; ; * Type: Integer ; * Default: 50 ; ; Defines the maximum depth an array variable may have, when registered through ; the COOKIE. ; ; Note: Array depth is not the number of elements within an array. ; ;suhosin.cookie.max_array_depth = 50 ; ; ; suhosin.cookie.max_array_index_length ; ------------------------------------- ; ; * Type: Integer ; * Default: 64 ; ; Defines the maximum length of array indices for variables registered through ; the COOKIE. ; ;suhosin.cookie.max_array_index_length = 64 ; ; ; suhosin.cookie.max_name_length ; ------------------------------ ; ; * Type: Integer ; * Default: 64 ; ; Defines the maximum length of variable names for variables registered through ; the COOKIE. For array variables this is the name in front of the indices. ; ;suhosin.cookie.max_name_length = 64 ; ; ; suhosin.cookie.max_totalname_length ; ----------------------------------- ; ; * Type: Integer ; * Default: 256 ; ; Defines the maximum length of the total variable name when registered through ; the COOKIE. For array variables this includes all indices. ; ;suhosin.cookie.max_totalname_length = 256 ; ; ; suhosin.cookie.max_value_length ; ------------------------------- ; ; * Type: Integer ; * Default: 10000 ; ; Defines the maximum length of a variable that is registered through the COOKIE. ; ;suhosin.cookie.max_value_length = 10000 ; ; ; suhosin.cookie.max_vars ; ----------------------- ; ; * Type: Integer ; * Default: 100 ; ; Defines the maximum number of variables that may be registered through the ; COOKIE. ; ;suhosin.cookie.max_vars = 100 ; ; ; suhosin.cookie.disallow_nul ; --------------------------- ; ; * Type: Boolean ; * Default: On ; ; When set to On ASCIIZ chars are not allowed in variables. ; ;suhosin.cookie.disallow_nul = On ; ; ; suhosin.cookie.disallow_ws ; -------------------------- ; ; * Type: Boolean ; * Default: On ; ; Ignore cookies with names starting with whitespace. ; ;suhosin.cookie.disallow_ws = On ; ; ; suhosin.get.max_array_depth ; --------------------------- ; ; * Type: Integer ; * Default: 50 ; ; Defines the maximum depth an array variable may have, when registered through ; the URL. ; ; Note: Array depth is not the number of elements within an array. ; ;suhosin.get.max_array_depth = 50 ; ; ; suhosin.get.max_array_index_length ; ---------------------------------- ; ; * Type: Integer ; * Default: 64 ; ; Defines the maximum length of array indices for variables registered through ; the URL. ; ;suhosin.get.max_array_index_length = 64 ; ; ; suhosin.get.max_name_length ; --------------------------- ; ; * Type: Integer ; * Default: 64 ; ; Defines the maximum length of variable names for variables registered through ; the URL. For array variables this is the name in front of the indices. ; ;suhosin.get.max_name_length = 64 ; ; ; suhosin.get.max_totalname_length ; -------------------------------- ; ; * Type: Integer ; * Default: 256 ; ; Defines the maximum length of the total variable name when registered through ; the URL. For array variables this includes all indices. ; ;suhosin.get.max_totalname_length = 256 ; ; ; suhosin.get.max_value_length ; ---------------------------- ; ; * Type: Integer ; * Default: 512 ; ; Defines the maximum length of a variable that is registered through the URL. ; ;suhosin.get.max_value_length = 512 ; ; ; suhosin.get.max_vars ; -------------------- ; ; * Type: Integer ; * Default: 100 ; ; Defines the maximum number of variables that may be registered through the URL. ; ;suhosin.get.max_vars = 100 ; ; ; suhosin.get.disallow_nul ; ------------------------ ; ; * Type: Boolean ; * Default: On ; ; When set to On ASCIIZ chars are not allowed in variables. ; ;suhosin.get.disallow_nul = On ; ; ; suhosin.get.disallow_ws ; ----------------------- ; ; * Type: Boolean ; * Default: Off ; ; Ignore GET parameters with names starting with whitespace. ; ;suhosin.get.disallow_ws = Off ; ; ; suhosin.post.max_array_depth ; ---------------------------- ; ; * Type: Integer ; * Default: 50 ; ; Defines the maximum depth an array variable may have, when registered through a ; POST request. ; ; Note: Array depth is not the number of elements within an array. ; ;suhosin.post.max_array_depth = 50 ; ; ; suhosin.post.max_array_index_length ; ----------------------------------- ; ; * Type: Integer ; * Default: 64 ; ; Defines the maximum length of array indices for variables registered through a ; POST request. ; ;suhosin.post.max_array_index_length = 64 ; ; ; suhosin.post.max_name_length ; ---------------------------- ; ; * Type: Integer ; * Default: 64 ; ; Defines the maximum length of variable names for variables registered through a ; POST request. For array variables this is the name in front of the indices. ; ;suhosin.post.max_name_length = 64 ; ; ; suhosin.post.max_totalname_length ; --------------------------------- ; ; * Type: Integer ; * Default: 256 ; ; Defines the maximum length of the total variable name when registered through a ; POST request. For array variables this includes all indices. ; ;suhosin.post.max_totalname_length = 256 ; ; ; suhosin.post.max_value_length ; ----------------------------- ; ; * Type: Integer ; * Default: 1000000 ; ; Defines the maximum length of a variable that is registered through a POST ; request. ; ;suhosin.post.max_value_length = 1000000 ; ; ; suhosin.post.max_vars ; --------------------- ; ; * Type: Integer ; * Default: 1000 ; ; Defines the maximum number of variables that may be registered through a POST ; request. ; ;suhosin.post.max_vars = 1000 ; ; ; suhosin.post.disallow_nul ; ------------------------- ; ; * Type: Boolean ; * Default: On ; ; When set to On ASCIIZ chars are not allowed in variables. ; ;suhosin.post.disallow_nul = On ; ; ; suhosin.post.disallow_ws ; ------------------------ ; ; * Type: Boolean ; * Default: Off ; ; Ignore POST parameters with names starting with whitespace. ; ;suhosin.post.disallow_ws = Off ; ; ; suhosin.request.array_index_blacklist ; ------------------------------------- ; ; * Type: String ; * Default: "'\"+<>;()" ; ; Defines a character blacklist for array indices not allowed in user input. ; ;suhosin.request.array_index_blacklist = "'\"+<>;()" ; ; ; suhosin.request.array_index_whitelist ; ------------------------------------- ; ; * Type: String ; * Default: ; ; * Example: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ; ; Defines a character whitelist for array indices allowed in user input. ; ; Note: This setting deactivates suhosin.request.array_index_blacklist. ; ;suhosin.request.array_index_whitelist = ; ; ; suhosin.request.max_array_depth ; ------------------------------- ; ; * Type: Integer ; * Default: 50 ; ; Defines the maximum depth an array variable may have, when registered through ; GET , POST or COOKIE. This setting is also an upper limit for the separate GET, ; POST, COOKIE configuration directives. ; ; Note: Array depth is not the number of elements within an array. ; ;suhosin.request.max_array_depth = 50 ; ; ; suhosin.request.max_array_index_length ; -------------------------------------- ; ; * Type: Integer ; * Default: 64 ; ; Defines the maximum length of array indices for variables registered through ; GET, POST or COOKIE. This setting is also an upper limit for the separate GET, ; POST, COOKIE configuration directives. ; ;suhosin.request.max_array_index_length = 64 ; ; ; suhosin.request.max_totalname_length ; ------------------------------------ ; ; * Type: Integer ; * Default: 256 ; ; Defines the maximum length of variable names for variables registered through ; the COOKIE, the URL or through a POST request. This is the complete name ; string, including all indices. This setting is also an upper limit for the ; separate GET, POST, COOKIE configuration directives. ; ;suhosin.request.max_totalname_length = 256 ; ; ; suhosin.request.max_value_length ; -------------------------------- ; ; * Type: Integer ; * Default: 1000000 ; ; Defines the maximum length of a variable that is registered through the COOKIE, ; the URL or through a POST request. This setting is also an upper limit for the ; variable origin specific configuration directives. ; ;suhosin.request.max_value_length = 1000000 ; ; ; suhosin.request.max_vars ; ------------------------ ; ; * Type: Integer ; * Default: 1000 ; ; Defines the maximum number of variables that may be registered through the ; COOKIE, the URL or through a POST request. This setting is also an upper limit ; for the variable origin specific configuration directives. ; ;suhosin.request.max_vars = 1000 ; ; ; suhosin.request.max_varname_length ; ---------------------------------- ; ; * Type: Integer ; * Default: 64 ; ; Defines the maximum name length (excluding possible array indices) of variables ; that may be registered through the COOKIE, the URL or through a POST request. ; This setting is also an upper limit for the variable origin specific ; configuration directives. ; ;suhosin.request.max_varname_length = 64 ; ; ; suhosin.request.disallow_nul ; ---------------------------- ; ; * Type: Boolean ; * Default: On ; ; When set to On ASCIIZ chars are not allowed in variables. ; ;suhosin.request.disallow_nul = On ; ; ; suhosin.request.disallow_ws ; --------------------------- ; ; * Type: Boolean ; * Default: Off ; ; Ignore all variables with names starting with whitespace. ; ;suhosin.request.disallow_ws = Off ; ; ; suhosin.upload.max_uploads ; -------------------------- ; ; * Type: Integer ; * Default: 25 ; ; Defines the maximum number of files that may be uploaded with one request. ; ;suhosin.upload.max_uploads = 25 ; ; ; suhosin.upload.max_newlines ; --------------------------- ; ; * Type: Integer ; * Default: 100 ; ; Defines the maximum number of newlines in rfc1867 mime headers. ; (added with version 0.9.38) ; ;suhosin.upload.max_newlines = 100 ; ; ; suhosin.upload.disallow_elf ; --------------------------- ; ; * Type: Boolean ; * Default: On ; ; When set to On it is not possible to upload ELF executables. ; ;suhosin.upload.disallow_elf = On ; ; ; suhosin.upload.disallow_binary ; ------------------------------ ; ; * Type: Boolean ; * Default: Off ; ; When set to On it is not possible to upload binary files. ; ;suhosin.upload.disallow_binary = Off ; ; ; suhosin.upload.remove_binary ; ---------------------------- ; ; * Type: Boolean ; * Default: Off ; ; When set to On binary content is removed from the uploaded files. ; ;suhosin.upload.remove_binary = Off ; ; ; suhosin.upload.allow_utf8 ; ------------------------- ; ; * Type: Boolean ; * Default: Off ; ; This is an experimental feature. This option allows UTF-8 along with ASCII when ; using `suhosin.upload.disallow_binary` or `suhosin.upload.remove_binary`. ; ;suhosin.upload.allow_utf8 = Off ; ; ; suhosin.upload.verification_script ; ---------------------------------- ; ; * Type: String ; * Default: ; ; This defines the full path to a verification script for uploaded files. The ; script gets the temporary filename supplied and has to decide if the upload is ; allowed. A possible application for this is to scan uploaded files for viruses. ; The called script has to write a 1 as first line to standard output to allow ; the upload. Any other value or no output at all will result in the file being ; deleted. ; ;suhosin.upload.verification_script = ; ; ; suhosin.session.max_id_length ; ----------------------------- ; ; * Type: Integer ; * Default: 128 ; ; Specifies the maximum length of the session identifier that is allowed. When a ; longer session identifier is passed a new session identifier will be created. ; This feature is important to fight buffer overflows in 3rd party session ; handlers. ; ;suhosin.session.max_id_length = 128 ; ; ; suhosin.server.encode ; --------------------- ; ; * Type: Boolean ; * Default: On ; ; Encode potentially dangerous characters in REQUEST_URI and QUERY_STRING with ; URL encoding. ; ;suhosin.server.encode = On ; ; ; suhosin.server.strip ; -------------------- ; ; * Type: Boolean ; * Default: On ; ; Replace potentially dangerous characters in PHP_SELF, PATH_INFO, ; PATH_TRANSLATED and HTTP_USER_AGENT with '?'. ; ;suhosin.server.strip = On ; ; ; suhosin.rand.seedingkey ; ----------------------- ; ; * Type: String ; * Default: ; ; This string is added to the entropy pool for seeding the random number ; generator. ; ;suhosin.rand.seedingkey = ; ; ; suhosin.rand.reseed_every_request ; --------------------------------- ; ; * Type: Boolean ; * Default: Off ; ; Controls if automatic reseeding of rand() / mt_rand() is done for every new ; request. Will improve security but decrease performance. In case the system's ; entry pool is exhausted, this flag may either significantly increase execution ; time or otherwise use less entropy (which is bad). ; ;suhosin.rand.reseed_every_request = Off ; ; ; suhosin.srand.ignore ; -------------------- ; ; * Type: Boolean ; * Default: On ; ; Flag that controls if calls to srand() are ignored in favour of Suhosin's own ; enhanced seeding - since 0.9.36 calls will trigger auto-reseeding. ; ;suhosin.srand.ignore = On ; ; ; suhosin.mt_srand.ignore ; ----------------------- ; ; * Type: Boolean ; * Default: On ; ; Flag that controls if calls to mt_srand() are ignored in favour of Suhosin's ; own enhanced seeding - since 0.9.36 calls will trigger auto-reseeding. ; ;suhosin.mt_srand.ignore = On ; ================================================ FILE: suhosin_logo.h ================================================ #define SUHOSIN_LOGO_GUID "SUHO8567F54-D428-14d2-A769-00DA302A5F18" static unsigned char suhosin_logo[] = "\xff\xd8\xff\xe0\x00\x10\x4a\x46\x49\x46\x00\x01\x01\x01\x00\x48" "\x00\x48\x00\x00\xff\xe1\x00\x16\x45\x78\x69\x66\x00\x00\x4d\x4d" "\x00\x2a\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\xff\xdb\x00\x43" "\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" "\x01\xff\xc0\x00\x0b\x08\x00\x27\x00\x71\x01\x01\x22\x00\xff\xc4" "\x00\x1e\x00\x00\x02\x02\x02\x03\x01\x01\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x09\x06\x08\x05\x07\x02\x03\x0a\x01\x04\xff\xc4" "\x00\x32\x10\x00\x01\x04\x03\x00\x02\x00\x05\x01\x05\x09\x01\x00" "\x00\x00\x00\x05\x02\x03\x04\x06\x01\x07\x08\x00\x09\x11\x12\x13" "\x14\x21\x15\x0a\x16\x31\x56\x96\x17\x18\x19\x23\x32\x41\x58\x98" "\xd4\xd6\xff\xda\x00\x08\x01\x01\x00\x00\x3f\x00\xf4\xc1\xe1\xe5" "\x69\xe9\x3e\xb9\xd1\x7c\x8a\x2e\x9d\x66\xe8\x3b\x29\x4d\x7f\x46" "\xba\x58\x55\x54\x8d\xb1\x5f\xaa\xd9\x8d\x51\x2b\xb6\x27\x5a\x69" "\xd1\x43\xaf\x16\x1a\xf0\xb2\xb1\xe9\x6d\x9f\xc2\xa4\x36\x18\xb5" "\x85\x10\x41\xbe\xfc\x09\xac\x49\x29\x11\xd4\x32\x97\xec\x08\x13" "\xc1\x2d\x20\xc3\x59\xeb\x26\x05\xd8\x6b\x76\x31\x43\x8f\x57\xcf" "\x84\x9f\x14\xa8\x53\x81\x0b\xc3\x64\x80\xa3\x02\x0a\x41\x75\xf8" "\x44\x85\x93\x81\x22\x3c\xd8\x13\xe1\xbe\xf4\x59\x91\x1f\x6a\x44" "\x77\x5c\x69\xc4\x2f\x39\x5f\x0f\x2a\x8d\xeb\xba\xf8\xc3\x56\x6c" "\x3b\x36\xa7\xda\xbd\x4d\xa1\xb5\x4e\xc6\xa7\xa4\x3a\xec\x15\x2d" "\xa5\xb3\xea\x5a\xdc\xac\x46\xac\x01\x60\xd8\x43\xc8\x8e\x8b\xb1" "\x40\x4c\x95\x8b\x34\x41\x28\x52\x91\x28\x43\xd3\xa3\xb6\xa7\x55" "\x15\xe7\x5a\x96\xcb\xf1\xda\xe5\x55\xee\xfe\x1e\xbd\xd9\x41\xd3" "\x28\xfd\x97\xca\x57\x2b\x85\x9c\xa4\x30\x95\xaa\xa5\x57\xa2\x35" "\x15\x86\xcb\x61\x34\x41\xe4\xc7\x80\x20\x18\x21\x17\x09\x85\x0b" "\x14\x9d\x21\x68\x62\x1c\x08\x11\x64\x4b\x92\xf2\xd2\xd3\x2d\x2d" "\x6a\xc2\x73\x6b\x3c\x3c\x8b\x9e\xbc\x52\xaa\xa4\xab\x81\x6c\xf6" "\xfa\xbd\x70\xc5\xc6\x7b\xc2\xaa\x22\x4f\x58\x04\x87\x25\x6a\x27" "\x1d\xa4\x3d\x20\x75\x72\x01\x09\x71\xe5\x1c\x9e\xc3\x2e\x36\xf3" "\xd0\xc6\x35\x2a\x43\x4d\x2d\x0e\x2d\xb4\xa1\x49\xce\x65\x1e\x52" "\x9e\xa1\xf6\x09\xcc\xdc\x63\x66\xa8\x01\xe9\x3b\x0d\xd7\x5a\x85" "\xbb\xc5\x65\xc0\x7b\x2e\x46\xa9\xd9\x56\x1d\x4c\x92\x72\x26\x4e" "\x86\xd5\x68\xae\xc4\xaa\x55\xce\xd7\x83\x59\xb3\x81\xee\xce\x74" "\x39\x39\x31\x9f\x8a\x25\xe8\xa5\xa5\xe5\x81\xf2\x11\x23\xcb\xa1" "\x1e\x43\x12\xe3\xb1\x2a\x2b\xcd\xc8\x8d\x25\x96\xa4\x47\x7d\x95" "\xa5\xc6\x9f\x61\xe4\x25\xc6\x5e\x69\xc4\xe7\x29\x5b\x6e\xb6\xa4" "\xad\x0b\x4e\x72\x95\x25\x58\x56\x33\x9c\x67\xce\xef\x0f\x17\xbf" "\x4c\x7b\x2d\xe6\xfe\x76\x35\x27\x5a\x07\x97\x67\xe8\xae\x8d\x71" "\x0f\xb2\x13\x99\xb9\xbc\x14\xad\xb3\xb7\xe6\x11\x6f\xe0\xda\x58" "\xb1\x08\xac\xa6\x6c\x2d\x7f\x05\xb7\x56\xd2\xe6\xcf\xbb\x4d\x0c" "\xe3\x50\xb2\xec\x91\xf0\x4a\xb8\xd6\x22\xb8\xa7\xf6\x67\xaf\xcf" "\x63\x7e\xd7\xe7\x42\xd8\xbd\xc3\x71\xa1\xf2\x7e\x9b\xa8\x97\x83" "\x6e\xd1\xdc\x4b\x06\x11\x2d\xae\x26\x61\x98\x72\x10\xf4\x42\x5d" "\x20\x4a\xa3\x73\xd7\xf2\xcd\x3c\x48\x32\xe4\x03\x9f\x80\x37\x08" "\x36\x11\xd0\xcb\x97\x6c\x08\xed\x6d\x33\x24\xa2\x1b\xb4\x77\xdf" "\x61\x5d\x5f\xc1\x43\xc2\x82\xeb\x0f\x5d\x84\x08\x68\xaa\xa4\x01" "\xe1\x19\xdf\xbc\x31\x65\xfe\xd1\xf5\x7d\x7a\xb2\x2a\x33\x50\x21" "\x2a\x56\x9d\xb1\x81\xab\xdb\x35\x78\x30\x83\xd9\x89\x1d\x31\xac" "\x96\x14\x07\x61\xbc\x20\x68\x42\x85\x33\x19\xac\xbe\xdb\x34\x56" "\xf1\xd5\xfd\x29\xa9\x28\xdb\xcb\x4c\x5a\x23\xdc\xf5\x96\xc5\x10" "\xa3\x35\x5b\x14\x68\xd3\x61\x62\x64\x76\x26\xcb\x17\x3e\x34\x98" "\x04\xa3\xc4\x20\x38\x90\x92\xe3\xc8\x07\x2c\x36\x74\x66\x26\x0e" "\x29\x02\x64\x29\x2d\x21\xe6\x16\x9c\x6b\xce\xa3\x89\xd9\x4f\xd3" "\xc4\xbd\xc5\x87\x79\x9c\x65\xf6\x39\x45\x60\xe8\xce\x9e\xab\x6d" "\x13\x15\x22\xe1\x5e\x4b\x38\x42\xc4\x1e\xd5\x76\xe0\xc5\xeb\x85" "\x07\x2d\x0f\xb8\xb6\xa6\xd6\x6d\x71\x0d\xa2\x43\x4c\x25\xea\xfa" "\xa1\xae\x4c\xe4\x7d\xbd\x76\xa9\xfb\x06\xc2\x83\x42\xeb\xad\xe7" "\xe9\x5f\x68\x6f\xba\xfb\x2f\x07\xce\xb8\x13\xc1\x9b\xeb\xb0\x76" "\x45\x57\x28\x7b\xea\xbe\x0f\xf4\x30\x7b\xa0\xed\xe4\x22\x93\x21" "\xfc\xbc\xe0\xb9\x75\xc1\x4f\xfc\xef\xb6\xfa\xa1\xfc\x64\xa1\x4a" "\x82\xc7\x33\xad\x75\xed\x82\xbd\x3d\xdb\xf7\xa8\xbe\x5e\xbb\x36" "\x62\x04\x9a\x2e\xc5\xd9\x9e\x9c\x3a\x0b\x98\x0b\x57\xac\xf1\x24" "\x62\x58\x83\x15\x5b\xa6\xf2\xda\x34\x70\x03\xce\x0f\x93\x1b\x12" "\xc7\xce\x54\x87\x33\x15\xd6\x53\x25\x1f\x2a\x90\x87\x12\xe3\x78" "\xef\x55\x77\x4d\x4a\xd8\x7e\xef\xd2\xfd\xd1\xaf\x3a\xaf\x55\xdb" "\x6a\x2d\x3d\x42\xac\x51\x79\xee\x91\xab\xe1\x05\x2d\x3c\x80\xa2" "\x43\xad\x22\x2e\xd5\x33\x13\xa4\x9e\x00\xe0\x04\x10\x84\xc8\xf2" "\x19\x30\x92\x1f\xaa\xc3\x28\xc9\x76\x30\x3f\xe9\x10\x61\x5e\x79" "\xd5\xf7\xdf\xd0\x54\xdb\xae\xb6\xae\xfa\xe8\xa3\x57\xe0\x6c\x2d" "\xf7\xbd\x49\xd6\x6e\x76\x79\xcc\x54\x0c\x5f\xff\x00\xbb\x06\x98" "\xa6\x9e\x89\x61\xb4\x6f\xc3\xe3\x6a\xc2\x4f\x59\x03\xc9\x80\x2c" "\x59\x24\x44\x70\x38\xd5\x96\x6a\x9e\x8b\x81\x64\xe5\xbc\xa0\x3c" "\x33\xaf\x17\x9d\xff\x00\x71\x1a\xd1\x3a\x80\x66\xb3\xd9\x31\x77" "\x0d\x12\xbd\xae\x29\xb5\x6a\xd6\xcf\x8d\x68\x87\x75\xcd\xe8\x65" "\x5a\xbe\x3c\x04\x7b\x34\xdb\x54\x19\xa4\x63\x9c\x2a\x5d\x23\xbe" "\xf4\xb1\x1c\x4d\x90\xec\x92\x2f\x49\x71\xf7\x14\xf2\x97\x9f\x15" "\x57\xed\x13\x21\x2a\xf5\x33\xd1\x2a\x52\x52\xac\xb7\x62\xd1\xcb" "\x46\x73\x8c\x67\x28\x56\x77\x86\xbf\x6f\x2a\x4e\x73\xfe\x95\x65" "\x0b\x5a\x3e\x38\xfc\xfc\xaa\x56\x3f\x86\x73\xe3\xb9\x4a\x52\x84" "\xa5\x08\x4e\x12\x94\x27\x09\x4a\x53\x8c\x61\x29\x4a\x71\xf0\x4a" "\x53\x8c\x7e\x31\x8c\x63\x18\xc6\x31\x8f\xc6\x31\xf8\xc7\x9f\x7c" "\xd5\xbb\xae\x5e\xe2\x1f\xab\x6e\x24\x34\x00\x8a\x25\x83\x70\x40" "\x1c\xcc\xda\x45\x7f\x66\x4e\x30\x2e\x94\x7e\x74\x49\xf0\xe4\x4e" "\x06\x5c\xa8\x2f\x89\x21\x2e\x98\x0e\xd9\x21\xc2\x0b\x21\x0f\xc4" "\x16\x6e\x48\xd9\xe4\xe3\x4a\x19\x1e\x64\x67\x54\xff\x00\x3a\x6d" "\x4f\x62\xb5\x00\x4a\xaa\x51\xfd\x2d\xe8\x0e\x6c\xaf\xc6\x7d\x6d" "\xc8\x88\xc7\x67\xea\x8a\x58\x02\x73\xe3\x65\x4d\xc9\x24\xc0\x3d" "\x57\xa3\x2e\x53\x16\x99\x4f\xe5\xe7\x19\x97\x3e\x3b\xcf\xc9\x4b" "\x99\x7f\x33\x25\xa5\xdf\xba\x77\x2b\xd3\x3e\xc2\x7b\x8b\x94\x07" "\xe9\x52\x5b\x43\x87\x34\x14\x86\x37\xcf\x41\x6b\x8e\x6a\xa5\x22" "\xab\xdb\x96\xa2\xcf\x46\xd8\x9b\x45\x93\xef\xd6\xdf\x3e\x99\x9c" "\x7e\x29\x10\x6b\x6c\xa2\xb8\x43\x05\x09\x44\x70\x8c\xb8\xaa\x54" "\x7c\x30\x36\x5e\x1c\x5e\x5b\x9f\x6c\x0d\x81\xee\xa0\x93\x8d\x67" "\x55\xf3\x87\xaf\xaa\x6b\x58\xf9\xbe\xb2\x36\x07\x42\x6e\xbd\x96" "\xe3\x9f\x1f\x8f\xc9\xf4\x9d\xae\x6a\x7d\x4c\x96\xbe\x5f\xc7\xcd" "\xf3\xb2\xf7\xcd\xf0\xcf\xc3\xe4\xf8\xfe\x37\x4f\x1c\x4d\xf6\x40" "\xf1\x6b\x7c\x4e\xe0\xa6\x71\xad\x56\xa7\x1c\x5c\x15\x6b\xfc\xf3" "\x01\x5d\xac\xf1\x75\x9a\x72\x6b\xaa\x28\xc5\x88\x6d\xfb\x33\x85" "\xe0\x4e\x61\xab\xeb\x31\x2c\x71\x08\x73\x11\x3b\xfc\xb5\xc0\x96" "\xcc\x87\x24\x44\xb5\x9b\x9e\xb3\x71\xba\xe9\xed\xb1\x4e\xd7\x76" "\x6c\xd2\xb6\x05\xb7\x5a\xde\xeb\x34\x5b\x96\x16\xfb\x59\xa9\x5c" "\x4f\x55\xca\x8a\xac\x59\xb0\xe4\x54\x39\x25\xbc\x81\x37\x2a\x09" "\x5f\x9e\x3b\x6b\x7d\x1f\x69\xf3\x34\x85\x39\x84\xa7\x28\x0b\xd3" "\xfd\xfb\x4b\x7a\xea\xe7\xd2\x3c\xd3\xda\x15\x68\xbc\x73\xd3\x22" "\x6f\xd7\x72\x5b\x2b\x66\xee\xa8\x0d\x54\xe8\x5b\xf9\x92\x96\x92" "\x93\xea\x97\x4a\xc7\x43\x10\x46\x35\xc5\xc0\x60\x8a\xe4\xc1\xb5" "\x36\xc6\xae\xed\xf7\x70\xa5\x86\x99\x3d\x91\xf8\xfd\x4e\x53\xeb" "\xbb\xbd\x6d\xec\x8f\xd7\x89\x3d\x31\x7f\xd7\x78\xba\x50\xbb\x74" "\x9d\xf6\xac\x4e\xb9\x03\x9c\x79\xd5\xe1\xbd\x17\x68\xd9\x13\x0b" "\x45\x75\x88\x00\x1d\x1f\xae\x73\x6a\x1d\x5c\x6e\x44\x9f\xa6\xfa" "\x4e\xd8\x25\x8b\xc0\xbc\xb2\x99\xe3\x17\x24\xb3\x23\xe2\x48\x8b" "\xfa\x22\xe7\x7e\x8f\xe6\x3f\x5f\x55\x0d\x75\xd3\x51\x0b\xd7\xed" "\xd3\x6f\x97\x3b\x85\x42\x80\x7e\x5f\xdc\x1b\xd6\xba\xee\xc4\x80" "\xce\x06\xa9\x15\x8c\x97\x5f\x40\x69\xb2\x4d\xc5\xb2\x5c\x1e\x01" "\x87\x7e\xe0\x36\x6d\x78\x80\x4e\x3c\x02\xec\x90\x1d\x11\x81\x74" "\xa5\x8b\xa4\xa0\x56\x06\xd5\x79\x72\x85\x57\x3b\xb2\x2e\xae\x90" "\x18\x8d\x91\xb2\x0e\x44\x19\xaa\xb4\xcc\x08\xed\x46\xfa\xd7\x2b" "\x78\x58\x72\x5d\xbb\x5e\x49\xe7\xee\xf3\x8a\x9d\x22\xa4\x19\xc8" "\xe7\x08\xc3\x90\x9b\x35\x9a\xa4\x25\x8c\x4b\x9b\xa7\xf8\xbf\x81" "\xf5\xdf\x22\x66\xf1\x7e\x9f\x66\x3d\xbb\xfa\x73\x73\x4d\xfd\x67" "\x7b\xf4\xce\xc3\x62\x2e\x6f\xbb\x0c\xa2\xdc\x69\xfc\x8a\x17\x0e" "\x3a\x9e\x83\x46\xd7\xe3\x5e\x65\x86\xc0\x51\x00\xbb\x91\xe3\xe1" "\xc1\x16\xc4\xe9\x65\x5c\x14\x3e\x44\x6a\x6b\xd1\x1e\xb0\x36\xdd" "\x0b\x7d\x8a\xeb\xaf\x58\x5b\x64\x3f\x38\xed\x52\x76\xe8\x46\xf7" "\x86\x84\xb3\x93\xb1\x0b\xe5\xfd\xfd\x0d\xe9\x6d\xe4\xf1\x1b\x1d" "\x56\xb4\x34\xe4\x6a\xf5\xa4\x9c\x2c\xc9\x64\x94\xc1\xf5\x79\x6d" "\x12\x96\xf3\x47\xc5\x48\xa8\xdb\xd8\x95\x64\x29\xcf\xf6\x88\xf1" "\x95\x7a\x98\xe8\xbc\x27\x19\xce\x73\x61\xd1\xb8\xc6\x31\x8c\xe7" "\x39\xce\x77\x9e\xbc\xc6\x31\x8c\x63\xf3\x9c\xe7\x39\xc6\x31\x8f" "\xf7\xce\x7e\x1e\x3b\x7f\x0f\x0f\x0f\x13\x57\xb9\x0a\xe1\x0b\x64" "\x5f\x58\x40\xc6\xc7\x7a\x4b\xf2\x3d\xbc\x71\xf4\xa7\xd2\xca\x14" "\xe2\x98\x1a\x30\x1e\xe0\x26\x5a\x6a\xf0\x9c\x67\x38\x66\x00\xb8" "\x72\xe6\xbe\xac\xfe\x12\xd3\x0b\x56\x73\x8c\x63\xc7\x2b\xe1\xe2" "\xe8\xdd\x7b\xff\x00\xd8\xe5\x23\x6c\xce\xa8\x69\xcf\x5e\x3a\xef" "\x77\xea\xe5\xab\x0e\x82\xdb\xd9\xed\x7a\x9e\xb8\x6d\x51\x32\xdb" "\x79\xc3\x36\x9a\x2d\xa3\x50\x39\x65\x0a\x63\x0e\xe5\xd4\x39\x12" "\xbf\x8b\x98\xa4\xa1\x2d\xad\xb3\xcf\x65\x6a\x43\x78\xb3\x3b\x07" "\xd8\xd5\xea\xae\x76\xad\x6f\xf5\xff\x00\xca\x93\xab\x96\xb0\x64" "\xeb\xd6\x4a\xd5\x87\xba\xec\x24\x60\x97\x06\x76\x03\xe3\x4c\x07" "\x29\x11\x8e\x34\x25\x02\x64\x29\xf0\x25\x48\x85\x3a\x33\x8b\x7a" "\x3c\x86\x1e\x75\xa5\x61\xc6\x97\x9f\x8d\x25\xf5\xc9\xcd\xde\xc9" "\x7d\x77\xf2\xc8\x7e\x70\xaf\x73\x5f\x2d\xec\xa2\x51\x2d\x96\xfb" "\x89\xad\x80\x57\xb2\x36\x1d\x7d\x83\x45\xac\xf3\xdb\xcc\x6c\x31" "\x4f\xcf\x30\x58\xd0\x12\x28\x90\x50\x42\x86\xfb\x48\x16\x3c\xc5" "\x9c\xf8\xe7\xcc\x29\x88\xb3\x4a\x4b\x4e\x6c\xbc\xdb\xc7\xbb\xe9" "\xb6\xa0\x8b\x11\xa1\x7d\x73\xd7\xe9\xbf\x7e\xc2\x6c\x10\x8d\xee" "\x9d\xef\x63\x3a\xe0\xf5\xbe\x8c\x3e\xa1\xc7\xc5\xd1\x00\x44\x1e" "\xf3\x51\xf2\xe2\xb0\xe3\xb5\x13\x7f\x32\xf1\x8c\xa6\x22\xfe\x1f" "\x49\x4d\xbb\xcf\x3a\x5d\xed\x4c\xd2\xfc\x85\xed\x23\xd6\xc7\x50" "\xb6\x5b\x3a\x16\x83\xb8\x6f\xfd\x32\x3f\xaa\x36\x34\xbb\xf5\x96" "\xa9\xab\xcf\x9f\x8f\xac\xc3\xca\xd5\x8b\xd8\x48\x9e\x79\xaa\x30" "\x87\xca\x58\x4d\x59\x96\xb9\x4f\xc5\x1b\x1c\xd2\xda\x5b\xe6\x57" "\x29\xa1\x28\x7a\x2b\x5b\xff\x00\x12\x2f\x5e\x3f\xf3\xbb\x8e\x7f" "\xec\xc6\x98\xff\x00\xed\x3c\xa6\xdd\xa9\xdc\x7e\xa0\xf7\xd6\x99" "\x31\xa2\xf7\xaf\x6b\xe9\x82\x74\x4b\x3d\x8f\x5e\x58\x0b\x33\xab" "\xef\xc3\xaf\x84\x64\xb9\xae\xb6\x25\x5f\x62\x8f\x1c\xe3\xf4\x51" "\xb7\x96\xe3\x0e\x30\x42\xa9\x18\x39\xbf\x9e\x2a\x1f\x74\x19\x02" "\x2d\x43\x93\x06\x63\xb1\xa7\x47\x6a\xfa\x9b\x6c\xeb\xbd\xe9\xae" "\x6a\x7b\x6f\x53\x5a\x60\x5d\xb5\xcd\xe8\x67\xeb\x35\x3b\x48\xc6" "\xa6\xb3\x04\xc8\xdf\xb8\x7e\x26\x64\xb0\xc9\x18\xb0\xa7\x33\xf2" "\x4a\x8b\x22\x3b\x8d\x4b\x89\x1d\xf6\x9d\x65\xc4\x38\xd2\x54\x9c" "\xe3\xcd\x89\xe1\xe1\xe6\x3e\x70\x81\x45\x1d\x18\xf9\x31\x83\xc8" "\xbe\x14\x82\x4b\x87\x7a\x74\x28\xd2\xdd\x12\x55\x30\xe6\x0e\x49" "\x31\x8e\x48\x69\xc5\xc0\x20\x91\xe4\x48\x41\x4c\xd8\xb9\x6a\x4e" "\x21\xce\x99\x1b\x0e\xfd\x09\x4f\xa1\x79\x0f\x0f\x0f\x0f\x0f\x0f" "\x0f\x3f\x3c\xb8\x71\x27\xc7\x72\x24\xe8\xb1\xa6\xc5\x7b\x18\xc3" "\xb1\xa5\xb0\xd4\x98\xee\xe3\x19\xc6\x71\x87\x19\x79\x2b\x6d\x78" "\xc6\x71\x8c\xe3\x0a\x4e\x71\x8c\xe3\x19\xfe\x38\xf2\x3b\xfb\x8b" "\x48\xfe\x4e\xaa\xff\x00\x4f\x08\xff\x00\xc7\xe1\xfb\x8b\x48\xfe" "\x4e\xaa\xff\x00\x4f\x08\xff\x00\xc7\xe4\x95\x86\x18\x8a\xcb\x31" "\xa3\x32\xd4\x78\xf1\xdb\x43\x2c\x47\x61\xb4\x32\xcb\x2c\xb4\x9c" "\x21\xb6\x99\x69\xbc\x25\xb6\xdb\x6d\x18\xc2\x10\xda\x12\x94\xa1" "\x38\xc2\x53\x8c\x63\x18\xc7\x9d\xbe\x7f\xff\xd9" ; ================================================ FILE: suhosin_rfc1867.h ================================================ /* +----------------------------------------------------------------------+ | Suhosin Version 1 | +----------------------------------------------------------------------+ | Copyright (c) 2006-2007 The Hardened-PHP Project | | Copyright (c) 2007-2015 SektionEins GmbH | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Stefan Esser | +----------------------------------------------------------------------+ */ /* $Id: suhosin_rfc1867.h,v 1.1.1.1 2007-11-28 01:15:35 sesser Exp $ */ #ifndef SUHOSIN_RFC1867_H #define SUHOSIN_RFC1867_H #include "rfc1867.h" #include "SAPI.h" #define MULTIPART_CONTENT_TYPE "multipart/form-data" #ifdef MULTIPART_EVENT_START #define HAVE_RFC1867_CALLBACK 1 #else #define HAVE_RFC1867_CALLBACK 0 #define MULTIPART_EVENT_START 0 #define MULTIPART_EVENT_FORMDATA 1 #define MULTIPART_EVENT_FILE_START 2 #define MULTIPART_EVENT_FILE_DATA 3 #define MULTIPART_EVENT_FILE_END 4 #define MULTIPART_EVENT_END 5 typedef struct _multipart_event_start { size_t content_length; } multipart_event_start; typedef struct _multipart_event_formdata { size_t post_bytes_processed; char *name; char **value; size_t length; size_t *newlength; } multipart_event_formdata; typedef struct _multipart_event_file_start { size_t post_bytes_processed; char *name; char **filename; } multipart_event_file_start; typedef struct _multipart_event_file_data { size_t post_bytes_processed; off_t offset; char *data; size_t length; size_t *newlength; } multipart_event_file_data; typedef struct _multipart_event_file_end { size_t post_bytes_processed; char *temp_filename; int cancel_upload; } multipart_event_file_end; typedef struct _multipart_event_end { size_t post_bytes_processed; } multipart_event_end; #endif SAPI_POST_HANDLER_FUNC(suhosin_rfc1867_post_handler); // void destroy_uploaded_files_hash(TSRMLS_D); #if !HAVE_RFC1867_CALLBACK extern PHP_SUHOSIN_API int (*php_rfc1867_callback)(unsigned int event, void *event_data, void **extra TSRMLS_DC); #else extern PHPAPI int (*php_rfc1867_callback)(unsigned int event, void *event_data, void **extra TSRMLS_DC); #endif #endif /* SUHOSIN_RFC1867_H */ ================================================ FILE: tests/cookie/crypt.checkraddr_4.phpt ================================================ --TEST-- cookie encryption with checkraddr=4 --SKIPIF-- --INI-- suhosin.cookie.encrypt=1 suhosin.cookie.cryptkey= suhosin.cookie.cryptua=Off suhosin.cookie.cryptdocroot=Off suhosin.cookie.cryptraddr=0 suhosin.cookie.checkraddr=4 ;suhosin.cookie.cryptlist= ;suhosin.cookie.plainlist= --ENV-- return << --EXPECTF-- array(1) { ["foo"]=> string(3) "bar" } ================================================ FILE: tests/cookie/crypt.checkraddr_4_incorrect.phpt ================================================ --TEST-- cookie encryption with checkraddr=4 --SKIPIF-- --INI-- suhosin.cookie.encrypt=1 suhosin.cookie.cryptkey= suhosin.cookie.cryptua=Off suhosin.cookie.cryptdocroot=Off suhosin.cookie.cryptraddr=0 suhosin.cookie.checkraddr=4 ;suhosin.cookie.cryptlist= ;suhosin.cookie.plainlist= --ENV-- return << --EXPECTF-- array(0) { } ================================================ FILE: tests/cookie/crypt.cryptlist.phpt ================================================ --TEST-- cookie encryption with cryptlist set --SKIPIF-- --INI-- suhosin.cookie.encrypt=1 suhosin.cookie.cryptkey= suhosin.cookie.cryptua=0 suhosin.cookie.cryptdocroot=0 suhosin.cookie.cryptraddr=0 suhosin.cookie.checkraddr=0 suhosin.cookie.cryptlist=a,b,foo,c ;suhosin.cookie.plainlist= --ENV-- return << --EXPECTF-- Set-Cookie: foo=EgJxlQxzPwoAcVFj395vssv3hy1rAem1lH9qZYUvRi8. Set-Cookie: foo2=bar2 ================================================ FILE: tests/cookie/crypt.docroot.phpt ================================================ --TEST-- cookie encryption using document root --SKIPIF-- --INI-- suhosin.cookie.encrypt=1 suhosin.cookie.cryptkey= suhosin.cookie.cryptua=Off suhosin.cookie.cryptdocroot=On suhosin.cookie.cryptraddr=0 suhosin.cookie.checkraddr=0 ;suhosin.cookie.cryptlist= ;suhosin.cookie.plainlist= --ENV-- return << --EXPECTF-- Set-Cookie: foo=CY8CspcGmDQPsap1NqJO1uAjB6fobur1Os5ZCqFGhU8. ================================================ FILE: tests/cookie/crypt.invalid.phpt ================================================ --TEST-- cookie encryption with invalid cookie --SKIPIF-- --INI-- suhosin.cookie.encrypt=1 suhosin.cookie.cryptkey= suhosin.cookie.cryptua=Off suhosin.cookie.cryptdocroot=Off suhosin.cookie.cryptraddr=0 suhosin.cookie.checkraddr=0 ;suhosin.cookie.cryptlist= ;suhosin.cookie.plainlist= --ENV-- return << --EXPECTF-- array(0) { } ================================================ FILE: tests/cookie/crypt.key_default.phpt ================================================ --TEST-- cookie encryption with default key --SKIPIF-- --INI-- suhosin.cookie.encrypt=1 suhosin.cookie.cryptkey=D3F4UL7 suhosin.cookie.cryptua=0 suhosin.cookie.cryptdocroot=0 suhosin.cookie.cryptraddr=0 suhosin.cookie.checkraddr=0 ;suhosin.cookie.cryptlist= ;suhosin.cookie.plainlist= --COOKIE-- a=b --FILE-- --EXPECTF-- Set-Cookie: foo=Jq5FsTmo4aEWrLMKdoEeUuFxZ4IujCzrQjg-8Y-xphg. ================================================ FILE: tests/cookie/crypt.key_empty.phpt ================================================ --TEST-- cookie encryption with empty key --SKIPIF-- --INI-- suhosin.cookie.encrypt=1 suhosin.cookie.cryptkey= suhosin.cookie.cryptua=0 suhosin.cookie.cryptdocroot=0 suhosin.cookie.cryptraddr=0 suhosin.cookie.checkraddr=0 ;suhosin.cookie.cryptlist= ;suhosin.cookie.plainlist= --COOKIE-- a=b --FILE-- --EXPECTF-- Set-Cookie: foo=Jq5FsTmo4aEWrLMKdoEeUuFxZ4IujCzrQjg-8Y-xphg. ================================================ FILE: tests/cookie/crypt.key_empty_remote_addr.phpt ================================================ --TEST-- cookie encryption with empty key and REMOTE_ADDR set --SKIPIF-- --INI-- suhosin.cookie.encrypt=1 suhosin.cookie.cryptkey= suhosin.cookie.cryptua=0 suhosin.cookie.cryptdocroot=0 suhosin.cookie.cryptraddr=0 suhosin.cookie.checkraddr=0 ;suhosin.cookie.cryptlist= ;suhosin.cookie.plainlist= --ENV-- return << --EXPECTF-- Set-Cookie: foo=EgJxlQxzPwoAcVFj395vssv3hy1rAem1lH9qZYUvRi8. ================================================ FILE: tests/cookie/crypt.no_encryption.phpt ================================================ --TEST-- cookie without encryption --SKIPIF-- --INI-- suhosin.cookie.encrypt=0 --COOKIE-- a=b --FILE-- --EXPECTF-- Set-Cookie: foo=bar ================================================ FILE: tests/cookie/crypt.plainlist.phpt ================================================ --TEST-- cookie encryption with plainlist set --SKIPIF-- --INI-- suhosin.cookie.encrypt=1 suhosin.cookie.cryptkey= suhosin.cookie.cryptua=0 suhosin.cookie.cryptdocroot=0 suhosin.cookie.cryptraddr=0 suhosin.cookie.checkraddr=0 ;suhosin.cookie.cryptlist= suhosin.cookie.plainlist=a,b,foo2,c --ENV-- return << --EXPECTF-- Set-Cookie: foo=EgJxlQxzPwoAcVFj395vssv3hy1rAem1lH9qZYUvRi8. Set-Cookie: foo2=bar2 ================================================ FILE: tests/cookie/crypt.raddr_1.phpt ================================================ --TEST-- cookie encryption using REMOTE_ADDR (cryptraddr=1) --SKIPIF-- --INI-- suhosin.cookie.encrypt=1 suhosin.cookie.cryptkey= suhosin.cookie.cryptua=Off suhosin.cookie.cryptdocroot=Off suhosin.cookie.cryptraddr=1 suhosin.cookie.checkraddr=0 ;suhosin.cookie.cryptlist= ;suhosin.cookie.plainlist= --ENV-- return << --EXPECTF-- Set-Cookie: foo=lwB1g2gEIQbzRLsbKEyLcKlmu6kpBNRd6sft46-la-4. ================================================ FILE: tests/cookie/crypt.raddr_2.phpt ================================================ --TEST-- cookie encryption using REMOTE_ADDR (cryptraddr=2) --SKIPIF-- --INI-- suhosin.cookie.encrypt=1 suhosin.cookie.cryptkey= suhosin.cookie.cryptua=Off suhosin.cookie.cryptdocroot=Off suhosin.cookie.cryptraddr=2 suhosin.cookie.checkraddr=0 ;suhosin.cookie.cryptlist= ;suhosin.cookie.plainlist= --ENV-- return << --EXPECTF-- Set-Cookie: foo=iTnKmpON_PFkZ2Sv8omXt_myOw0LIxwZTmj5OZYQ5c8. ================================================ FILE: tests/cookie/crypt.raddr_3.phpt ================================================ --TEST-- cookie encryption using REMOTE_ADDR (cryptraddr=3) --SKIPIF-- --INI-- suhosin.cookie.encrypt=1 suhosin.cookie.cryptkey= suhosin.cookie.cryptua=Off suhosin.cookie.cryptdocroot=Off suhosin.cookie.cryptraddr=3 suhosin.cookie.checkraddr=0 ;suhosin.cookie.cryptlist= ;suhosin.cookie.plainlist= --ENV-- return << --EXPECTF-- Set-Cookie: foo=q2LriHN5UE2RN8YKu8N-k2hE5ShtXbk8vZooBU0idWg. ================================================ FILE: tests/cookie/crypt.raddr_4.phpt ================================================ --TEST-- cookie encryption using REMOTE_ADDR (cryptraddr=4) --SKIPIF-- --INI-- suhosin.cookie.encrypt=1 suhosin.cookie.cryptkey= suhosin.cookie.cryptua=Off suhosin.cookie.cryptdocroot=Off suhosin.cookie.cryptraddr=4 suhosin.cookie.checkraddr=0 ;suhosin.cookie.cryptlist= ;suhosin.cookie.plainlist= --ENV-- return << --EXPECTF-- Set-Cookie: foo=KYNdxYn5b1vujSEplr6YyON2A04YRH0YY4pCZWQDxG8. ================================================ FILE: tests/cookie/crypt.ua.phpt ================================================ --TEST-- cookie with encryption using HTTP_USER_AGENT --SKIPIF-- --INI-- suhosin.cookie.encrypt=1 suhosin.cookie.cryptkey= suhosin.cookie.cryptua=On suhosin.cookie.cryptdocroot=0 suhosin.cookie.cryptraddr=0 suhosin.cookie.checkraddr=0 ;suhosin.cookie.cryptlist= ;suhosin.cookie.plainlist= --ENV-- return << --EXPECTF-- Set-Cookie: foo=ZWvJsNdplAsT5Uz57vuUq7-_pbjyXTGeMrUfSrgre5w. ================================================ FILE: tests/empty.inc ================================================ ================================================ FILE: tests/executor/allow_symlink_off.phpt ================================================ --TEST-- suhosin.executor.allow_symlink=Off --SKIPIF-- --INI-- error_reporting=E_ALL open_basedir= suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.executor.allow_symlink=Off --FILE-- --EXPECTF-- Warning: symlink() expects exactly 2 parameters, 0 given in %s on line 2 ALERT - symlink called during open_basedir (attacker 'REMOTE_ADDR not set', file '%s', line 4) ================================================ FILE: tests/executor/allow_symlink_on.phpt ================================================ --TEST-- suhosin.executor.allow_symlink=On --SKIPIF-- --INI-- error_reporting=E_ALL open_basedir= suhosin.log.stdout=255 suhosin.log.script=0 suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.executor.allow_symlink=On --FILE-- --EXPECTF-- Warning: symlink() expects exactly 2 parameters, 0 given in %s on line 2 Warning: symlink() expects exactly 2 parameters, 0 given in %s on line 4 ================================================ FILE: tests/executor/disable_emod_off.phpt ================================================ --TEST-- Testing: suhosin.executor.disable_emodifier=0 --SKIPIF-- --INI-- error_reporting=E_ALL&~E_DEPRECATED suhosin.log.sapi=64 suhosin.executor.disable_emodifier=0 --FILE-- --EXPECTF-- string(5) "HALLO" string(5) "HALLO" ================================================ FILE: tests/executor/disable_emod_on.phpt ================================================ --TEST-- Testing: suhosin.executor.disable_emodifier=1 --SKIPIF-- --INI-- error_reporting=E_ALL&~E_DEPRECATED suhosin.log.sapi=64 suhosin.executor.disable_emodifier=1 --FILE-- --EXPECTF-- string(5) "HALLO" ALERT - use of preg_replace() with /e modifier is forbidden by configuration (attacker 'REMOTE_ADDR not set', file '%s', line 7) Fatal error: SUHOSIN - Use of preg_replace() with /e modifier is forbidden by configuration in %s(7) : regexp code on line %d ================================================ FILE: tests/executor/disable_eval_off.phpt ================================================ --TEST-- Testing: suhosin.executor.disable_eval=0 --SKIPIF-- --INI-- suhosin.log.sapi=64 suhosin.executor.disable_eval=0 --FILE-- --EXPECTF-- int(1) ================================================ FILE: tests/executor/disable_eval_on.phpt ================================================ --TEST-- Testing: suhosin.executor.disable_eval=1 --SKIPIF-- --INI-- suhosin.log.sapi=64 suhosin.executor.disable_eval=1 --FILE-- --EXPECTF-- ALERT - use of eval is forbidden by configuration (attacker 'REMOTE_ADDR not set', file '%s', line 3) Fatal error: SUHOSIN - Use of eval is forbidden by configuration in %s(3) : eval()'d code on line %d ================================================ FILE: tests/executor/eval_blacklist.phpt ================================================ --TEST-- Testing: suhosin.executor.eval.blacklist=max --SKIPIF-- --INI-- suhosin.log.sapi=64 suhosin.executor.disable_eval=0 suhosin.executor.eval.blacklist=max --FILE-- --EXPECTF-- ALERT - function within eval blacklist called: max() (attacker 'REMOTE_ADDR not set', file '%s', line 4) Warning: max() has been disabled for security reasons in %s : eval()'d code on line 2 ================================================ FILE: tests/executor/eval_blacklist_printf.phpt ================================================ --TEST-- Testing: suhosin.executor.eval.blacklist=printf via call_user_func --SKIPIF-- --INI-- suhosin.log.sapi=64 suhosin.executor.disable_eval=0 suhosin.executor.eval.blacklist=printf --FILE-- --EXPECTF-- ALERT - function within eval blacklist called: printf() (attacker 'REMOTE_ADDR not set', file '%s : eval()'d code', line 1) Warning: printf() has been disabled for security reasons in %s : eval()'d code on line 1 ================================================ FILE: tests/executor/eval_blacklist_printf_function_exists.phpt ================================================ --TEST-- Testing: suhosin.executor.eval.blacklist=printf with function_exists() --SKIPIF-- --INI-- suhosin.log.sapi=64 suhosin.executor.disable_eval=0 suhosin.executor.eval.blacklist=printf,max --FILE-- --EXPECTF-- bool(true) bool(false) bool(true) bool(false) bool(true) ================================================ FILE: tests/executor/eval_whitelist_absmax.phpt ================================================ --TEST-- Testing: suhosin.executor.eval.whitelist=abs,max --SKIPIF-- --INI-- suhosin.log.sapi=64 suhosin.executor.disable_eval=0 suhosin.executor.eval.whitelist=abs,max --FILE-- --EXPECTF-- ================================================ FILE: tests/executor/eval_whitelist_call_user_func.phpt ================================================ --TEST-- Testing: suhosin.executor.eval.whitelist=printf via call_user_func --SKIPIF-- --INI-- suhosin.log.sapi=64 suhosin.executor.eval.whitelist=call_user_func --FILE-- --EXPECTF-- ALERT - function outside of eval whitelist called: printf() (attacker 'REMOTE_ADDR not set', file '%s : eval()'d code', line 1) Warning: printf() has been disabled for security reasons in %s : eval()'d code on line 1 ================================================ FILE: tests/executor/function_blacklist.phpt ================================================ --TEST-- Testing: suhosin.executor.func.blacklist=max --SKIPIF-- --INI-- suhosin.log.sapi=64 suhosin.executor.func.blacklist=max --FILE-- --EXPECTF-- ALERT - function within blacklist called: max() (attacker 'REMOTE_ADDR not set', file '%s', line 3) Warning: max() has been disabled for security reasons in %s on line 3 ================================================ FILE: tests/executor/function_blacklist_printf.phpt ================================================ --TEST-- Testing: suhosin.executor.func.blacklist=printf --SKIPIF-- --INI-- suhosin.log.sapi=64 suhosin.executor.func.blacklist=printf --FILE-- --EXPECTF-- ALERT - function within blacklist called: printf() (attacker 'REMOTE_ADDR not set', file '%s', line 2) Warning: printf() has been disabled for security reasons in %s on line 2 ================================================ FILE: tests/executor/function_blacklist_printf_function_exists.phpt ================================================ --TEST-- Testing: suhosin.executor.func.blacklist=printf with function_exists() --SKIPIF-- --INI-- suhosin.log.sapi=64 suhosin.executor.func.blacklist=printf,max --FILE-- --EXPECTF-- bool(true) bool(false) bool(true) bool(false) bool(true) ================================================ FILE: tests/executor/function_call_user_func.phpt ================================================ --TEST-- Testing if call_user_func() actually works --SKIPIF-- --INI-- suhosin.log.sapi=64 --FILE-- --EXPECTF-- hello ================================================ FILE: tests/executor/function_whitelist.phpt ================================================ --TEST-- Testing: suhosin.executor.func.whitelist=abs --SKIPIF-- --INI-- suhosin.log.sapi=64 suhosin.executor.func.whitelist=abs --FILE-- --EXPECTF-- ALERT - function outside of whitelist called: max() (attacker 'REMOTE_ADDR not set', file '%s', line 3) Warning: max() has been disabled for security reasons in %s on line 3 ================================================ FILE: tests/executor/function_whitelist_absmax.phpt ================================================ --TEST-- Testing: suhosin.executor.func.whitelist=abs,max --SKIPIF-- --INI-- suhosin.log.sapi=64 suhosin.executor.func.whitelist=abs,max --FILE-- --EXPECTF-- ================================================ FILE: tests/executor/function_whitelist_call_user_func.phpt ================================================ --TEST-- Testing: suhosin.executor.func.whitelist=call_user_func --SKIPIF-- --INI-- suhosin.log.sapi=64 suhosin.executor.func.whitelist=call_user_func --FILE-- --EXPECTF-- ALERT - function outside of whitelist called: printf() (attacker 'REMOTE_ADDR not set', file '%s', line 2) Warning: printf() has been disabled for security reasons in %s on line 2 ================================================ FILE: tests/executor/function_whitelist_function_exists.phpt ================================================ --TEST-- Testing: suhosin.executor.func.whitelist with function_exists() --SKIPIF-- --INI-- suhosin.log.sapi=64 suhosin.executor.func.whitelist=printf,max,function_exists,var_dump --FILE-- --EXPECTF-- bool(false) bool(true) bool(false) bool(true) bool(false) ================================================ FILE: tests/executor/function_whitelist_maxabs.phpt ================================================ --TEST-- Testing: suhosin.executor.func.whitelist=max,abs --SKIPIF-- --INI-- suhosin.log.sapi=64 suhosin.executor.func.whitelist=max,abs --FILE-- --EXPECTF-- ================================================ FILE: tests/executor/function_whitelist_without_function_exists.phpt ================================================ --TEST-- Testing: suhosin.executor.func.whitelist without function_exists() --SKIPIF-- --INI-- suhosin.log.sapi=64 suhosin.executor.func.whitelist=printf,max,var_dump --FILE-- --EXPECTF-- ALERT - function outside of whitelist called: function_exists() (attacker 'REMOTE_ADDR not set', file '%s', line 2) Warning: function_exists() has been disabled for security reasons in %s on line 2 ================================================ FILE: tests/executor/memory_limit.phpt ================================================ --TEST-- memory_limit test: set suhosin hard_limit to normal limit --SKIPIF-- --INI-- memory_limit=16M suhosin.memory_limit=0 suhosin.log.syslog=0 suhosin.log.script=0 suhosin.log.sapi=2 --FILE-- --EXPECTF-- 13M 14M 15M 16M ALERT - script tried to increase memory_limit to 17825792 bytes which is above the allowed value (attacker 'REMOTE_ADDR not set', file '%s', line 6) 16M ALERT - script tried to increase memory_limit to 18874368 bytes which is above the allowed value (attacker 'REMOTE_ADDR not set', file '%s', line 7) 16M ================================================ FILE: tests/executor/memory_limit_64bit.phpt ================================================ --TEST-- memory_limit test: set suhosin hard_limit to normal limit (64 bit) --SKIPIF-- --INI-- memory_limit=16M suhosin.memory_limit=0 suhosin.log.syslog=0 suhosin.log.script=0 suhosin.log.sapi=2 --FILE-- --EXPECTF-- 13M 14M 15M 16M ALERT - script tried to increase memory_limit to 17825792 bytes which is above the allowed value (attacker 'REMOTE_ADDR not set', file '%s', line 6) 16M ALERT - script tried to increase memory_limit to 18874368 bytes which is above the allowed value (attacker 'REMOTE_ADDR not set', file '%s', line 7) 16M ALERT - script tried to increase memory_limit to 2147483648 bytes which is above the allowed value (attacker 'REMOTE_ADDR not set', file '%s', line 8) 16M ALERT - script tried to increase memory_limit to 3221225472 bytes which is above the allowed value (attacker 'REMOTE_ADDR not set', file '%s', line 9) 16M ALERT - script tried to increase memory_limit to 4294967296 bytes which is above the allowed value (attacker 'REMOTE_ADDR not set', file '%s', line 10) 16M ALERT - script tried to increase memory_limit to 5368709120 bytes which is above the allowed value (attacker 'REMOTE_ADDR not set', file '%s', line 11) 16M ================================================ FILE: tests/executor/memory_limit_64bit_10G.phpt ================================================ --TEST-- memory_limit test: set suhosin hard_limit to normal limit (64 bit) - 10 GB --SKIPIF-- --INI-- memory_limit=10G suhosin.memory_limit=0 suhosin.log.syslog=0 suhosin.log.script=0 suhosin.log.sapi=2 --FILE-- --EXPECTF-- 13M 14M 15M 16M 17M 18M 2G 3G 4G 5G ================================================ FILE: tests/executor/memory_limit_negative.phpt ================================================ --TEST-- memory_limit test: trying to set memory_limit to a negative value --SKIPIF-- --INI-- memory_limit=16M suhosin.memory_limit=17M suhosin.log.syslog=0 suhosin.log.script=0 suhosin.log.sapi=2 --FILE-- --EXPECTF-- ALERT - script tried to disable memory_limit by setting it to a negative value -%d bytes which is not allowed (attacker 'REMOTE_ADDR not set', file '%s', line 2) 16M ================================================ FILE: tests/executor/memory_limit_other_hardlimit.phpt ================================================ --TEST-- memory_limit test: set suhosin hard_limit to normal limit + 1M --SKIPIF-- --INI-- memory_limit=16M suhosin.memory_limit=17M suhosin.log.syslog=0 suhosin.log.script=0 suhosin.log.sapi=2 --FILE-- --EXPECTF-- 13M 14M 15M 16M 17M ALERT - script tried to increase memory_limit to %d bytes which is above the allowed value (attacker 'REMOTE_ADDR not set', file '%s', line 7) 17M ================================================ FILE: tests/executor/preg_replace.phpt ================================================ --TEST-- Testing protection against "\0" in preg_replace() first parameter --SKIPIF-- --INI-- suhosin.log.sapi=0 --FILE-- --EXPECT-- string(49) "One little boy with 2 dogs, 3 cats and four birds" bool(false) string(39) "The three cats play with the four birds" bool(false) ================================================ FILE: tests/executor/preg_replace_error.phpt ================================================ --TEST-- Testing protection against "\0" in preg_replace() first parameter (INCL. SUHOSIN ERROR MESSAGES) --SKIPIF-- --INI-- suhosin.log.sapi=64 --FILE-- --EXPECTF-- string(49) "One little boy with 2 dogs, 3 cats and four birds" ALERT - string termination attack on first preg_replace parameter detected (attacker 'REMOTE_ADDR not set', file '%s', line 14) bool(false) string(39) "The three cats play with the four birds" ALERT - string termination attack on first preg_replace parameter detected (attacker 'REMOTE_ADDR not set', file '%s', line 16) bool(false) ================================================ FILE: tests/executor/recursion_maxdepth.phpt ================================================ --TEST-- Testing: suhosin.executor.max_depth --SKIPIF-- --INI-- suhosin.log.sapi=64 suhosin.executor.max_depth=13 --FILE-- --EXPECTF-- 2 3 4 5 6 7 8 9 10 11 12 13 ALERT - maximum execution depth reached - script terminated (attacker 'REMOTE_ADDR not set', file '%s', line 5) ================================================ FILE: tests/executor/user_session_handler.phpt ================================================ --TEST-- Testing user session handler functions --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.script=0 suhosin.log.sapi=2 suhosin.session.encrypt=On session.save_path=SUHOSIN_TEST_CASE --FILE-- $sessionName"; } function sess_close() { $GLOBALS['msg'][] = "close"; } function sess_read($id) { $GLOBALS['msg'][] = "read $id"; return @$GLOBALS['test_array_session'][$id]; } function sess_write($id, $data) { $GLOBALS['msg'][] = "write $id - $data"; $GLOBALS['test_array_session'][$id] = $data; return true; } function sess_destroy($id) { $GLOBALS['msg'][] = "destroy $id"; } function sess_gc($lifetime) { } session_set_save_handler ( "sess_open" , "sess_close" , "sess_read" , "sess_write" , "sess_destroy" , "sess_gc" ); session_id(md5("testsession1")); session_start(); $_SESSION['test1'] = "test"; $_SESSION['test2'] = 12345; $_SESSION['test3'] = array(); $_SESSION['test4'] = new StdClass(); session_write_close(); session_start(); var_dump($_SESSION); var_dump($msg); ?> --EXPECTF-- array(4) { ["test1"]=> string(4) "test" ["test2"]=> int(12345) ["test3"]=> array(0) { } ["test4"]=> object(stdClass)#1 (0) { } } array(6) { [0]=> string(35) "open SUHOSIN_TEST_CASE -> PHPSESSID" [1]=> string(37) "read 4cdacd154c45b08c35d83f3b514eddab" [2]=> string(%d) "write 4cdacd154c45b08c35d83f3b514eddab - %s" [3]=> string(5) "close" [4]=> string(35) "open SUHOSIN_TEST_CASE -> PHPSESSID" [5]=> string(37) "read 4cdacd154c45b08c35d83f3b514eddab" } ================================================ FILE: tests/filter/cookie_disallow_nul.phpt ================================================ --TEST-- suhosin input filter (suhosin.cookie.disallow_nul) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.disallow_nul=0 suhosin.cookie.disallow_nul=1 --SKIPIF-- --COOKIE-- var1=xx%001;var2=2;var3=xx%003;var4=4; --GET-- --POST-- --FILE-- --EXPECTF-- array(2) { ["var2"]=> string(1) "2" ["var4"]=> string(1) "4" } ALERT - ASCII-NUL chars not allowed within COOKIE variables - dropped variable 'var1' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - ASCII-NUL chars not allowed within COOKIE variables - dropped variable 'var3' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 2 request variables - (0 in GET, 0 in POST, 2 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/cookie_disallow_ws.phpt ================================================ --TEST-- suhosin input filter (suhosin.cookie.disallow_ws) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.cookie.disallow_ws=1 --SKIPIF-- --COOKIE-- +var1=1;var2=2;%20var3=3; var4=4; --GET-- --POST-- --FILE-- --EXPECTF-- array(2) { ["var2"]=> string(1) "2" ["var4"]=> string(1) "4" } ALERT - COOKIE variable name begins with disallowed whitespace - dropped variable ' var1' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - COOKIE variable name begins with disallowed whitespace - dropped variable ' var3' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 2 request variables - (0 in GET, 0 in POST, 2 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/cookie_max_array_depth.phpt ================================================ --TEST-- suhosin input filter (suhosin.cookie.max_array_depth) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_array_depth=0 suhosin.cookie.max_array_depth=4 --SKIPIF-- --COOKIE-- var1[]=1;var2[][]=2;var3[][][]=3;var4[][][][]=4;var5[][][][][]=5;var6[][][][][][]=6; --GET-- --POST-- --FILE-- --EXPECTF-- array(4) { ["var1"]=> array(1) { [0]=> string(1) "1" } ["var2"]=> array(1) { [0]=> array(1) { [0]=> string(1) "2" } } ["var3"]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> string(1) "3" } } } ["var4"]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> string(1) "4" } } } } } ALERT - configured COOKIE variable array depth limit exceeded - dropped variable 'var5[][][][][]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured COOKIE variable array depth limit exceeded - dropped variable 'var6[][][][][][]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 2 request variables - (0 in GET, 0 in POST, 2 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/cookie_max_array_index_length.phpt ================================================ --TEST-- suhosin input filter (suhosin.cookie.max_array_index_length) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_array_index_length=0 suhosin.cookie.max_array_index_length=3 --SKIPIF-- --COOKIE-- var1[AAA]=1;var2[BBBB]=1;var3[AAA][BBB]=1;var4[AAA][BBBB]=4;var5[AAA][BBB][CCC]=1;var6[AAA][BBBB][CCC]=1; --GET-- --POST-- --FILE-- --EXPECTF-- array(3) { ["var1"]=> array(1) { ["AAA"]=> string(1) "1" } ["var3"]=> array(1) { ["AAA"]=> array(1) { ["BBB"]=> string(1) "1" } } ["var5"]=> array(1) { ["AAA"]=> array(1) { ["BBB"]=> array(1) { ["CCC"]=> string(1) "1" } } } } ALERT - configured COOKIE variable array index length limit exceeded - dropped variable 'var2[BBBB]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured COOKIE variable array index length limit exceeded - dropped variable 'var4[AAA][BBBB]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured COOKIE variable array index length limit exceeded - dropped variable 'var6[AAA][BBBB][CCC]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 3 request variables - (0 in GET, 0 in POST, 3 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/cookie_max_name_length.phpt ================================================ --TEST-- suhosin input filter (suhosin.cookie.max_name_length) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_varname_length=0 suhosin.cookie.max_name_length=4 --SKIPIF-- --COOKIE-- var=0;var1=1;var2[]=2;var3[xxx]=3;var04=4;var05[]=5;var06[xxx]=6; --GET-- --POST-- --FILE-- --EXPECTF-- array(4) { ["var"]=> string(1) "0" ["var1"]=> string(1) "1" ["var2"]=> array(1) { [0]=> string(1) "2" } ["var3"]=> array(1) { ["xxx"]=> string(1) "3" } } ALERT - configured COOKIE variable name length limit exceeded - dropped variable 'var04' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured COOKIE variable name length limit exceeded - dropped variable 'var05[]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured COOKIE variable name length limit exceeded - dropped variable 'var06[xxx]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 3 request variables - (0 in GET, 0 in POST, 3 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/cookie_max_totalname_length.phpt ================================================ --TEST-- suhosin input filter (suhosin.cookie.max_totalname_length) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_totalname_length=0 suhosin.cookie.max_totalname_length=7 --SKIPIF-- --COOKIE-- var=0;var1=1;var2[]=2;var3[xxx]=3;var04=4;var05[]=5;var06[xxx]=6; --GET-- --POST-- --FILE-- --EXPECTF-- array(5) { ["var"]=> string(1) "0" ["var1"]=> string(1) "1" ["var2"]=> array(1) { [0]=> string(1) "2" } ["var04"]=> string(1) "4" ["var05"]=> array(1) { [0]=> string(1) "5" } } ALERT - configured COOKIE variable total name length limit exceeded - dropped variable 'var3[xxx]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured COOKIE variable total name length limit exceeded - dropped variable 'var06[xxx]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 2 request variables - (0 in GET, 0 in POST, 2 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/cookie_max_value_length.phpt ================================================ --TEST-- suhosin input filter (suhosin.cookie.max_value_length) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_value_length=0 suhosin.cookie.max_value_length=3 --SKIPIF-- --COOKIE-- var1=1;var2=22;var3=333;var4=4444;var5=55%00555;var6=666666; --GET-- --POST-- --FILE-- --EXPECTF-- array(3) { ["var1"]=> string(1) "1" ["var2"]=> string(2) "22" ["var3"]=> string(3) "333" } ALERT - configured COOKIE variable value length limit exceeded - dropped variable 'var4' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured COOKIE variable value length limit exceeded - dropped variable 'var5' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured COOKIE variable value length limit exceeded - dropped variable 'var6' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 3 request variables - (0 in GET, 0 in POST, 3 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/cookie_max_vars.phpt ================================================ --TEST-- suhosin input filter (suhosin.cookie.max_vars) --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.cookie.max_vars=3 --COOKIE-- a=1; b=2; c=3; d=4 --FILE-- --EXPECTF-- array(3) { ["a"]=> string(1) "1" ["b"]=> string(1) "2" ["c"]=> string(1) "3" } ALERT - configured COOKIE variable limit exceeded - dropped variable 'd' - all further COOKIE variables are dropped (attacker '%s', file '%s') ALERT - dropped 1 request variables - (0 in GET, 0 in POST, 1 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/filter_action_302.phpt ================================================ --TEST-- suhosin filter action: 302 redirect --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.stdout=0 suhosin.log.script=0 suhosin.request.disallow_nul=1 suhosin.filter.action=302,http://example.com/ --SKIPIF-- --CGI-- --COOKIE-- x=%00 --FILE-- --EXPECTHEADERS-- Status: 302 Moved Temporarily Location: http://example.com/ --EXPECTF-- ================================================ FILE: tests/filter/filter_action_php.phpt ================================================ --TEST-- suhosin filter action: fallback PHP file --FOO-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.stdout=0 suhosin.log.script=0 suhosin.request.disallow_nul=1 suhosin.filter.action=404,filter_action_php.phpt --SKIPIF-- --COOKIE-- x=%00 --FILE-- --EXPECTF-- %s %s %s FALLBACK ================================================ FILE: tests/filter/filter_logging_statistics.phpt ================================================ --TEST-- suhosin variable filter logging statistics --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.get.max_vars=5 error_reporting=E_ALL --SKIPIF-- --COOKIE-- --GET-- A=A&B=B&C=C&D=D&E=E&F=F&G=G& --POST-- --FILE-- --EXPECTF-- Notice: Undefined variable: counter in %s on line 2 array(5) { ["A"]=> string(1) "A" ["B"]=> string(1) "B" ["C"]=> string(1) "C" ["D"]=> string(1) "D" ["E"]=> string(1) "E" } ALERT - configured GET variable limit exceeded - dropped variable 'F' - all further GET variables are dropped (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 2 request variables - (2 in GET, 0 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/get_allow_ws.phpt ================================================ --TEST-- suhosin input filter (allow whitespace) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.stdout=255 suhosin.log.script=0 suhosin.request.disallow_ws=0 suhosin.get.disallow_ws=0 suhosin.post.disallow_ws=0 suhosin.cookie.disallow_ws=0 --SKIPIF-- --COOKIE-- +var1=1;var2=2;%20var3=3; var4=4; --GET-- +var1=1&var2=2&%20var3=3& var4=4& --POST-- +var1=1&var2=2&%20var3=3& var4=4& --FILE-- --EXPECTF-- array(4) { ["var1"]=> string(1) "1" ["var2"]=> string(1) "2" ["var3"]=> string(1) "3" ["var4"]=> string(1) "4" } array(4) { ["var1"]=> string(1) "1" ["var2"]=> string(1) "2" ["var3"]=> string(1) "3" ["var4"]=> string(1) "4" } array(4) { ["var1"]=> string(1) "1" ["var2"]=> string(1) "2" ["var3"]=> string(1) "3" ["var4"]=> string(1) "4" } ================================================ FILE: tests/filter/get_disallow_nul.phpt ================================================ --TEST-- suhosin input filter (suhosin.get.disallow_nul) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.disallow_nul=0 suhosin.get.disallow_nul=1 --SKIPIF-- --COOKIE-- --GET-- var1=xx%001&var2=2&var3=xx%003&var4=4& --POST-- --FILE-- --EXPECTF-- array(2) { ["var2"]=> string(1) "2" ["var4"]=> string(1) "4" } ALERT - ASCII-NUL chars not allowed within GET variables - dropped variable 'var1' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - ASCII-NUL chars not allowed within GET variables - dropped variable 'var3' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 2 request variables - (2 in GET, 0 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/get_disallow_ws.phpt ================================================ --TEST-- suhosin input filter (suhosin.get.disallow_ws) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.get.disallow_ws=1 --SKIPIF-- --COOKIE-- --GET-- +var1=1&var2=2&%20var3=3& var4=4& --POST-- --FILE-- --EXPECTF-- array(1) { ["var2"]=> string(1) "2" } ALERT - GET variable name begins with disallowed whitespace - dropped variable ' var1' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - GET variable name begins with disallowed whitespace - dropped variable ' var3' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - GET variable name begins with disallowed whitespace - dropped variable ' var4' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 3 request variables - (3 in GET, 0 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/get_filter_1.phpt ================================================ --TEST-- suhosin GET filter (disallowed variable names) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp --SKIPIF-- --COOKIE-- --GET-- HTTP_RAW_POST_DATA=HTTP_RAW_POST_DATA&HTTP_SESSION_VARS=HTTP_SESSION_VARS&harmless1=harmless1&HTTP_SERVER_VARS=HTTP_SERVER_VARS&HTTP_COOKIE_VARS=HTTP_COOKIE_VARS&HTTP_POST_FILES=HTTP_POST_FILES&HTTP_POST_VARS=HTTP_POST_VARS&HTTP_GET_VARS=HTTP_GET_VARS&HTTP_ENV_VARS=HTTP_ENV_VARS&_SESSION=_SESSION&_REQUEST=_REQUEST&GLOBALS=GLOBALS&_COOKIE=_COOKIE&_SERVER=_SERVER&_FILES=_FILES&_POST=_POST&_ENV=_ENV&_GET=_GET&harmless2=harmless2& --POST-- --FILE-- --EXPECTF-- array(2) { ["harmless1"]=> string(9) "harmless1" ["harmless2"]=> string(9) "harmless2" } ALERT - tried to register forbidden variable 'HTTP_RAW_POST_DATA' through GET variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'HTTP_SESSION_VARS' through GET variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'HTTP_SERVER_VARS' through GET variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'HTTP_COOKIE_VARS' through GET variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'HTTP_POST_FILES' through GET variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'HTTP_POST_VARS' through GET variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'HTTP_GET_VARS' through GET variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'HTTP_ENV_VARS' through GET variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_SESSION' through GET variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_REQUEST' through GET variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'GLOBALS' through GET variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_COOKIE' through GET variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_SERVER' through GET variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_FILES' through GET variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_POST' through GET variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_ENV' through GET variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_GET' through GET variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 17 request variables - (17 in GET, 0 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/get_filter_2.phpt ================================================ --TEST-- suhosin GET filter (suhosin.get.max_vars) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.get.max_vars=5 --SKIPIF-- --COOKIE-- --GET-- A=A&B=B&C=C&D=D&E=E&F=F&G=G& --POST-- --FILE-- --EXPECTF-- array(5) { ["A"]=> string(1) "A" ["B"]=> string(1) "B" ["C"]=> string(1) "C" ["D"]=> string(1) "D" ["E"]=> string(1) "E" } ALERT - configured GET variable limit exceeded - dropped variable 'F' - all further GET variables are dropped (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 2 request variables - (2 in GET, 0 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/get_globals.phpt ================================================ --TEST-- Testing: GLOBALS in GET --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=255 suhosin.log.script=255 suhosin.log.script.name=/tmp/xx --GET-- a=1&b=2&GLOBALS=123&c=3 --FILE-- --EXPECT-- string(1) "1" string(1) "2" string(1) "3" int(5) ================================================ FILE: tests/filter/get_max_array_depth.phpt ================================================ --TEST-- suhosin input filter (suhosin.get.max_array_depth) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_array_depth=0 suhosin.get.max_array_depth=4 --SKIPIF-- --COOKIE-- --GET-- var1[]=1&var2[][]=2&var3[][][]=3&var4[][][][]=4&var5[][][][][]=5&var6[][][][][][]=6& --POST-- --FILE-- --EXPECTF-- array(4) { ["var1"]=> array(1) { [0]=> string(1) "1" } ["var2"]=> array(1) { [0]=> array(1) { [0]=> string(1) "2" } } ["var3"]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> string(1) "3" } } } ["var4"]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> string(1) "4" } } } } } ALERT - configured GET variable array depth limit exceeded - dropped variable 'var5[][][][][]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured GET variable array depth limit exceeded - dropped variable 'var6[][][][][][]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 2 request variables - (2 in GET, 0 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/get_max_array_index_length.phpt ================================================ --TEST-- suhosin input filter (suhosin.get.max_array_index_length) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_array_index_length=0 suhosin.get.max_array_index_length=3 --SKIPIF-- --COOKIE-- --GET-- var1[AAA]=1&var2[BBBB]=1&var3[AAA][BBB]=1&var4[AAA][BBBB]=4&var5[AAA][BBB][CCC]=1&var6[AAA][BBBB][CCC]=1 --POST-- --FILE-- --EXPECTF-- array(3) { ["var1"]=> array(1) { ["AAA"]=> string(1) "1" } ["var3"]=> array(1) { ["AAA"]=> array(1) { ["BBB"]=> string(1) "1" } } ["var5"]=> array(1) { ["AAA"]=> array(1) { ["BBB"]=> array(1) { ["CCC"]=> string(1) "1" } } } } ALERT - configured GET variable array index length limit exceeded - dropped variable 'var2[BBBB]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured GET variable array index length limit exceeded - dropped variable 'var4[AAA][BBBB]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured GET variable array index length limit exceeded - dropped variable 'var6[AAA][BBBB][CCC]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 3 request variables - (3 in GET, 0 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/get_max_name_length.phpt ================================================ --TEST-- suhosin input filter (suhosin.get.max_name_length) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_varname_length=0 suhosin.get.max_name_length=4 --SKIPIF-- --COOKIE-- --GET-- var=0&var1=1&var2[]=2&var3[xxx]=3&var04=4&var05[]=5&var06[xxx]=6& --POST-- --FILE-- --EXPECTF-- array(4) { ["var"]=> string(1) "0" ["var1"]=> string(1) "1" ["var2"]=> array(1) { [0]=> string(1) "2" } ["var3"]=> array(1) { ["xxx"]=> string(1) "3" } } ALERT - configured GET variable name length limit exceeded - dropped variable 'var04' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured GET variable name length limit exceeded - dropped variable 'var05[]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured GET variable name length limit exceeded - dropped variable 'var06[xxx]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 3 request variables - (3 in GET, 0 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/get_max_totalname_length.phpt ================================================ --TEST-- suhosin input filter (suhosin.get.max_totalname_length) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_totalname_length=0 suhosin.get.max_totalname_length=7 --SKIPIF-- --COOKIE-- --GET-- var=0&var1=1&var2[]=2&var3[xxx]=3&var04=4&var05[]=5&var06[xxx]=6& --POST-- --FILE-- --EXPECTF-- array(5) { ["var"]=> string(1) "0" ["var1"]=> string(1) "1" ["var2"]=> array(1) { [0]=> string(1) "2" } ["var04"]=> string(1) "4" ["var05"]=> array(1) { [0]=> string(1) "5" } } ALERT - configured GET variable total name length limit exceeded - dropped variable 'var3[xxx]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured GET variable total name length limit exceeded - dropped variable 'var06[xxx]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 2 request variables - (2 in GET, 0 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/get_max_value_length.phpt ================================================ --TEST-- suhosin input filter (suhosin.get.max_value_length) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_value_length=0 suhosin.get.max_value_length=3 --SKIPIF-- --COOKIE-- --GET-- var1=1&var2=22&var3=333&var4=4444&var5=55%00555&var6=666666& --POST-- --FILE-- --EXPECTF-- array(3) { ["var1"]=> string(1) "1" ["var2"]=> string(2) "22" ["var3"]=> string(3) "333" } ALERT - configured GET variable value length limit exceeded - dropped variable 'var4' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured GET variable value length limit exceeded - dropped variable 'var5' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured GET variable value length limit exceeded - dropped variable 'var6' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 3 request variables - (3 in GET, 0 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/input_filter_request_max_value_length.phpt ================================================ --TEST-- suhosin input filter (suhosin.request.max_value_length) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_value_length=3 --SKIPIF-- --COOKIE-- var1=1;var2=22;var3=333;var4=4444;var5=55%00555;var6=666666; --GET-- var1=1&var2=22&var3=333&var4=4444&var5=55%00555&var6=666666& --POST-- var1=1&var2=22&var3=333&var4=4444&var5=55%00555&var6=666666& --FILE-- --EXPECTF-- array(3) { ["var1"]=> string(1) "1" ["var2"]=> string(2) "22" ["var3"]=> string(3) "333" } array(3) { ["var1"]=> string(1) "1" ["var2"]=> string(2) "22" ["var3"]=> string(3) "333" } array(3) { ["var1"]=> string(1) "1" ["var2"]=> string(2) "22" ["var3"]=> string(3) "333" } ALERT - configured request variable value length limit exceeded - dropped variable 'var4' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable value length limit exceeded - dropped variable 'var5' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable value length limit exceeded - dropped variable 'var6' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable value length limit exceeded - dropped variable 'var4' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable value length limit exceeded - dropped variable 'var5' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable value length limit exceeded - dropped variable 'var6' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable value length limit exceeded - dropped variable 'var4' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable value length limit exceeded - dropped variable 'var5' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable value length limit exceeded - dropped variable 'var6' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 9 request variables - (3 in GET, 3 in POST, 3 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/post_disallow_nul.phpt ================================================ --TEST-- suhosin input filter (suhosin.post.disallow_nul) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.disallow_nul=0 suhosin.post.disallow_nul=1 --SKIPIF-- --COOKIE-- --GET-- --POST-- var1=xx%001&var2=2&var3=xx%003&var4=4& --FILE-- --EXPECTF-- array(2) { ["var2"]=> string(1) "2" ["var4"]=> string(1) "4" } ALERT - ASCII-NUL chars not allowed within POST variables - dropped variable 'var1' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - ASCII-NUL chars not allowed within POST variables - dropped variable 'var3' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 2 request variables - (0 in GET, 2 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/post_disallow_ws.phpt ================================================ --TEST-- suhosin input filter (suhosin.post.disallow_ws) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.post.disallow_ws=1 --SKIPIF-- --COOKIE-- --GET-- --POST-- +var1=1&var2=2&%20var3=3& var4=4& --FILE-- --EXPECTF-- array(1) { ["var2"]=> string(1) "2" } ALERT - POST variable name begins with disallowed whitespace - dropped variable ' var1' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - POST variable name begins with disallowed whitespace - dropped variable ' var3' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - POST variable name begins with disallowed whitespace - dropped variable ' var4' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 3 request variables - (0 in GET, 3 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/post_fileupload_array_index_blacklist.phpt ================================================ --TEST-- suhosin file upload filter (array index whitelist) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp file_uploads=1 suhosin.request.array_index_blacklist=ABC --SKIPIF-- --COOKIE-- --GET-- --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="fn[foo][bar]" ok -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="fn[foo][BAR]" bad -----------------------------20896060251896012921717172737-- --FILE-- --EXPECTF-- array(1) { ["fn"]=> array(1) { ["foo"]=> array(1) { ["bar"]=> string(2) "ok" } } } ALERT - array index contains blacklisted characters - dropped variable 'fn[foo][BAR]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 1 request variables - (0 in GET, 1 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/post_fileupload_array_index_whitelist.phpt ================================================ --TEST-- suhosin file upload filter (array index whitelist) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp file_uploads=1 suhosin.request.array_index_whitelist=abcdefghijklmnopqrstuvwxyz --SKIPIF-- --COOKIE-- --GET-- --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="fn[foo][bar]" ok -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="fn[foo][BAR]" bad -----------------------------20896060251896012921717172737-- --FILE-- --EXPECTF-- array(1) { ["fn"]=> array(1) { ["foo"]=> array(1) { ["bar"]=> string(2) "ok" } } } ALERT - array index contains not whitelisted characters - dropped variable 'fn[foo][BAR]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 1 request variables - (0 in GET, 1 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/post_fileupload_filter_1.phpt ================================================ --TEST-- suhosin rfc1867 file upload filter (disallowed variable names) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp file_uploads=1 upload_max_filesize=1024 --SKIPIF-- --COOKIE-- --GET-- --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="HTTP_RAW_POST_DATA" HTTP_RAW_POST_DATA -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="HTTP_SESSION_VARS" HTTP_SESSION_VARS -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="HTTP_SERVER_VARS" HTTP_SERVER_VARS -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="HTTP_COOKIE_VARS" HTTP_COOKIE_VARS -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="HTTP_POST_FILES" HTTP_POST_FILES -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="HTTP_POST_VARS" HTTP_POST_VARS -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="HTTP_GET_VARS" HTTP_GET_VARS -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="HTTP_ENV_VARS" HTTP_ENV_VARS -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="_SESSION" _SESSION -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="_REQUEST" _REQUEST -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="GLOBALS" GLOBALS -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="_COOKIE" _COOKIE -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="_SERVER" _SERVER -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="_FILES" _FILES -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="_POST" _POST -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="_ENV" _ENV -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="_GET" _GET -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="harmless" harmless -----------------------------20896060251896012921717172737-- --FILE-- --EXPECTF-- array(1) { ["harmless"]=> string(8) "harmless" } ALERT - tried to register forbidden variable 'HTTP_RAW_POST_DATA' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'HTTP_SESSION_VARS' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'HTTP_SERVER_VARS' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'HTTP_COOKIE_VARS' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'HTTP_POST_FILES' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'HTTP_POST_VARS' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'HTTP_GET_VARS' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'HTTP_ENV_VARS' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_SESSION' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_REQUEST' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'GLOBALS' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_COOKIE' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_SERVER' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_FILES' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_POST' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_ENV' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_GET' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 17 request variables - (0 in GET, 17 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/post_fileupload_filter_2.phpt ================================================ --TEST-- suhosin rfc1867 file upload filter (suhosin.post.max_vars) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.post.max_vars=5 file_uploads=1 upload_max_filesize=1024 --SKIPIF-- --COOKIE-- --GET-- --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="A" A -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="B" B -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="C" C -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="D" D -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="E" E -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="F" F -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="G" G -----------------------------20896060251896012921717172737-- --FILE-- --EXPECTF-- array(5) { ["A"]=> string(1) "A" ["B"]=> string(1) "B" ["C"]=> string(1) "C" ["D"]=> string(1) "D" ["E"]=> string(1) "E" } ALERT - configured POST variable limit exceeded - dropped variable 'F' - all further POST variables are dropped (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 2 request variables - (0 in GET, 2 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/post_filter_1.phpt ================================================ --TEST-- suhosin POST filter (disallowed variable names) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp --SKIPIF-- --COOKIE-- --GET-- --POST-- HTTP_RAW_POST_DATA=HTTP_RAW_POST_DATA&HTTP_SESSION_VARS=HTTP_SESSION_VARS&harmless1=harmless1&HTTP_SERVER_VARS=HTTP_SERVER_VARS&HTTP_COOKIE_VARS=HTTP_COOKIE_VARS&HTTP_POST_FILES=HTTP_POST_FILES&HTTP_POST_VARS=HTTP_POST_VARS&HTTP_GET_VARS=HTTP_GET_VARS&HTTP_ENV_VARS=HTTP_ENV_VARS&_SESSION=_SESSION&_REQUEST=_REQUEST&GLOBALS=GLOBALS&_COOKIE=_COOKIE&_SERVER=_SERVER&_FILES=_FILES&_POST=_POST&_ENV=_ENV&_GET=_GET&harmless2=harmless2& --FILE-- --EXPECTF-- array(2) { ["harmless1"]=> string(9) "harmless1" ["harmless2"]=> string(9) "harmless2" } ALERT - tried to register forbidden variable 'HTTP_RAW_POST_DATA' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'HTTP_SESSION_VARS' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'HTTP_SERVER_VARS' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'HTTP_COOKIE_VARS' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'HTTP_POST_FILES' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'HTTP_POST_VARS' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'HTTP_GET_VARS' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'HTTP_ENV_VARS' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_SESSION' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_REQUEST' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable 'GLOBALS' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_COOKIE' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_SERVER' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_FILES' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_POST' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_ENV' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - tried to register forbidden variable '_GET' through POST variables (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 17 request variables - (0 in GET, 17 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/post_filter_2.phpt ================================================ --TEST-- suhosin POST filter (suhosin.post.max_vars) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.post.max_vars=5 --SKIPIF-- --COOKIE-- --GET-- --POST-- A=A&B=B&C=C&D=D&E=E&F=F&G=G& --FILE-- --EXPECTF-- array(5) { ["A"]=> string(1) "A" ["B"]=> string(1) "B" ["C"]=> string(1) "C" ["D"]=> string(1) "D" ["E"]=> string(1) "E" } ALERT - configured POST variable limit exceeded - dropped variable 'F' - all further POST variables are dropped (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 2 request variables - (0 in GET, 2 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/post_filter_empty_avar.phpt ================================================ --TEST-- suhosin POST filter with empty array variable --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.stdout=255 suhosin.log.script=0 --SKIPIF-- --COOKIE-- --GET-- --POST-- a[]=&a[]=test --FILE-- --EXPECTF-- array(1) { ["a"]=> array(2) { [0]=> string(0) "" [1]=> string(4) "test" } } ================================================ FILE: tests/filter/post_filter_empty_var.phpt ================================================ --TEST-- suhosin POST filter with empty variable --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.stdout=255 suhosin.log.script=0 --SKIPIF-- --COOKIE-- --GET-- --POST-- A=&B=test --FILE-- --EXPECTF-- array(2) { ["A"]=> string(0) "" ["B"]=> string(4) "test" } ================================================ FILE: tests/filter/post_max_array_depth.phpt ================================================ --TEST-- suhosin input filter (suhosin.post.max_array_depth) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_array_depth=0 suhosin.post.max_array_depth=4 --SKIPIF-- --COOKIE-- --GET-- --POST-- var1[]=1&var2[][]=2&var3[][][]=3&var4[][][][]=4&var5[][][][][]=5&var6[][][][][][]=6& --FILE-- --EXPECTF-- array(4) { ["var1"]=> array(1) { [0]=> string(1) "1" } ["var2"]=> array(1) { [0]=> array(1) { [0]=> string(1) "2" } } ["var3"]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> string(1) "3" } } } ["var4"]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> string(1) "4" } } } } } ALERT - configured POST variable array depth limit exceeded - dropped variable 'var5[][][][][]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured POST variable array depth limit exceeded - dropped variable 'var6[][][][][][]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 2 request variables - (0 in GET, 2 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/post_max_array_depth_rfc1867.phpt ================================================ --TEST-- suhosin input filter (suhosin.post.max_array_depth - RFC1867 version) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_array_depth=0 suhosin.post.max_array_depth=4 --SKIPIF-- --COOKIE-- --GET-- --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var1[]" 1 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var2[][]" 2 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var3[][][]" 3 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var4[][][][]" 4 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var5[][][][][]" 5 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var6[][][][][][]" 6 -----------------------------20896060251896012921717172737-- --FILE-- --EXPECTF-- array(4) { ["var1"]=> array(1) { [0]=> string(1) "1" } ["var2"]=> array(1) { [0]=> array(1) { [0]=> string(1) "2" } } ["var3"]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> string(1) "3" } } } ["var4"]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> string(1) "4" } } } } } ALERT - configured POST variable array depth limit exceeded - dropped variable 'var5[][][][][]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured POST variable array depth limit exceeded - dropped variable 'var6[][][][][][]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 2 request variables - (0 in GET, 2 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/post_max_array_index_length.phpt ================================================ --TEST-- suhosin input filter (suhosin.post.max_array_index_length) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_array_index_length=0 suhosin.post.max_array_index_length=3 --SKIPIF-- --COOKIE-- --GET-- --POST-- var1[AAA]=1&var2[BBBB]=1&var3[AAA][BBB]=1&var4[AAA][BBBB]=4&var5[AAA][BBB][CCC]=1&var6[AAA][BBBB][CCC]=1 --FILE-- --EXPECTF-- array(3) { ["var1"]=> array(1) { ["AAA"]=> string(1) "1" } ["var3"]=> array(1) { ["AAA"]=> array(1) { ["BBB"]=> string(1) "1" } } ["var5"]=> array(1) { ["AAA"]=> array(1) { ["BBB"]=> array(1) { ["CCC"]=> string(1) "1" } } } } ALERT - configured POST variable array index length limit exceeded - dropped variable 'var2[BBBB]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured POST variable array index length limit exceeded - dropped variable 'var4[AAA][BBBB]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured POST variable array index length limit exceeded - dropped variable 'var6[AAA][BBBB][CCC]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 3 request variables - (0 in GET, 3 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/post_max_array_index_length_rfc1867.phpt ================================================ --TEST-- suhosin input filter (suhosin.post.max_array_index_length - RFC1867 version) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_array_index_length=0 suhosin.post.max_array_index_length=3 --SKIPIF-- --COOKIE-- --GET-- --POST-- var1[AAA]=1&var2[BBBB]=1&var3[AAA][BBB]=1&var4[AAA][BBBB]=4&var5[AAA][BBB][CCC]=1&var6[AAA][BBBB][CCC]=1 --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var1[AAA]" 1 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var2[BBBB]" 1 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var3[AAA][BBB]" 1 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var4[AAA][BBBB]" 1 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var5[AAA][BBB][CCC]" 1 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var6[AAA][BBBB][CCC]" 1 -----------------------------20896060251896012921717172737-- --FILE-- --EXPECTF-- array(3) { ["var1"]=> array(1) { ["AAA"]=> string(1) "1" } ["var3"]=> array(1) { ["AAA"]=> array(1) { ["BBB"]=> string(1) "1" } } ["var5"]=> array(1) { ["AAA"]=> array(1) { ["BBB"]=> array(1) { ["CCC"]=> string(1) "1" } } } } ALERT - configured POST variable array index length limit exceeded - dropped variable 'var2[BBBB]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured POST variable array index length limit exceeded - dropped variable 'var4[AAA][BBBB]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured POST variable array index length limit exceeded - dropped variable 'var6[AAA][BBBB][CCC]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 3 request variables - (0 in GET, 3 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/post_max_name_length.phpt ================================================ --TEST-- suhosin input filter (suhosin.post.max_name_length) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_varname_length=0 suhosin.post.max_name_length=4 --SKIPIF-- --COOKIE-- --GET-- --POST-- var=0&var1=1&var2[]=2&var3[xxx]=3&var04=4&var05[]=5&var06[xxx]=6& --FILE-- --EXPECTF-- array(4) { ["var"]=> string(1) "0" ["var1"]=> string(1) "1" ["var2"]=> array(1) { [0]=> string(1) "2" } ["var3"]=> array(1) { ["xxx"]=> string(1) "3" } } ALERT - configured POST variable name length limit exceeded - dropped variable 'var04' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured POST variable name length limit exceeded - dropped variable 'var05[]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured POST variable name length limit exceeded - dropped variable 'var06[xxx]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 3 request variables - (0 in GET, 3 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/post_max_name_length_rfc1867.phpt ================================================ --TEST-- suhosin input filter (suhosin.post.max_name_length - RFC1867 version) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_varname_length=0 suhosin.post.max_name_length=4 --SKIPIF-- --COOKIE-- --GET-- --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var" 0 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var1" 1 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var2[]" 2 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var3[xxx]" 3 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var04" 4 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var05[]" 5 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var06[xxx]" 6 -----------------------------20896060251896012921717172737-- --FILE-- --EXPECTF-- array(4) { ["var"]=> string(1) "0" ["var1"]=> string(1) "1" ["var2"]=> array(1) { [0]=> string(1) "2" } ["var3"]=> array(1) { ["xxx"]=> string(1) "3" } } ALERT - configured POST variable name length limit exceeded - dropped variable 'var04' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured POST variable name length limit exceeded - dropped variable 'var05[]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured POST variable name length limit exceeded - dropped variable 'var06[xxx]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 3 request variables - (0 in GET, 3 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/post_max_totalname_length.phpt ================================================ --TEST-- suhosin input filter (suhosin.post.max_totalname_length) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_totalname_length=0 suhosin.post.max_totalname_length=7 --SKIPIF-- --COOKIE-- --GET-- --POST-- var=0&var1=1&var2[]=2&var3[xxx]=3&var04=4&var05[]=5&var06[xxx]=6& --FILE-- --EXPECTF-- array(5) { ["var"]=> string(1) "0" ["var1"]=> string(1) "1" ["var2"]=> array(1) { [0]=> string(1) "2" } ["var04"]=> string(1) "4" ["var05"]=> array(1) { [0]=> string(1) "5" } } ALERT - configured POST variable total name length limit exceeded - dropped variable 'var3[xxx]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured POST variable total name length limit exceeded - dropped variable 'var06[xxx]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 2 request variables - (0 in GET, 2 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/post_max_totalname_length_rfc1867.phpt ================================================ --TEST-- suhosin input filter (suhosin.post.max_totalname_length - RFC1867 version) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_totalname_length=0 suhosin.post.max_totalname_length=7 --SKIPIF-- --COOKIE-- --GET-- --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var" 0 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var1" 1 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var2[]" 2 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var3[xxx]" 3 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var04" 4 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var05[]" 5 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="var06[xxx]" 6 -----------------------------20896060251896012921717172737-- --FILE-- --EXPECTF-- array(5) { ["var"]=> string(1) "0" ["var1"]=> string(1) "1" ["var2"]=> array(1) { [0]=> string(1) "2" } ["var04"]=> string(1) "4" ["var05"]=> array(1) { [0]=> string(1) "5" } } ALERT - configured POST variable total name length limit exceeded - dropped variable 'var3[xxx]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured POST variable total name length limit exceeded - dropped variable 'var06[xxx]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 2 request variables - (0 in GET, 2 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/post_max_value_length.phpt ================================================ --TEST-- suhosin input filter (suhosin.post.max_value_length) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_value_length=0 suhosin.post.max_value_length=3 --SKIPIF-- --COOKIE-- --GET-- --POST-- var1=1&var2=22&var3=333&var4=4444&var5=55%00555&var6=666666& --FILE-- --EXPECTF-- array(3) { ["var1"]=> string(1) "1" ["var2"]=> string(2) "22" ["var3"]=> string(3) "333" } ALERT - configured POST variable value length limit exceeded - dropped variable 'var4' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured POST variable value length limit exceeded - dropped variable 'var5' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured POST variable value length limit exceeded - dropped variable 'var6' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 3 request variables - (0 in GET, 3 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/request_array_index_blacklist.phpt ================================================ --TEST-- suhosin input filter (suhosin.request.array_index_blacklist) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.array_index_blacklist="=ABC%{}\\$;" --SKIPIF-- --COOKIE-- var1[aaa]=1;var2[bbB]=1;var3[ccc][ccC]=1 --GET-- var1[aaa]=1&var2[bbB]=1&var3[ccc][ccC]=1 --POST-- var1[aaa]=1&var2[bbB]=1&var3[ccc][ccC]=1 --FILE-- --EXPECTF-- string(10) "=ABC%{}\$;" array(1) { ["var1"]=> array(1) { ["aaa"]=> string(1) "1" } } array(1) { ["var1"]=> array(1) { ["aaa"]=> string(1) "1" } } array(1) { ["var1"]=> array(1) { ["aaa"]=> string(1) "1" } } ALERT - array index contains blacklisted characters - dropped variable 'var2[bbB]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - array index contains blacklisted characters - dropped variable 'var3[ccc][ccC]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - array index contains blacklisted characters - dropped variable 'var2[bbB]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - array index contains blacklisted characters - dropped variable 'var3[ccc][ccC]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - array index contains blacklisted characters - dropped variable 'var2[bbB]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - array index contains blacklisted characters - dropped variable 'var3[ccc][ccC]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 6 request variables - (2 in GET, 2 in POST, 2 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/request_array_index_whitelist.phpt ================================================ --TEST-- suhosin input filter (suhosin.request.array_index_whitelist) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.array_index_whitelist=abcdefghijklmnopqrstuvwxyz --SKIPIF-- --COOKIE-- var1[aaa]=1;var2[bbB]=1;var3[ccc][ccC]=1 --GET-- var1[aaa]=1&var2[bbB]=1&var3[ccc][ccC]=1 --POST-- var1[aaa]=1&var2[bbB]=1&var3[ccc][ccC]=1 --FILE-- --EXPECTF-- array(1) { ["var1"]=> array(1) { ["aaa"]=> string(1) "1" } } array(1) { ["var1"]=> array(1) { ["aaa"]=> string(1) "1" } } array(1) { ["var1"]=> array(1) { ["aaa"]=> string(1) "1" } } ALERT - array index contains not whitelisted characters - dropped variable 'var2[bbB]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - array index contains not whitelisted characters - dropped variable 'var3[ccc][ccC]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - array index contains not whitelisted characters - dropped variable 'var2[bbB]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - array index contains not whitelisted characters - dropped variable 'var3[ccc][ccC]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - array index contains not whitelisted characters - dropped variable 'var2[bbB]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - array index contains not whitelisted characters - dropped variable 'var3[ccc][ccC]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 6 request variables - (2 in GET, 2 in POST, 2 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/request_disallow_nul.phpt ================================================ --TEST-- suhosin input filter (suhosin.request.disallow_nul) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.disallow_nul=1 --SKIPIF-- --COOKIE-- var1=xx%001;var2=2;var3=xx%003;var4=4; --GET-- var1=xx%001&var2=2&var3=xx%003&var4=4& --POST-- var1=xx%001&var2=2&var3=xx%003&var4=4& --FILE-- --EXPECTF-- array(2) { ["var2"]=> string(1) "2" ["var4"]=> string(1) "4" } array(2) { ["var2"]=> string(1) "2" ["var4"]=> string(1) "4" } array(2) { ["var2"]=> string(1) "2" ["var4"]=> string(1) "4" } ALERT - ASCII-NUL chars not allowed within request variables - dropped variable 'var1' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - ASCII-NUL chars not allowed within request variables - dropped variable 'var3' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - ASCII-NUL chars not allowed within request variables - dropped variable 'var1' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - ASCII-NUL chars not allowed within request variables - dropped variable 'var3' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - ASCII-NUL chars not allowed within request variables - dropped variable 'var1' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - ASCII-NUL chars not allowed within request variables - dropped variable 'var3' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 6 request variables - (2 in GET, 2 in POST, 2 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/request_disallow_ws.phpt ================================================ --TEST-- suhosin input filter (suhosin.request.disallow_ws) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.disallow_ws=1 --SKIPIF-- --COOKIE-- --GET-- +var1=1&var2=2&%20var3=3& var4=4& --POST-- --FILE-- --EXPECTF-- array(1) { ["var2"]=> string(1) "2" } ALERT - request variable name begins with disallowed whitespace - dropped variable ' var1' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - request variable name begins with disallowed whitespace - dropped variable ' var3' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - request variable name begins with disallowed whitespace - dropped variable ' var4' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 3 request variables - (3 in GET, 0 in POST, 0 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/request_max_array_depth.phpt ================================================ --TEST-- suhosin input filter (suhosin.request.max_array_depth) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_array_depth=4 --SKIPIF-- --COOKIE-- var1[]=1;var2[][]=2;var3[][][]=3;var4[][][][]=4;var5[][][][][]=5;var6[][][][][][]=6; --GET-- var1[]=1&var2[][]=2&var3[][][]=3&var4[][][][]=4&var5[][][][][]=5&var6[][][][][][]=6& --POST-- var1[]=1&var2[][]=2&var3[][][]=3&var4[][][][]=4&var5[][][][][]=5&var6[][][][][][]=6& --FILE-- --EXPECTF-- array(4) { ["var1"]=> array(1) { [0]=> string(1) "1" } ["var2"]=> array(1) { [0]=> array(1) { [0]=> string(1) "2" } } ["var3"]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> string(1) "3" } } } ["var4"]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> string(1) "4" } } } } } array(4) { ["var1"]=> array(1) { [0]=> string(1) "1" } ["var2"]=> array(1) { [0]=> array(1) { [0]=> string(1) "2" } } ["var3"]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> string(1) "3" } } } ["var4"]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> string(1) "4" } } } } } array(4) { ["var1"]=> array(1) { [0]=> string(1) "1" } ["var2"]=> array(1) { [0]=> array(1) { [0]=> string(1) "2" } } ["var3"]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> string(1) "3" } } } ["var4"]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> array(1) { [0]=> string(1) "4" } } } } } ALERT - configured request variable array depth limit exceeded - dropped variable 'var5[][][][][]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable array depth limit exceeded - dropped variable 'var6[][][][][][]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable array depth limit exceeded - dropped variable 'var5[][][][][]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable array depth limit exceeded - dropped variable 'var6[][][][][][]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable array depth limit exceeded - dropped variable 'var5[][][][][]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable array depth limit exceeded - dropped variable 'var6[][][][][][]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 6 request variables - (2 in GET, 2 in POST, 2 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/request_max_array_index_length.phpt ================================================ --TEST-- suhosin input filter (suhosin.request.max_array_index_length) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_array_index_length=3 --SKIPIF-- --COOKIE-- var1[AAA]=1;var2[BBBB]=1;var3[AAA][BBB]=1;var4[AAA][BBBB]=4;var5[AAA][BBB][CCC]=1;var6[AAA][BBBB][CCC]=1; --GET-- var1[AAA]=1&var2[BBBB]=1&var3[AAA][BBB]=1&var4[AAA][BBBB]=4&var5[AAA][BBB][CCC]=1&var6[AAA][BBBB][CCC]=1 --POST-- var1[AAA]=1&var2[BBBB]=1&var3[AAA][BBB]=1&var4[AAA][BBBB]=4&var5[AAA][BBB][CCC]=1&var6[AAA][BBBB][CCC]=1 --FILE-- --EXPECTF-- array(3) { ["var1"]=> array(1) { ["AAA"]=> string(1) "1" } ["var3"]=> array(1) { ["AAA"]=> array(1) { ["BBB"]=> string(1) "1" } } ["var5"]=> array(1) { ["AAA"]=> array(1) { ["BBB"]=> array(1) { ["CCC"]=> string(1) "1" } } } } array(3) { ["var1"]=> array(1) { ["AAA"]=> string(1) "1" } ["var3"]=> array(1) { ["AAA"]=> array(1) { ["BBB"]=> string(1) "1" } } ["var5"]=> array(1) { ["AAA"]=> array(1) { ["BBB"]=> array(1) { ["CCC"]=> string(1) "1" } } } } array(3) { ["var1"]=> array(1) { ["AAA"]=> string(1) "1" } ["var3"]=> array(1) { ["AAA"]=> array(1) { ["BBB"]=> string(1) "1" } } ["var5"]=> array(1) { ["AAA"]=> array(1) { ["BBB"]=> array(1) { ["CCC"]=> string(1) "1" } } } } ALERT - configured request variable array index length limit exceeded - dropped variable 'var2[BBBB]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable array index length limit exceeded - dropped variable 'var4[AAA][BBBB]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable array index length limit exceeded - dropped variable 'var6[AAA][BBBB][CCC]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable array index length limit exceeded - dropped variable 'var2[BBBB]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable array index length limit exceeded - dropped variable 'var4[AAA][BBBB]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable array index length limit exceeded - dropped variable 'var6[AAA][BBBB][CCC]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable array index length limit exceeded - dropped variable 'var2[BBBB]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable array index length limit exceeded - dropped variable 'var4[AAA][BBBB]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable array index length limit exceeded - dropped variable 'var6[AAA][BBBB][CCC]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 9 request variables - (3 in GET, 3 in POST, 3 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/request_max_name_length.phpt ================================================ --TEST-- suhosin input filter (suhosin.request.max_varname_length) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_varname_length=4 --SKIPIF-- --COOKIE-- var=0;var1=1;var2[]=2;var3[xxx]=3;var04=4;var05[]=5;var06[xxx]=6; --GET-- var=0&var1=1&var2[]=2&var3[xxx]=3&var04=4&var05[]=5&var06[xxx]=6& --POST-- var=0&var1=1&var2[]=2&var3[xxx]=3&var04=4&var05[]=5&var06[xxx]=6& --FILE-- --EXPECTF-- array(4) { ["var"]=> string(1) "0" ["var1"]=> string(1) "1" ["var2"]=> array(1) { [0]=> string(1) "2" } ["var3"]=> array(1) { ["xxx"]=> string(1) "3" } } array(4) { ["var"]=> string(1) "0" ["var1"]=> string(1) "1" ["var2"]=> array(1) { [0]=> string(1) "2" } ["var3"]=> array(1) { ["xxx"]=> string(1) "3" } } array(4) { ["var"]=> string(1) "0" ["var1"]=> string(1) "1" ["var2"]=> array(1) { [0]=> string(1) "2" } ["var3"]=> array(1) { ["xxx"]=> string(1) "3" } } ALERT - configured request variable name length limit exceeded - dropped variable 'var04' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable name length limit exceeded - dropped variable 'var05[]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable name length limit exceeded - dropped variable 'var06[xxx]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable name length limit exceeded - dropped variable 'var04' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable name length limit exceeded - dropped variable 'var05[]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable name length limit exceeded - dropped variable 'var06[xxx]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable name length limit exceeded - dropped variable 'var04' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable name length limit exceeded - dropped variable 'var05[]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable name length limit exceeded - dropped variable 'var06[xxx]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 9 request variables - (3 in GET, 3 in POST, 3 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/request_max_totalname_length.phpt ================================================ --TEST-- suhosin input filter (suhosin.request.max_totalname_length) --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.request.max_totalname_length=7 --SKIPIF-- --COOKIE-- var=0;var1=1;var2[]=2;var3[xxx]=3;var04=4;var05[]=5;var06[xxx]=6; --GET-- var=0&var1=1&var2[]=2&var3[xxx]=3&var04=4&var05[]=5&var06[xxx]=6& --POST-- var=0&var1=1&var2[]=2&var3[xxx]=3&var04=4&var05[]=5&var06[xxx]=6& --FILE-- --EXPECTF-- array(5) { ["var"]=> string(1) "0" ["var1"]=> string(1) "1" ["var2"]=> array(1) { [0]=> string(1) "2" } ["var04"]=> string(1) "4" ["var05"]=> array(1) { [0]=> string(1) "5" } } array(5) { ["var"]=> string(1) "0" ["var1"]=> string(1) "1" ["var2"]=> array(1) { [0]=> string(1) "2" } ["var04"]=> string(1) "4" ["var05"]=> array(1) { [0]=> string(1) "5" } } array(5) { ["var"]=> string(1) "0" ["var1"]=> string(1) "1" ["var2"]=> array(1) { [0]=> string(1) "2" } ["var04"]=> string(1) "4" ["var05"]=> array(1) { [0]=> string(1) "5" } } ALERT - configured request variable total name length limit exceeded - dropped variable 'var3[xxx]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable total name length limit exceeded - dropped variable 'var06[xxx]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable total name length limit exceeded - dropped variable 'var3[xxx]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable total name length limit exceeded - dropped variable 'var06[xxx]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable total name length limit exceeded - dropped variable 'var3[xxx]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - configured request variable total name length limit exceeded - dropped variable 'var06[xxx]' (attacker 'REMOTE_ADDR not set', file '%s') ALERT - dropped 6 request variables - (2 in GET, 2 in POST, 2 in COOKIE) (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/server_encode_off.phpt ================================================ --TEST-- Testing: suhosin.server.encode=Off --DESCRIPTION-- This test is incomplete but at the moment we cannot do better with the standard test framework. --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.stdout=255 suhosin.log.script=0 suhosin.server.encode=Off --SKIPIF-- --ENV-- return <<"'`!AAA END; --COOKIE-- --GET-- BBB<>"'`!BBB --POST-- --FILE-- --EXPECTF-- string(12) "AAA<>"'`!AAA" string(12) "BBB<>"'`!BBB" ================================================ FILE: tests/filter/server_encode_on.phpt ================================================ --TEST-- Testing: suhosin.server.encode=On --DESCRIPTION-- This test is incomplete but at the moment we cannot do better with the standard test framework. --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.stdout=255 suhosin.log.script=0 suhosin.server.encode=On --SKIPIF-- --ENV-- return <<"'`!AAA END; --COOKIE-- --GET-- BBB<>"'`!BBB --POST-- --FILE-- --EXPECTF-- string(22) "AAA%3C%3E%22%27%60!AAA" string(22) "BBB%3C%3E%22%27%60!BBB" ================================================ FILE: tests/filter/server_filter.phpt ================================================ --TEST-- suhosin SERVER filter --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp --SKIPIF-- --ENV-- return << $v) { if (!strncmp($k, "HTTP_", 5)) echo "$k => $v\n"; } ?> --EXPECTF-- HTTP_MY_VARS => HTTP_MY_VARS ALERT - Attacker tried to overwrite a superglobal through a HTTP header (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/server_strip_off.phpt ================================================ --TEST-- Testing: suhosin.server.strip=Off --DESCRIPTION-- This test is incomplete but at the moment we cannot do better with the standard test framework. --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.stdout=255 suhosin.log.script=0 suhosin.server.strip=Off --SKIPIF-- --ENV-- return <<"'`!AAA END; --COOKIE-- --GET-- A=B --POST-- --FILE-- --EXPECTF-- string(40) "X/index.php/THIS_IS_A_FAKE_NAME<>"'`!AAA" ================================================ FILE: tests/filter/server_strip_on.phpt ================================================ --TEST-- Testing: suhosin.server.strip=On --DESCRIPTION-- This test is incomplete but at the moment we cannot do better with the standard test framework. --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.stdout=255 suhosin.log.script=0 suhosin.server.strip=On --SKIPIF-- --ENV-- return <<"'`!AAA END; --COOKIE-- --GET-- A=B --POST-- --FILE-- --EXPECTF-- string(40) "X/index.php/THIS_IS_A_FAKE_NAME?????!AAA" ================================================ FILE: tests/filter/server_user_agent_strip_off.phpt ================================================ --TEST-- Testing: suhosin.server.strip=On --DESCRIPTION-- This test is not exactly what we want, but good enough due to limitations of the test framework. --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.stdout=255 suhosin.log.script=0 suhosin.server.strip=Off --SKIPIF-- --ENV-- return <<alert('123');Gecko/20100101 Firefox/29.0 END; --COOKIE-- --GET-- A=B --POST-- --FILE-- --EXPECTF-- string(95) "Mozilla/5.0 (Windows NT 6.0; rv:29.0) Gecko/20100101 Firefox/29.0" ================================================ FILE: tests/filter/server_user_agent_strip_on.phpt ================================================ --TEST-- Testing: suhosin.server.strip=On --DESCRIPTION-- This test is not exactly what we want, but good enough due to limitations of the test framework. --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.stdout=255 suhosin.log.script=0 suhosin.server.strip=On --SKIPIF-- --ENV-- return <<alert('123');Gecko/20100101 Firefox/29.0 END; --COOKIE-- --GET-- A=B --POST-- --FILE-- --EXPECTF-- string(95) "Mozilla/5.0 (Windows NT 6.0; rv:29.0) ?script?alert(?123?);?/script?Gecko/20100101 Firefox/29.0" ================================================ FILE: tests/filter/suhosin_upload_disallow_binary_utf8.phpt ================================================ --TEST-- Testing: suhosin.upload.disallow_binary=On with UTF-8 --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.stdout=255 suhosin.log.script=0 file_uploads=1 suhosin.upload.disallow_binary=On suhosin.upload.allow_utf8=On max_file_uploads=40 suhosin.upload.max_uploads=40 --SKIPIF-- --COOKIE-- --GET-- --POST_RAW-- Content-Type: multipart/form-data; boundary=bound --bound Content-Disposition: form-data; name="test"; filename="test" Spaß am Gerät! --bound-- --FILE-- --EXPECTF-- array(1) { ["test"]=> array(5) { ["name"]=> string(4) "test" ["type"]=> string(0) "" ["tmp_name"]=> string(%d) "%s" ["error"]=> int(0) ["size"]=> int(17) } } ================================================ FILE: tests/filter/suhosin_upload_disallow_binary_utf8fail.phpt ================================================ --TEST-- Testing: suhosin.upload.disallow_binary=On with UTF-8 and allow_utf8=Off --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp file_uploads=1 suhosin.upload.disallow_binary=On suhosin.upload.allow_utf8=Off max_file_uploads=40 suhosin.upload.max_uploads=40 --SKIPIF-- --COOKIE-- --GET-- --POST_RAW-- Content-Type: multipart/form-data; boundary=bound --bound Content-Disposition: form-data; name="test"; filename="test" Spaß am Gerät! --bound-- --FILE-- --EXPECTF-- array(1) { ["test"]=> array(5) { ["name"]=> string(4) "test" ["type"]=> string(0) "" ["tmp_name"]=> string(0) "" ["error"]=> int(8) ["size"]=> int(0) } } ALERT - uploaded file contains binary data - file dropped (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/suhosin_upload_disallow_elf.phpt ================================================ --TEST-- Testing: suhosin.upload.disallow_elf=On --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp file_uploads=1 suhosin.upload.disallow_elf=On --SKIPIF-- --COOKIE-- --GET-- --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="A"; filename="A" ELFABCDEFGHIJKLMN -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="B"; filename="B" XELFABCDEFGHIJKLMN -----------------------------20896060251896012921717172737-- --FILE-- --EXPECTF-- array(2) { ["A"]=> array(5) { ["name"]=> string(1) "A" ["type"]=> string(0) "" ["tmp_name"]=> string(0) "" ["error"]=> int(8) ["size"]=> int(0) } ["B"]=> array(5) { ["name"]=> string(1) "B" ["type"]=> string(0) "" ["tmp_name"]=> string(%d) "%s" ["error"]=> int(0) ["size"]=> int(18) } } ALERT - uploaded file is an ELF executable - file dropped (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/suhosin_upload_disallow_elf_off.phpt ================================================ --TEST-- Testing: suhosin.upload.disallow_elf=Off --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.stdout=255 suhosin.log.script=0 file_uploads=1 suhosin.upload.disallow_elf=Off --SKIPIF-- --COOKIE-- --GET-- --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="A"; filename="A" ELFABCDEFGHIJKLMN -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="B"; filename="B" XELFABCDEFGHIJKLMN -----------------------------20896060251896012921717172737-- --FILE-- --EXPECTF-- array(2) { ["A"]=> array(5) { ["name"]=> string(1) "A" ["type"]=> string(0) "" ["tmp_name"]=> string(%d) "%s" ["error"]=> int(0) ["size"]=> int(18) } ["B"]=> array(5) { ["name"]=> string(1) "B" ["type"]=> string(0) "" ["tmp_name"]=> string(%d) "%s" ["error"]=> int(0) ["size"]=> int(18) } } ================================================ FILE: tests/filter/suhosin_upload_max_uploads.phpt ================================================ --TEST-- suhosin.upload.max_uploads --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.post.max_vars=5 file_uploads=1 suhosin.upload.max_uploads=3 --SKIPIF-- --COOKIE-- --GET-- --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="A"; filename="A" A -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="B"; filename="B" B -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="C"; filename="C" C -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="D"; filename="D" D -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="E"; filename="E" E -----------------------------20896060251896012921717172737-- --FILE-- --EXPECTF-- array(3) { ["A"]=> array(5) { ["name"]=> string(1) "A" ["type"]=> string(0) "" ["tmp_name"]=> string(%d) "%s" ["error"]=> int(0) ["size"]=> int(1) } ["B"]=> array(5) { ["name"]=> string(1) "B" ["type"]=> string(0) "" ["tmp_name"]=> string(%d) "%s" ["error"]=> int(0) ["size"]=> int(1) } ["C"]=> array(5) { ["name"]=> string(1) "C" ["type"]=> string(0) "" ["tmp_name"]=> string(%d) "%s" ["error"]=> int(0) ["size"]=> int(1) } } ALERT - configured fileupload limit exceeded - file dropped (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/filter/suhosin_upload_remove_binary_utf8.phpt ================================================ --TEST-- Testing: suhosin.upload.remove_binary=On with UTF-8 --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.stdout=255 suhosin.log.script=0 file_uploads=1 suhosin.upload.disallow_binary=Off suhosin.upload.remove_binary=On suhosin.upload.allow_utf8=On max_file_uploads=40 suhosin.upload.max_uploads=40 --SKIPIF-- --COOKIE-- --GET-- --POST_RAW-- Content-Type: multipart/form-data; boundary=bound --bound Content-Disposition: form-data; name="test"; filename="test" Spaß am Gerät! --bound-- --FILE-- --EXPECTF-- string(17) "Spaß am Gerät! " ================================================ FILE: tests/filter/suhosin_upload_remove_binary_utf8fail.phpt ================================================ --TEST-- Testing: suhosin.upload.remove_binary=On with UTF-8 and allow_utf8=Off --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.stdout=255 suhosin.log.script=0 file_uploads=1 suhosin.upload.disallow_binary=Off suhosin.upload.remove_binary=On suhosin.upload.allow_utf8=Off max_file_uploads=40 suhosin.upload.max_uploads=40 --SKIPIF-- --COOKIE-- --GET-- --POST_RAW-- Content-Type: multipart/form-data; boundary=bound --bound Content-Disposition: form-data; name="test"; filename="test" Spaß am Gerät! --bound-- --FILE-- --EXPECTF-- string(13) "Spa am Gert! " ================================================ FILE: tests/funcs/crypt_blowfish.phpt ================================================ --TEST-- CRYPT_BLOWFISH support --SKIPIF-- --FILE-- --EXPECT-- int(1) $2a$07$rasmuslerd............nIdrcHdxcUxWomQX9j6kvERCFjTg7Ra ================================================ FILE: tests/funcs/crypt_ext_des.phpt ================================================ --TEST-- CRYPT_EXT_DES support --SKIPIF-- --FILE-- --EXPECT-- _J9..rasmBYk8r9AiWNc ================================================ FILE: tests/funcs/crypt_md5.phpt ================================================ --TEST-- CRYPT_MD5 support --SKIPIF-- --FILE-- --EXPECT-- $1$rasmusle$rISCgZzpwk3UhDidwXvin0 ================================================ FILE: tests/funcs/crypt_std_des.phpt ================================================ --TEST-- CRYPT_STD_DES support --SKIPIF-- --FILE-- --EXPECT-- rl.3StKT.4T8M ================================================ FILE: tests/funcs/sha256.phpt ================================================ --TEST-- SHA256 support --SKIPIF-- --FILE-- --EXPECT-- e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb 68325720aabd7c82f30f554b313d0570c95accbb7dc4b5aae11204c08ffe732b 7c4fbf484498d21b487b9d61de8914b2eadaf2698712936d47c3ada2558f6788 4096804221093ddccfbf46831490ea63e9e99414858f8d75ff7f642c7ca61803 7abc22c0ae5af26ce93dbb94433a0e0b2e119d014f8e7f65bd56c61ccccd9504 7516fb8bb11350df2bf386bc3c33bd0f52cb4c67c6e4745e0488e62c2aea2605 0eb0281b27a4604709b0513b43ad29fdcff9a7a958554abc689d7fe35af703e4 dee684641421d1ba5a65c71f986a117cbb3d619a052a0b3409306c629575c00f 47f527210d6e8f940b5082fec01b7305908fa2b49ea3ae597c19a3986097153c c60d239cc6da3ad31f4de0c2d58a73ccf3f9279e504fa60ad55a31dcf686f3ca e0164d90dbfcf173bb88044fac596ccd03b8d247c79907aaa5701767fad7b576 dc990ef3109a7bcf626199db9ab7801213ceb0ad2ee398963b5061e39c05c7b5 c1c9a4daadcc8678835872c7f1f8824376ac7b412e1fc2285069b41afd51397e 6840619417b4d8ecaa7902f8eaf2e82be2638dec97cb7e8fcc377007cc176718 0f5308ff22b828e18bd65afbc427e3c1a678962832519df5f2f803f68f55e10b ================================================ FILE: tests/include/include_allow_writable_files_off.phpt ================================================ --TEST-- Testing suhosin.executor.include.allow_writable_files=Off --DESCRIPTION-- Because the test file itself is writable the whole test case is not executed!!! --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=255 suhosin.log.script=0 suhosin.log.phpscript=0 suhosin.executor.include.whitelist= suhosin.executor.include.blacklist= suhosin.executor.include.allow_writable_files=Off --FILE-- --EXPECTF-- ALERT - Include filename ('%s') is writable by PHP process (attacker 'REMOTE_ADDR not set', file '%s') ================================================ FILE: tests/include/include_allow_writable_files_on.phpt ================================================ --TEST-- Testing suhosin.executor.include.allow_writable_files=On --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=255 suhosin.log.script=0 suhosin.log.phpscript=0 suhosin.executor.include.whitelist= suhosin.executor.include.blacklist= suhosin.executor.include.allow_writable_files=On --FILE-- --EXPECTF-- AAAA BBBB ================================================ FILE: tests/include/include_blacklist.phpt ================================================ --TEST-- Include blacklist --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=255 suhosin.log.script=0 suhosin.log.phpscript=0 suhosin.executor.include.whitelist= suhosin.executor.include.blacklist=foo,boo --FILE-- --EXPECTF-- value-from-empty.inc ALERT - Include filename ('foo://test') is a URL that is forbidden by the blacklist (attacker 'REMOTE_ADDR not set', file '%s', line 6) ================================================ FILE: tests/include/include_blackwhitelist_empty.phpt ================================================ --TEST-- Include URL with empty black-/whitelist --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=255 suhosin.log.script=0 suhosin.log.phpscript=0 suhosin.executor.include.whitelist= suhosin.executor.include.blacklist= --FILE-- --EXPECTF-- value-from-empty.inc ALERT - Include filename ('foo://test') is a URL that is not allowed (attacker 'REMOTE_ADDR not set', file '%s', line 6) ================================================ FILE: tests/include/include_constant.phpt ================================================ --TEST-- Include "Constant URL"; --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=255 suhosin.log.script=0 suhosin.log.phpscript=0 suhosin.executor.include.whitelist= suhosin.executor.include.blacklist= --FILE-- --EXPECTF-- ALERT - Include filename ('http://127.0.0.1/') is a URL that is not allowed (attacker 'REMOTE_ADDR not set', file '%s', line 2) ================================================ FILE: tests/include/include_etc_passwd.phpt ================================================ --TEST-- Include "../../../../../../../../../../../etc/passwd"; --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=255 suhosin.log.script=0 suhosin.log.phpscript=0 suhosin.executor.include.whitelist= suhosin.executor.include.blacklist= suhosin.executor.include.max_traversal=3 --FILE-- --EXPECTF-- value-from-empty.inc ALERT - Include filename ('%s../../../../../../../../../../../etc/passwd') contains too many '../' (attacker 'REMOTE_ADDR not set', file '%s', line 6) ================================================ FILE: tests/include/include_max_traversal.phpt ================================================ --TEST-- Testing suhosin.executor.include.max_traversal=10 --DESCRIPTION-- Seems to work fine, maybe split up later into multiple test cases. --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=255 suhosin.log.script=0 suhosin.log.phpscript=0 error_reporting=0 suhosin.executor.include.whitelist= suhosin.executor.include.blacklist= suhosin.executor.include.max_traversal=10 --FILE-- --EXPECTF-- C1 INCLUDED! C2 INCLUDED! ALERT - Include filename ('/.././.././.././.././.././.././.././.././.././../%s') contains too many '../' (attacker 'REMOTE_ADDR not set', file '%s', line 7) ================================================ FILE: tests/include/include_nul_in_filename.phpt ================================================ --TEST-- Testing include of filename including ASCIIZ character --DESCRIPTION-- This test will only trigger the PHP internal protection. If this test case ever breaks then PHP has failed and hopefully Suhosin has kicked in. --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=255 suhosin.log.script=0 suhosin.log.phpscript=0 suhosin.executor.include.whitelist= suhosin.executor.include.blacklist= --FILE-- --EXPECTF-- Warning: include(): Failed opening 'AAAA' for inclusion (include_path='%s') in %s on line 3 ================================================ FILE: tests/include/include_once_constant.phpt ================================================ --TEST-- Include_once "Constant URL"; --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=255 suhosin.log.script=0 suhosin.log.phpscript=0 suhosin.executor.include.whitelist= suhosin.executor.include.blacklist= --FILE-- --EXPECTF-- ALERT - Include filename ('http://127.0.0.1/') is a URL that is not allowed (attacker 'REMOTE_ADDR not set', file '%s', line 2) ================================================ FILE: tests/include/include_once_tmpvar.phpt ================================================ --TEST-- Include_once "Temp Variable URL"; --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=255 suhosin.log.script=0 suhosin.log.phpscript=0 suhosin.executor.include.whitelist= suhosin.executor.include.blacklist= --FILE-- --EXPECTF-- ALERT - Include filename ('http://127.0.0.1/?') is a URL that is not allowed (attacker 'REMOTE_ADDR not set', file '%s', line 4) ================================================ FILE: tests/include/include_once_var.phpt ================================================ --TEST-- Include_once "Variable URL"; --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=255 suhosin.log.script=0 suhosin.log.phpscript=0 suhosin.executor.include.whitelist= suhosin.executor.include.blacklist= --FILE-- --EXPECTF-- ALERT - Include filename ('http://127.0.0.1/') is a URL that is not allowed (attacker 'REMOTE_ADDR not set', file '%s', line 3) ================================================ FILE: tests/include/include_tmpvar.phpt ================================================ --TEST-- Include "Temp Variable URL"; --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=255 suhosin.log.script=0 suhosin.log.phpscript=0 suhosin.executor.include.whitelist= suhosin.executor.include.blacklist= --FILE-- --EXPECTF-- ALERT - Include filename ('http://127.0.0.1/?') is a URL that is not allowed (attacker 'REMOTE_ADDR not set', file '%s', line 4) ================================================ FILE: tests/include/include_too_long.phpt ================================================ --TEST-- Testing include of too long filename --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=255 suhosin.log.script=0 suhosin.log.phpscript=0 suhosin.executor.include.whitelist= suhosin.executor.include.blacklist= --FILE-- --EXPECTF-- ALERT - Include filename ('AAAA%sAAAA') is too long (attacker 'REMOTE_ADDR not set', file '%s', line 3) ================================================ FILE: tests/include/include_uploaded_file_diff_filename.phpt ================================================ --TEST-- Testing include file from $_FILES (but change name a bit) --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.stdout=255 suhosin.executor.include.whitelist= suhosin.executor.include.blacklist= --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="f1"; filename="filename2" --EXPECTF-- ALERT - Include filename is an uploaded file (attacker 'REMOTE_ADDR not set', file '%s', line 2) ================================================ FILE: tests/include/include_uploaded_file_from_FILES.phpt ================================================ --TEST-- Testing include file from $_FILES --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.stdout=255 suhosin.executor.include.whitelist= suhosin.executor.include.blacklist= --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 Content-Disposition: form-data; name="f1"; filename="filename2" --EXPECTF-- ALERT - Include filename is an uploaded file (attacker 'REMOTE_ADDR not set', file '%s', line 2) ================================================ FILE: tests/include/include_var.phpt ================================================ --TEST-- Include "Variable URL"; --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=255 suhosin.log.script=0 suhosin.log.phpscript=0 suhosin.executor.include.whitelist= suhosin.executor.include.blacklist= --FILE-- --EXPECTF-- ALERT - Include filename ('http://127.0.0.1/') is a URL that is not allowed (attacker 'REMOTE_ADDR not set', file '%s', line 3) ================================================ FILE: tests/include/include_whitelist.phpt ================================================ --TEST-- Include whitelist --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=255 suhosin.log.script=0 suhosin.log.phpscript=0 suhosin.executor.include.whitelist=file suhosin.executor.include.blacklist= --FILE-- --EXPECTF-- value-from-empty.inc ALERT - Include filename ('foo://test') is a URL that is not allowed (attacker 'REMOTE_ADDR not set', file '%s', line 6) ================================================ FILE: tests/include/require_constant.phpt ================================================ --TEST-- Require "Constant URL"; --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=255 suhosin.log.script=0 suhosin.log.phpscript=0 suhosin.executor.include.whitelist= suhosin.executor.include.blacklist= --FILE-- --EXPECTF-- ALERT - Include filename ('http://127.0.0.1/') is a URL that is not allowed (attacker 'REMOTE_ADDR not set', file '%s', line 2) ================================================ FILE: tests/include/require_once_constant.phpt ================================================ --TEST-- Require_once "Constant URL"; --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=255 suhosin.log.script=0 suhosin.log.phpscript=0 suhosin.executor.include.whitelist= suhosin.executor.include.blacklist= --FILE-- --EXPECTF-- ALERT - Include filename ('http://127.0.0.1/') is a URL that is not allowed (attacker 'REMOTE_ADDR not set', file '%s', line 2) ================================================ FILE: tests/include/require_once_tmpvar.phpt ================================================ --TEST-- Require_once "Temp Variable URL"; --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=255 suhosin.log.script=0 suhosin.log.phpscript=0 suhosin.executor.include.whitelist= suhosin.executor.include.blacklist= --FILE-- --EXPECTF-- ALERT - Include filename ('http://127.0.0.1/?') is a URL that is not allowed (attacker 'REMOTE_ADDR not set', file '%s', line 4) ================================================ FILE: tests/include/require_once_var.phpt ================================================ --TEST-- Require_once "Variable URL"; --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=255 suhosin.log.script=0 suhosin.log.phpscript=0 suhosin.executor.include.whitelist= suhosin.executor.include.blacklist= --FILE-- --EXPECTF-- ALERT - Include filename ('http://127.0.0.1/') is a URL that is not allowed (attacker 'REMOTE_ADDR not set', file '%s', line 3) ================================================ FILE: tests/include/require_tmpvar.phpt ================================================ --TEST-- Require "Temp Variable URL"; --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=255 suhosin.log.script=0 suhosin.log.phpscript=0 suhosin.executor.include.whitelist= suhosin.executor.include.blacklist= --FILE-- --EXPECTF-- ALERT - Include filename ('http://127.0.0.1/?') is a URL that is not allowed (attacker 'REMOTE_ADDR not set', file '%s', line 4) ================================================ FILE: tests/include/require_var.phpt ================================================ --TEST-- Require "Variable URL"; --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=255 suhosin.log.script=0 suhosin.log.phpscript=0 suhosin.executor.include.whitelist= suhosin.executor.include.blacklist= --FILE-- --EXPECTF-- ALERT - Include filename ('http://127.0.0.1/') is a URL that is not allowed (attacker 'REMOTE_ADDR not set', file '%s', line 3) ================================================ FILE: tests/logging/log_max_error_length.phpt ================================================ --TEST-- Testing: suhosin.log.use-x-forwarded-for=On (without X-Forwarded-For set) --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.max_error_length=20 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp --FILE-- --EXPECTF-- ALERT - script tried to disa... %s ================================================ FILE: tests/logging/logscript_executable.phpt ================================================ --TEST-- Testing: suhosin.log.script.name=EXECUTABLE --SKIPIF-- --INI-- suhosin.log.sapi=0 suhosin.log.stdout=0 suhosin.log.script=255 suhosin.log.script.name=/bin/echo suhosin.log.syslog=0 suhosin.executor.func.blacklist=max --FILE-- --EXPECTF-- Warning: max() has been disabled for security reasons in %s on line 2 ================================================ FILE: tests/logging/logscript_nonexecutable.phpt ================================================ --TEST-- Testing: suhosin.log.script.name=NON-EXECUTABLE --SKIPIF-- --INI-- suhosin.log.sapi=0 suhosin.log.stdout=0 suhosin.log.script=255 suhosin.log.script.name=/etc/passwd suhosin.log.syslog=0 suhosin.executor.func.blacklist=max --FILE-- --EXPECTF-- ALERT - logging shell script /etc/passwd is not executable - file dropped (attacker 'REMOTE_ADDR not set', file '%s', line 2) Warning: max() has been disabled for security reasons in %s on line 2 ================================================ FILE: tests/logging/logscript_nonexistant.phpt ================================================ --TEST-- Testing: suhosin.log.script.name=NON-EXISTANT --SKIPIF-- --INI-- suhosin.log.sapi=0 suhosin.log.stdout=0 suhosin.log.script=255 suhosin.log.script.name=/php/non-existant-script-really-really-really suhosin.log.syslog=0 suhosin.executor.func.blacklist=max --FILE-- --EXPECTF-- ALERT - unable to find logging shell script /php/non-existant-script-really-really-really - file dropped (attacker 'REMOTE_ADDR not set', file '%s', line 2) Warning: max() has been disabled for security reasons in %s on line 2 ================================================ FILE: tests/logging/use_x_forwarded_for_off.phpt ================================================ --TEST-- Testing: suhosin.log.use-x-forwarded-for=Off --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.executor.func.blacklist=max suhosin.log.use-x-forwarded-for=Off suhosin.simulation=1 --ENV-- return << --EXPECTF-- Warning: SIMULATION - max() has been disabled for security reasons in %s on line 2 ALERT-SIMULATION - function within blacklist called: max() (attacker '101.102.103.104', file '%s', line 2) ================================================ FILE: tests/logging/use_x_forwarded_for_off_no_remote_addr.phpt ================================================ --TEST-- Testing: suhosin.log.use-x-forwarded-for=Off (without REMOTE_ADDR set) --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.executor.func.blacklist=max suhosin.log.use-x-forwarded-for=Off suhosin.simulation=1 --FILE-- --EXPECTF-- Warning: SIMULATION - max() has been disabled for security reasons in %s on line 2 ALERT-SIMULATION - function within blacklist called: max() (attacker 'REMOTE_ADDR not set', file '%s', line 2) ================================================ FILE: tests/logging/use_x_forwarded_for_on.phpt ================================================ --TEST-- Testing: suhosin.log.use-x-forwarded-for=On --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.executor.func.blacklist=max suhosin.log.use-x-forwarded-for=On suhosin.simulation=1 --ENV-- return << --EXPECTF-- Warning: SIMULATION - max() has been disabled for security reasons in %s on line 2 ALERT-SIMULATION - function within blacklist called: max() (attacker '1.2.3.4', file '%s', line 2) ================================================ FILE: tests/logging/use_x_forwarded_for_on_no_x_forwarded.phpt ================================================ --TEST-- Testing: suhosin.log.use-x-forwarded-for=On (without X-Forwarded-For set) --SKIPIF-- --INI-- suhosin.log.syslog=0 suhosin.log.sapi=0 suhosin.log.script=0 suhosin.log.file=255 suhosin.log.file.time=0 suhosin.log.file.name={PWD}/suhosintest.$$.log.tmp auto_append_file={PWD}/suhosintest.$$.log.tmp suhosin.executor.func.blacklist=max suhosin.log.use-x-forwarded-for=On suhosin.simulation=1 --FILE-- --EXPECTF-- Warning: SIMULATION - max() has been disabled for security reasons in %s on line 2 ALERT-SIMULATION - function within blacklist called: max() (attacker 'X-FORWARDED-FOR not set', file '%s', line 2) ================================================ FILE: tests/misc/disable_display_errors_fail.phpt ================================================ --TEST-- Testing: suhosin.disable.display_errors=fail --SKIPIF-- --INI-- suhosin.log.sapi=0 suhosin.log.stdout=255 suhosin.log.script=0 suhosin.log.syslog=0 display_errors=1 suhosin.disable.display_errors=fail --FILE-- --EXPECTF-- string(1) "0" bool(false) string(1) "0" bool(false) string(1) "0" ================================================ FILE: tests/misc/disable_display_errors_off.phpt ================================================ --TEST-- Testing: suhosin.disable.display_errors=Off --SKIPIF-- --INI-- suhosin.log.sapi=0 suhosin.log.stdout=255 suhosin.log.script=0 suhosin.log.syslog=0 display_errors=1 suhosin.disable.display_errors=0 --FILE-- --EXPECTF-- Warning: ini_get() expects exactly 1 parameter, 0 given in %s on line 6 string(1) "1" string(1) "1" string(1) "0" string(1) "0" string(1) "1" Warning: ini_get() expects exactly 1 parameter, 0 given in %s on line 13 ================================================ FILE: tests/misc/disable_display_errors_on.phpt ================================================ --TEST-- Testing: suhosin.disable.display_errors=On --SKIPIF-- --INI-- suhosin.log.sapi=0 suhosin.log.stdout=255 suhosin.log.script=0 suhosin.log.syslog=0 display_errors=1 suhosin.disable.display_errors=1 --FILE-- --EXPECTF-- string(1) "1" string(1) "1" string(1) "0" string(1) "0" string(1) "1" ================================================ FILE: tests/misc/mailprotect_1_header_nl.phpt ================================================ --TEST-- Testing: suhosin.mail.protect=1 and extra headers start with newline --SKIPIF-- --INI-- suhosin.log.sapi=255 suhosin.log.stdout=0 suhosin.log.script=0 suhosin.log.syslog=0 suhosin.mail.protect=1 sendmail_path=$([ -f /bin/true ]&& echo /bin/true || echo /usr/bin/true) --FILE-- --EXPECTF-- ALERT - mail() - double newline in headers, possible injection, mail dropped (attacker 'REMOTE_ADDR not set', file '%s', line 2) bool(false) ================================================ FILE: tests/misc/mailprotect_1_header_nlnl.phpt ================================================ --TEST-- Testing: suhosin.mail.protect=1 and extra headers contain double newline --SKIPIF-- --INI-- suhosin.log.sapi=255 suhosin.log.stdout=0 suhosin.log.script=0 suhosin.log.syslog=0 suhosin.mail.protect=1 sendmail_path=$([ -f /bin/true ]&& echo /bin/true || echo /usr/bin/true) --FILE-- --EXPECTF-- ALERT - mail() - double newline in headers, possible injection, mail dropped (attacker 'REMOTE_ADDR not set', file '%s', line 2) bool(false) ================================================ FILE: tests/misc/mailprotect_1_subject.phpt ================================================ --TEST-- Testing: suhosin.mail.protect=1 with NL in Subject --SKIPIF-- --INI-- suhosin.log.sapi=255 suhosin.log.stdout=0 suhosin.log.script=0 suhosin.log.syslog=0 suhosin.mail.protect=1 sendmail_path=$([ -f /bin/true ]&& echo /bin/true || echo /usr/bin/true) --FILE-- --EXPECTF-- ALERT - mail() - newline in Subject header, possible injection, mail dropped (attacker 'REMOTE_ADDR not set', file '%s', line 2) bool(false) ================================================ FILE: tests/misc/mailprotect_1_subject_long.phpt ================================================ --TEST-- Testing: suhosin.mail.protect=1 with valid long Subject --SKIPIF-- --INI-- suhosin.log.sapi=255 suhosin.log.stdout=0 suhosin.log.script=0 suhosin.log.syslog=0 suhosin.mail.protect=1 sendmail_path=$([ -f /bin/true ]&& echo /bin/true || echo /usr/bin/true) --FILE-- --EXPECTF-- bool(true) ================================================ FILE: tests/misc/mailprotect_1_to.phpt ================================================ --TEST-- Testing: suhosin.mail.protect=1 with NL in To --SKIPIF-- --INI-- suhosin.log.sapi=255 suhosin.log.stdout=0 suhosin.log.script=0 suhosin.log.syslog=0 suhosin.mail.protect=1 sendmail_path=$([ -f /bin/true ]&& echo /bin/true || echo /usr/bin/true) --FILE-- --EXPECTF-- ALERT - mail() - newline in To header, possible injection, mail dropped (attacker 'REMOTE_ADDR not set', file '%s', line 2) bool(false) ================================================ FILE: tests/misc/mailprotect_1_to_long.phpt ================================================ --TEST-- Testing: suhosin.mail.protect=1 with valid long To --SKIPIF-- --INI-- suhosin.log.sapi=255 suhosin.log.stdout=0 suhosin.log.script=0 suhosin.log.syslog=0 suhosin.mail.protect=1 sendmail_path=$([ -f /bin/true ]&& echo /bin/true || echo /usr/bin/true) --FILE-- --EXPECTF-- bool(true) ================================================ FILE: tests/misc/mailprotect_2_bcc.phpt ================================================ --TEST-- Testing: suhosin.mail.protect=2 and extra headers contain Bcc: --SKIPIF-- --INI-- suhosin.log.sapi=255 suhosin.log.stdout=0 suhosin.log.script=0 suhosin.log.syslog=0 suhosin.mail.protect=2 sendmail_path=$([ -f /bin/true ]&& echo /bin/true || echo /usr/bin/true) --FILE-- --EXPECTF-- ALERT - mail() - BCC: headers aren't allowed in the headers parameter. (attacker 'REMOTE_ADDR not set', file '%s', line 2) bool(false) ================================================ FILE: tests/misc/mailprotect_2_cc.phpt ================================================ --TEST-- Testing: suhosin.mail.protect=2 and extra headers contain Cc: --SKIPIF-- --INI-- suhosin.log.sapi=255 suhosin.log.stdout=0 suhosin.log.script=0 suhosin.log.syslog=0 suhosin.mail.protect=2 sendmail_path=$([ -f /bin/true ]&& echo /bin/true || echo /usr/bin/true) --FILE-- --EXPECTF-- ALERT - mail() - CC: headers aren't allowed in the headers parameter. (attacker 'REMOTE_ADDR not set', file '%s', line 2) bool(false) ================================================ FILE: tests/misc/mailprotect_2_to.phpt ================================================ --TEST-- Testing: suhosin.mail.protect=2 and extra headers contain To: --SKIPIF-- --INI-- suhosin.log.sapi=255 suhosin.log.stdout=0 suhosin.log.script=0 suhosin.log.syslog=0 suhosin.mail.protect=2 sendmail_path=$([ -f /bin/true ]&& echo /bin/true || echo /usr/bin/true) --FILE-- --EXPECTF-- ALERT - mail() - To: headers aren't allowed in the headers parameter. (attacker 'REMOTE_ADDR not set', file '%s', line 2) bool(false) ================================================ FILE: tests/misc/mt_srand_ignore_off.phpt ================================================ --TEST-- Testing: suhosin.mt_srand.ignore=0 --SKIPIF-- --INI-- suhosin.log.sapi=255 suhosin.log.stdout=0 suhosin.log.script=0 suhosin.log.syslog=0 suhosin.mt_srand.ignore=0 --FILE-- --EXPECTF-- bool(true) ================================================ FILE: tests/misc/mt_srand_ignore_on.phpt ================================================ --TEST-- Testing: suhosin.mt_srand.ignore=1 --SKIPIF-- --INI-- suhosin.log.sapi=255 suhosin.log.stdout=0 suhosin.log.script=0 suhosin.log.syslog=0 suhosin.mt_srand.ignore=1 --FILE-- --EXPECTF-- bool(true) ================================================ FILE: tests/misc/protectkey_off.phpt ================================================ --TEST-- Testing: suhosin.protectkey=On --SKIPIF-- --INI-- suhosin.log.sapi=0 suhosin.log.stdout=255 suhosin.log.script=0 suhosin.log.syslog=0 suhosin.protectkey=0 suhosin.session.cryptkey=SUHOSIN_TEST_SESSION_CRYPTKEY suhosin.cookie.cryptkey=SUHOSIN_TEST_COOKIE_CRYPTKEY suhosin.rand.seedingkey=SUHOSIN_TEST_SEEDINGKEY --FILE-- --EXPECTF-- bool(false) bool(false) bool(false) ================================================ FILE: tests/misc/protectkey_on.phpt ================================================ --TEST-- Testing: suhosin.protectkey=On --SKIPIF-- --INI-- suhosin.log.sapi=0 suhosin.log.stdout=255 suhosin.log.script=0 suhosin.log.syslog=0 suhosin.protectkey=1 suhosin.session.cryptkey=SUHOSIN_TEST_SESSION_CRYPTKEY suhosin.cookie.cryptkey=SUHOSIN_TEST_COOKIE_CRYPTKEY suhosin.rand.seedingkey=SUHOSIN_TEST_SEEDINGKEY --FILE-- --EXPECTF-- bool(true) bool(true) bool(true) ================================================ FILE: tests/misc/srand_ignore_off.phpt ================================================ --TEST-- Testing: suhosin.srand.ignore=0 --SKIPIF-- --INI-- suhosin.log.sapi=255 suhosin.log.stdout=0 suhosin.log.script=0 suhosin.log.syslog=0 suhosin.srand.ignore=0 --FILE-- --EXPECTF-- bool(true) ================================================ FILE: tests/misc/srand_ignore_on.phpt ================================================ --TEST-- Testing: suhosin.srand.ignore=1 --SKIPIF-- --INI-- suhosin.log.sapi=255 suhosin.log.stdout=0 suhosin.log.script=0 suhosin.log.syslog=0 suhosin.srand.ignore=1 --FILE-- --EXPECTF-- bool(true) ================================================ FILE: tests/session/PHPSESSID_max_id_length_ok.phpt ================================================ --TEST-- PHPSESSID session id not too long --SKIPIF-- --INI-- suhosin.session.max_id_length=32 session.hash_bits_per_character=4 --COOKIE-- PHPSESSID=12345678901234567890123456789012; --FILE-- --EXPECTF-- 12345678901234567890123456789012 ================================================ FILE: tests/session/PHPSESSID_max_id_length_toolong.phpt ================================================ --TEST-- PHPSESSID session id too long --SKIPIF-- --INI-- suhosin.session.max_id_length=32 session.hash_bits_per_character=4 --COOKIE-- PHPSESSID=123456789012345678901234567890123; --FILE-- --EXPECTF-- 32 ================================================ FILE: tests/session/crypt.checkraddr_4.phpt ================================================ --TEST-- session encryption with checkraddr=4 --SKIPIF-- --ENV-- return << --EXPECTF-- array(1) { ["a"]=> string(1) "b" } ================================================ FILE: tests/session/crypt.checkraddr_4_incorrect.phpt ================================================ --TEST-- session encryption with checkraddr=4 and incorrect REMOTE_ADDR --SKIPIF-- --ENV-- return << --EXPECTF-- array(0) { } ================================================ FILE: tests/session/crypt.docroot.phpt ================================================ --TEST-- session with encryption using docroot --SKIPIF-- --ENV-- return << --EXPECTF-- SESSION: NKChb1rdctXd-Acz0uzOYVnJT_J2mxYRVUgSh0w5mlk. ================================================ FILE: tests/session/crypt.key_default.phpt ================================================ --TEST-- session with encryption default key --SKIPIF-- --INI-- suhosin.session.encrypt=On suhosin.session.cryptkey=D3F4UL7 suhosin.session.cryptua=Off suhosin.session.cryptdocroot=Off suhosin.session.cryptraddr=0 suhosin.session.checkraddr=0 --FILE-- --EXPECTF-- SESSION: RIuy2LSSd3_s3hhDCnN89bNWyCnhvNAO0YUq7OQKuJc. ================================================ FILE: tests/session/crypt.key_empty.phpt ================================================ --TEST-- session with encryption key empty --SKIPIF-- --INI-- suhosin.session.encrypt=On suhosin.session.cryptkey= suhosin.session.cryptua=Off suhosin.session.cryptdocroot=Off suhosin.session.cryptraddr=0 suhosin.session.checkraddr=0 --FILE-- --EXPECTF-- SESSION: RIuy2LSSd3_s3hhDCnN89bNWyCnhvNAO0YUq7OQKuJc. ================================================ FILE: tests/session/crypt.key_empty_remote_addr.phpt ================================================ --TEST-- session with encryption key empty and REMOTE_ADDR set --SKIPIF-- --ENV-- return << --EXPECTF-- SESSION: j1YTvIOAUqxZMjuJ_ZnHPHWY5XEayycsr7O94aMzmBQ. ================================================ FILE: tests/session/crypt.no_encryption.phpt ================================================ --TEST-- session without encryption --SKIPIF-- --INI-- suhosin.session.encrypt=Off --FILE-- --EXPECTF-- SESSION: a|s:1:"b"; ================================================ FILE: tests/session/crypt.raddr_1.phpt ================================================ --TEST-- session with encryption using REMOTE_ADDR (cryptraddr=1) --SKIPIF-- --ENV-- return << --EXPECTF-- SESSION: wkiQGgZgWnBFDyCs_4QYD_oaw_m35l_5I35XRg0wX_g. ================================================ FILE: tests/session/crypt.raddr_2.phpt ================================================ --TEST-- session with encryption using REMOTE_ADDR (cryptraddr=2) --SKIPIF-- --ENV-- return << --EXPECTF-- SESSION: WDyvE0R4mUqvOG6e5VzhfgWMjfCWSFC5bNNI_3dIT3w. ================================================ FILE: tests/session/crypt.raddr_3.phpt ================================================ --TEST-- session with encryption using REMOTE_ADDR (cryptraddr=3) --SKIPIF-- --ENV-- return << --EXPECTF-- SESSION: 6kLKLrgCmlOuEPXPON_K5SWHLuIbHdLsh4MJ0QtTFj8. ================================================ FILE: tests/session/crypt.raddr_4.phpt ================================================ --TEST-- session with encryption using REMOTE_ADDR (cryptraddr=4) --SKIPIF-- --ENV-- return << --EXPECTF-- SESSION: QYSbWh8enETvdtKfao8G6aiXqK7_lhzFmRNYa2lo-UM. ================================================ FILE: tests/session/crypt.ua.phpt ================================================ --TEST-- session with encryption using ua --SKIPIF-- --ENV-- return << --EXPECTF-- SESSION: 3pVZdIv7vHG-PwO_rLQLUGerd4L_UX60xJoAM-IoVC4. ================================================ FILE: tests/session/max_id_length_ok.phpt ================================================ --TEST-- session id not too long --SKIPIF-- --INI-- suhosin.session.max_id_length=32 session.hash_bits_per_character=4 --FILE-- --EXPECTF-- 12345678901234567890123456789012 ================================================ FILE: tests/session/max_id_length_toolong.phpt ================================================ --TEST-- session id too long --SKIPIF-- --INI-- suhosin.session.max_id_length=32 session.hash_bits_per_character=4 --FILE-- --EXPECTF-- 32 ================================================ FILE: tests/session/session_recursive_crash.phpt ================================================ --TEST-- session SessionHandler() recursive crash --SKIPIF-- --ENV-- return << string(1) "b" } ================================================ FILE: tests/session/session_recursive_crash2.phpt ================================================ --TEST-- session user handler recursive crash - issue #60 --SKIPIF-- --ENV-- return << ================================================ FILE: tests/skipif.inc ================================================ ================================================ FILE: tests/skipifcli.inc ================================================ ================================================ FILE: tests/skipifnotcli.inc ================================================ ================================================ FILE: tests/sql/connect.inc ================================================ ================================================ FILE: tests/sql/mysqli_comment_conditional.phpt ================================================ --TEST-- Mysqli query with SQL comment protection and MySQL condition (/*!...*/) --INI-- extension=mysqli.so suhosin.sql.bailout_on_error=0 suhosin.sql.comment=2 suhosin.sql.opencomment=0 suhosin.sql.multiselect=0 suhosin.sql.union=0 suhosin.log.stdout=32 --SKIPIF-- --FILE-- query("SELECT 1 /*! ... */"); flush(); echo "mark."; ?> --EXPECTF-- mark. ================================================ FILE: tests/sql/mysqli_comment_cstyle_fail.phpt ================================================ --TEST-- Mysqli query with SQL comment (/*...*/) protection set to fail --INI-- extension=mysqli.so suhosin.sql.bailout_on_error=0 suhosin.sql.comment=2 suhosin.sql.opencomment=0 suhosin.sql.multiselect=0 suhosin.sql.union=0 suhosin.log.stdout=32 --SKIPIF-- --FILE-- query("SELECT 1 /* injection */"); flush(); echo "mark."; ?> --EXPECTREGEX-- ALERT - Comment in SQL query.*\) ================================================ FILE: tests/sql/mysqli_comment_hashstyle_fail.phpt ================================================ --TEST-- Mysqli query with SQL comment (#) protection set to fail --INI-- extension=mysqli.so suhosin.sql.bailout_on_error=0 suhosin.sql.comment=2 suhosin.sql.opencomment=0 suhosin.sql.multiselect=0 suhosin.sql.union=0 suhosin.log.stdout=32 --SKIPIF-- --FILE-- query("SELECT 1 # injection"); flush(); echo "mark."; ?> --EXPECTREGEX-- ALERT - Comment in SQL query.*\) ================================================ FILE: tests/sql/mysqli_comment_sqlstyle.phpt ================================================ --TEST-- Mysqli query with SQL comment (--) protection --INI-- extension=mysqli.so suhosin.sql.bailout_on_error=0 suhosin.sql.comment=1 suhosin.sql.opencomment=0 suhosin.sql.multiselect=0 suhosin.sql.union=0 suhosin.log.stdout=32 --SKIPIF-- --FILE-- query("SELECT 1 -- injection"); flush(); echo "mark."; ?> --EXPECTREGEX-- ALERT - Comment in SQL query.*mark. ================================================ FILE: tests/sql/mysqli_comment_sqlstyle_fail.phpt ================================================ --TEST-- Mysqli query with SQL comment (--) protection set to fail --INI-- extension=mysqli.so suhosin.sql.bailout_on_error=0 suhosin.sql.comment=2 suhosin.sql.opencomment=0 suhosin.sql.multiselect=0 suhosin.sql.union=0 suhosin.log.stdout=32 --SKIPIF-- --FILE-- query("SELECT 1 -- injection"); flush(); echo "mark."; ?> --EXPECTREGEX-- ALERT - Comment in SQL query.*\) ================================================ FILE: tests/sql/mysqli_connect_invalid_username.phpt ================================================ --TEST-- Mysqli connect with user_match not matching username --INI-- extension=mysqli.so suhosin.log.stdout=32 --SKIPIF-- --FILE-- --EXPECTREGEX-- ALERT - SQL username contains invalid characters.* ================================================ FILE: tests/sql/mysqli_multiselect.phpt ================================================ --TEST-- Mysqli query with multiple SELECT statements --INI-- extension=mysqli.so suhosin.sql.bailout_on_error=0 suhosin.sql.comment=0 suhosin.sql.opencomment=0 suhosin.sql.multiselect=1 suhosin.sql.union=0 suhosin.log.stdout=32 --SKIPIF-- --FILE-- query("SELECT 1; SELECT 2"); flush(); echo "mark."; ?> --EXPECTREGEX-- ALERT - Multiple SELECT in SQL query.*mark. ================================================ FILE: tests/sql/mysqli_multiselect_fail.phpt ================================================ --TEST-- Mysqli query with multiple SELECT statements set to fail --INI-- extension=mysqli.so suhosin.sql.bailout_on_error=0 suhosin.sql.comment=0 suhosin.sql.opencomment=0 suhosin.sql.multiselect=2 suhosin.sql.union=0 suhosin.log.stdout=32 --SKIPIF-- --FILE-- query("SELECT 1; SELECT 2"); flush(); echo "mark."; ?> --EXPECTREGEX-- ALERT - Multiple SELECT in SQL query.*\) ================================================ FILE: tests/sql/mysqli_multiselect_subselect.phpt ================================================ --TEST-- Mysqli query with sub-SELECT --INI-- extension=mysqli.so suhosin.sql.bailout_on_error=0 suhosin.sql.comment=0 suhosin.sql.opencomment=0 suhosin.sql.multiselect=1 suhosin.sql.union=0 suhosin.log.stdout=32 --SKIPIF-- --FILE-- query("SELECT * FROM (SELECT 1)"); flush(); echo "mark."; ?> --EXPECTREGEX-- ALERT - Multiple SELECT in SQL query.*mark. ================================================ FILE: tests/sql/mysqli_no_constraints.phpt ================================================ --TEST-- Mysqli connection test without any constraints --INI-- extension=mysqli.so suhosin.sql.comment=0 suhosin.sql.bailout_on_error=0 suhosin.sql.comment=0 suhosin.sql.opencomment=0 suhosin.sql.multiselect=0 suhosin.sql.union=0 --SKIPIF-- --FILE-- query("SELECT 1 AS A UNION SELECT 2 -- injection"); $rows = $result->fetch_all(); if ($rows !== null && count($rows) == 2) { echo "ok"; } ?> --EXPECTF-- ok ================================================ FILE: tests/sql/mysqli_open_comment.phpt ================================================ --TEST-- Mysqli query with SQL open comment protection (/*...) --INI-- extension=mysqli.so suhosin.sql.bailout_on_error=0 suhosin.sql.comment=0 suhosin.sql.opencomment=1 suhosin.sql.multiselect=0 suhosin.sql.union=0 suhosin.log.stdout=32 --SKIPIF-- --FILE-- query("SELECT 1 /*"); flush(); echo "mark."; ?> --EXPECTREGEX-- ALERT - Open comment in SQL query.*mark. ================================================ FILE: tests/sql/mysqli_open_comment_fail.phpt ================================================ --TEST-- Mysqli query with SQL open comment protection (/*...) set to fail --INI-- extension=mysqli.so suhosin.sql.bailout_on_error=0 suhosin.sql.comment=0 suhosin.sql.opencomment=2 suhosin.sql.multiselect=0 suhosin.sql.union=0 suhosin.log.stdout=32 --SKIPIF-- --FILE-- query("SELECT 1 /*"); flush(); echo "mark."; ?> --EXPECTREGEX-- ALERT - Open comment in SQL query.*\) ================================================ FILE: tests/sql/mysqli_union.phpt ================================================ --TEST-- Mysqli query with UNION protection --INI-- extension=mysqli.so suhosin.sql.bailout_on_error=0 suhosin.sql.comment=0 suhosin.sql.opencomment=0 suhosin.sql.multiselect=0 suhosin.sql.union=1 suhosin.log.stdout=32 --SKIPIF-- --FILE-- query("SELECT 1 UNION SELECT 2"); flush(); echo "mark."; ?> --EXPECTREGEX-- ALERT - UNION in SQL query.*mark. ================================================ FILE: tests/sql/mysqli_union_fail.phpt ================================================ --TEST-- Mysqli query with UNION protection set to fail --INI-- extension=mysqli.so suhosin.sql.bailout_on_error=0 suhosin.sql.comment=0 suhosin.sql.opencomment=0 suhosin.sql.multiselect=0 suhosin.sql.union=2 suhosin.log.stdout=32 --SKIPIF-- --FILE-- query("SELECT 1 UNION SELECT 2"); echo "mark."; ?> --EXPECTREGEX-- ALERT - UNION in SQL query.*\) ================================================ FILE: tests/sql/mysqli_user_match_error.phpt ================================================ --TEST-- Mysqli connect with user_match not matching username --INI-- extension=mysqli.so suhosin.sql.user_match=complicated_userprefix* suhosin.log.stdout=32 --SKIPIF-- --FILE-- --EXPECTREGEX-- ALERT - SQL username .* does not match.* ================================================ FILE: tests/sql/mysqli_user_match_ok.phpt ================================================ --TEST-- Mysqli connect with user_match matching username --INI-- extension=mysqli.so suhosin.sql.user_match=invalid_* suhosin.log.stdout=32 --SKIPIF-- --FILE-- --EXPECTREGEX-- .*Access denied for user 'invalid_username'.* ================================================ FILE: tests/sql/mysqli_user_postfix.phpt ================================================ --TEST-- Mysqli connect with user_postfix --INI-- extension=mysqli.so suhosin.sql.user_postfix=_post suhosin.log.stdout=32 --SKIPIF-- --FILE-- --EXPECTREGEX-- .*Access denied for user 'invalid_username_post'.* ================================================ FILE: tests/sql/mysqli_user_prefix.phpt ================================================ --TEST-- Mysqli connect with user_prefix --INI-- extension=mysqli.so suhosin.sql.user_prefix=pre_ suhosin.log.stdout=32 --SKIPIF-- --FILE-- --EXPECTREGEX-- .*Access denied for user 'pre_invalid_username'.* ================================================ FILE: tests/sql/skipifmysqli.inc ================================================ ================================================ FILE: treat_data.c ================================================ /* +----------------------------------------------------------------------+ | Suhosin Version 1 | +----------------------------------------------------------------------+ | Copyright (c) 2006-2007 The Hardened-PHP Project | | Copyright (c) 2007-2015 SektionEins GmbH | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Stefan Esser | +----------------------------------------------------------------------+ */ /* $Id: treat_data.c,v 1.1.1.1 2007-11-28 01:15:35 sesser Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_ini.h" #include "php_suhosin.h" #include "SAPI.h" #include "php_variables.h" #include "ext/standard/url.h" SAPI_TREAT_DATA_FUNC(suhosin_treat_data) { char *res = NULL, *var, *val, *separator = NULL; const char *c_var; zval *array_ptr; int free_buffer = 0; char *strtok_buf = NULL; long count = 0; /* Mark that we were not yet called */ SUHOSIN_G(already_scanned) = 0; switch (arg) { case PARSE_POST: case PARSE_GET: case PARSE_COOKIE: ALLOC_ZVAL(array_ptr); array_init(array_ptr); INIT_PZVAL(array_ptr); switch (arg) { case PARSE_POST: if (PG(http_globals)[TRACK_VARS_POST]) { zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_POST]); } PG(http_globals)[TRACK_VARS_POST] = array_ptr; if (SUHOSIN_G(max_request_variables) && (SUHOSIN_G(max_post_vars) == 0 || SUHOSIN_G(max_request_variables) <= SUHOSIN_G(max_post_vars))) { SUHOSIN_G(max_post_vars) = SUHOSIN_G(max_request_variables); } break; case PARSE_GET: if (PG(http_globals)[TRACK_VARS_GET]) { zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_GET]); } PG(http_globals)[TRACK_VARS_GET] = array_ptr; if (SUHOSIN_G(max_request_variables) && (SUHOSIN_G(max_get_vars) == 0 || SUHOSIN_G(max_request_variables) <= SUHOSIN_G(max_get_vars))) { SUHOSIN_G(max_get_vars) = SUHOSIN_G(max_request_variables); } break; case PARSE_COOKIE: if (PG(http_globals)[TRACK_VARS_COOKIE]) { zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_COOKIE]); } PG(http_globals)[TRACK_VARS_COOKIE] = array_ptr; if (SUHOSIN_G(max_request_variables) && (SUHOSIN_G(max_cookie_vars) == 0 || SUHOSIN_G(max_request_variables) <= SUHOSIN_G(max_cookie_vars))) { SUHOSIN_G(max_cookie_vars) = SUHOSIN_G(max_request_variables); } break; } break; default: array_ptr = destArray; break; } if (arg == PARSE_POST) { sapi_handle_post(array_ptr TSRMLS_CC); return; } if (arg == PARSE_GET) { /* GET data */ c_var = SG(request_info).query_string; if (c_var && *c_var) { res = (char *) estrdup(c_var); free_buffer = 1; } else { free_buffer = 0; } } else if (arg == PARSE_COOKIE) { /* Cookie data */ c_var = SG(request_info).cookie_data; if (c_var && *c_var) { if (SUHOSIN_G(cookie_encrypt)) { res = (char *) estrdup(suhosin_cookie_decryptor(TSRMLS_C)); } else { res = (char *) estrdup(c_var); } free_buffer = 1; } else { free_buffer = 0; } } else if (arg == PARSE_STRING) { /* String data */ res = str; free_buffer = 1; } if (!res) { return; } switch (arg) { case PARSE_GET: case PARSE_STRING: separator = (char *) estrdup(PG(arg_separator).input); break; case PARSE_COOKIE: separator = ";\0"; break; } var = php_strtok_r(res, separator, &strtok_buf); while (var) { if (arg == PARSE_COOKIE) { /* Remove leading spaces from cookie names, needed for multi-cookie header where ; can be followed by a space */ while (isspace(*var)) { var++; } } val = strchr(var, '='); if (++count > PG(max_input_vars)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars)); break; } if (val) { /* have a value */ int val_len; unsigned int new_val_len; *val++ = '\0'; php_url_decode(var, strlen(var)); val_len = php_url_decode(val, strlen(val)); val = estrndup(val, val_len); if (suhosin_input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) { if (sapi_module.input_filter(arg, var, &val, new_val_len, &new_val_len TSRMLS_CC)) { php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); } } else { SUHOSIN_G(abort_request) = 1; } efree(val); } else { int val_len; unsigned int new_val_len; php_url_decode(var, strlen(var)); val_len = 0; val = estrndup("", val_len); if (suhosin_input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) { if (sapi_module.input_filter(arg, var, &val, new_val_len, &new_val_len TSRMLS_CC)) { php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); } } else { SUHOSIN_G(abort_request) = 1; } efree(val); } var = php_strtok_r(NULL, separator, &strtok_buf); } if (arg != PARSE_COOKIE) { efree(separator); } if (free_buffer) { efree(res); } } void suhosin_hook_treat_data() { TSRMLS_FETCH(); sapi_register_treat_data(suhosin_treat_data TSRMLS_CC); if (old_input_filter == NULL) { old_input_filter = sapi_module.input_filter; } sapi_module.input_filter = suhosin_input_filter_wrapper; } /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ ================================================ FILE: ufilter.c ================================================ /* +----------------------------------------------------------------------+ | Suhosin Version 1 | +----------------------------------------------------------------------+ | Copyright (c) 2006-2007 The Hardened-PHP Project | | Copyright (c) 2007-2015 SektionEins GmbH | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Stefan Esser | +----------------------------------------------------------------------+ */ /* $Id: ufilter.c,v 1.1.1.1 2007-11-28 01:15:35 sesser Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" #include "php_suhosin.h" #include "php_variables.h" #include "suhosin_rfc1867.h" #include "ext/standard/php_var.h" #if !HAVE_RFC1867_CALLBACK PHP_SUHOSIN_API int (*php_rfc1867_callback)(unsigned int event, void *event_data, void **extra TSRMLS_DC) = NULL; #endif /* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC */ static int check_fileupload_varname(char *varname TSRMLS_DC) { char *index, *prev_index = NULL, *var; unsigned int var_len, total_len, depth = 0; var = estrdup(varname); /* Normalize the variable name */ normalize_varname(var); /* Find length of variable name */ index = strchr(var, '['); total_len = strlen(var); var_len = index ? index-var : total_len; /* Drop this variable if it exceeds the varname/total length limit */ if (SUHOSIN_G(max_varname_length) && SUHOSIN_G(max_varname_length) < var_len) { suhosin_log(S_FILES, "configured request variable name length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { goto return_failure; } } if (SUHOSIN_G(max_totalname_length) && SUHOSIN_G(max_totalname_length) < total_len) { suhosin_log(S_FILES, "configured request variable total name length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { goto return_failure; } } if (SUHOSIN_G(max_post_name_length) && SUHOSIN_G(max_post_name_length) < var_len) { suhosin_log(S_FILES, "configured POST variable name length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { goto return_failure; } } if (SUHOSIN_G(max_post_totalname_length) && SUHOSIN_G(max_post_totalname_length) < var_len) { suhosin_log(S_FILES, "configured POST variable total name length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { goto return_failure; } } /* Find out array depth */ while (index) { char *index_end; unsigned int index_length; /* overjump '[' */ index++; /* increase array depth */ depth++; index_end = strchr(index, ']'); if (index_end == NULL) { index_end = index+strlen(index); } index_length = index_end - index; if (SUHOSIN_G(max_array_index_length) && SUHOSIN_G(max_array_index_length) < index_length) { suhosin_log(S_FILES, "configured request variable array index length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { goto return_failure; } } if (SUHOSIN_G(max_post_array_index_length) && SUHOSIN_G(max_post_array_index_length) < index_length) { suhosin_log(S_FILES, "configured POST variable array index length limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { goto return_failure; } } /* index whitelist/blacklist */ if (SUHOSIN_G(array_index_whitelist) && *(SUHOSIN_G(array_index_whitelist))) { if (suhosin_strnspn(index, index_length, SUHOSIN_G(array_index_whitelist)) != index_length) { suhosin_log(S_VARS, "array index contains not whitelisted characters - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { goto return_failure; } } } else if (SUHOSIN_G(array_index_blacklist) && *(SUHOSIN_G(array_index_blacklist))) { if (suhosin_strncspn(index, index_length, SUHOSIN_G(array_index_blacklist)) != index_length) { suhosin_log(S_VARS, "array index contains blacklisted characters - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { goto return_failure; } } } index = strchr(index, '['); } /* Drop this variable if it exceeds the array depth limit */ if (SUHOSIN_G(max_array_depth) && SUHOSIN_G(max_array_depth) < depth) { suhosin_log(S_FILES, "configured request variable array depth limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { goto return_failure; } } if (SUHOSIN_G(max_post_array_depth) && SUHOSIN_G(max_post_array_depth) < depth) { suhosin_log(S_FILES, "configured POST variable array depth limit exceeded - dropped variable '%s'", var); if (!SUHOSIN_G(simulation)) { goto return_failure; } } /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ /* This is to protect several silly scripts that do globalizing themself */ if (php_varname_check(var, var_len, 1 TSRMLS_CC) == FAILURE || suhosin_is_protected_varname(var, var_len)) { suhosin_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var); if (!SUHOSIN_G(simulation)) { goto return_failure; } } efree(var); return SUCCESS; return_failure: efree(var); return FAILURE; } /* }}} */ #ifdef SUHOSIN_EXPERIMENTAL static inline int suhosin_validate_utf8_multibyte(const char* cp, size_t maxlen) { if (maxlen < 2 || !(*cp & 0x80)) { return 0; } if ((*cp & 0xe0) == 0xc0 && // 1st byte is 110xxxxx (*(cp+1) & 0xc0) == 0x80 && // 2nd byte is 10xxxxxx (*cp & 0x1e)) { // overlong check 110[xxxx]x 10xxxxxx return 2; } if (maxlen < 3) { return 0; } if ((*cp & 0xf0) == 0xe0 && // 1st byte is 1110xxxx (*(cp+1) & 0xc0) == 0x80 && // 2nd byte is 10xxxxxx (*(cp+2) & 0xc0) == 0x80 && // 3rd byte is 10xxxxxx ((*cp & 0x0f) | (*(cp+1) & 0x20))) { // 1110[xxxx] 10[x]xxxxx 10xxxxxx return 3; } if (maxlen < 4) { return 0; } if ((*cp & 0xf8) == 0xf0 && // 1st byte is 11110xxx (*(cp+1) & 0xc0) == 0x80 && // 2nd byte is 10xxxxxx (*(cp+2) & 0xc0) == 0x80 && // 3rd byte is 10xxxxxx (*(cp+3) & 0xc0) == 0x80 && // 4th byte is 10xxxxxx ((*cp & 0x07) | (*(cp+1) & 0x30))) { // 11110[xxx] 10[xx]xxxx 10xxxxxx 10xxxxxx return 4; } return 0; } #endif int suhosin_rfc1867_filter(unsigned int event, void *event_data, void **extra TSRMLS_DC) { int retval = SUCCESS; SDEBUG("rfc1867_filter %u", event); switch (event) { case MULTIPART_EVENT_START: case MULTIPART_EVENT_FORMDATA: /* nothing todo */ break; case MULTIPART_EVENT_FILE_START: { multipart_event_file_start *mefs = (multipart_event_file_start *) event_data; /* Drop if no more variables flag is set */ if (SUHOSIN_G(no_more_uploads)) { goto continue_with_failure; } /* Drop this fileupload if the limit is reached */ if (SUHOSIN_G(upload_limit) && SUHOSIN_G(upload_limit) <= SUHOSIN_G(num_uploads)) { suhosin_log(S_FILES, "configured fileupload limit exceeded - file dropped"); if (!SUHOSIN_G(simulation)) { SUHOSIN_G(no_more_uploads) = 1; goto continue_with_failure; } } if (check_fileupload_varname(mefs->name TSRMLS_CC) == FAILURE) { goto continue_with_failure; } } break; case MULTIPART_EVENT_FILE_DATA: if (SUHOSIN_G(upload_disallow_elf)) { multipart_event_file_data *mefd = (multipart_event_file_data *) event_data; if (mefd->offset == 0 && mefd->length > 10) { if (mefd->data[0] == 0x7F && mefd->data[1] == 'E' && mefd->data[2] == 'L' && mefd->data[3] == 'F') { suhosin_log(S_FILES, "uploaded file is an ELF executable - file dropped"); if (!SUHOSIN_G(simulation)) { goto continue_with_failure; } } } } if (SUHOSIN_G(upload_disallow_binary)) { multipart_event_file_data *mefd = (multipart_event_file_data *) event_data; char *cp, *cpend; int n; cpend = mefd->data + mefd->length; for (cp = mefd->data; cp < cpend; cp++) { if (*cp >= 32 || isspace(*cp)) { continue; } #ifdef SUHOSIN_EXPERIMENTAL if ((*cp & 0x80) && SUHOSIN_G(upload_allow_utf8)) { SDEBUG("checking char %x", *cp); if ((n = suhosin_validate_utf8_multibyte(cp, cpend-cp))) { // valid UTF8 multibyte character cp += n - 1; continue; } } #endif suhosin_log(S_FILES, "uploaded file contains binary data - file dropped"); if (!SUHOSIN_G(simulation)) { goto continue_with_failure; } break; } } if (SUHOSIN_G(upload_remove_binary)) { multipart_event_file_data *mefd = (multipart_event_file_data *) event_data; size_t i, j; int n; for (i=0, j=0; ilength; i++) { if (mefd->data[i] >= 32 || isspace(mefd->data[i])) { mefd->data[j++] = mefd->data[i]; } #ifdef SUHOSIN_EXPERIMENTAL else if (SUHOSIN_G(upload_allow_utf8) && mefd->data[i] & 0x80) { n = suhosin_validate_utf8_multibyte(mefd->data + i, mefd->length - i); if (!n) { continue; } while (n--) { mefd->data[j++] = mefd->data[i++]; } i--; } #endif } mefd->data[j] = '\0'; SDEBUG("removing binary %zu %zu",i,j); /* IMPORTANT FOR DAISY CHAINING */ mefd->length = j; if (mefd->newlength) { *mefd->newlength = j; } } break; case MULTIPART_EVENT_FILE_END: if (SUHOSIN_G(upload_verification_script)) { multipart_event_file_end *mefe = (multipart_event_file_end *) event_data; char cmd[8192]; FILE *in; int first=1; struct stat st; char *sname = SUHOSIN_G(upload_verification_script); /* ignore files that will get deleted anyway */ if (mefe->cancel_upload) { break; } /* ignore empty scriptnames */ while (isspace(*sname)) ++sname; if (*sname == 0) { SUHOSIN_G(num_uploads)++; break; } if (VCWD_STAT(sname, &st) < 0) { suhosin_log(S_FILES, "unable to find fileupload verification script %s - file dropped", sname); if (!SUHOSIN_G(simulation)) { goto continue_with_failure; } else { goto continue_with_next; } } if (access(sname, X_OK|R_OK) < 0) { suhosin_log(S_FILES, "fileupload verification script %s is not executable - file dropped", sname); if (!SUHOSIN_G(simulation)) { goto continue_with_failure; } else { goto continue_with_next; } } ap_php_snprintf(cmd, sizeof(cmd), "%s %s 2>&1", sname, mefe->temp_filename); if ((in=VCWD_POPEN(cmd, "r"))==NULL) { suhosin_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", sname); if (!SUHOSIN_G(simulation)) { goto continue_with_failure; } else { goto continue_with_next; } } retval = FAILURE; /* read and forget the result */ while (1) { int readbytes = fread(cmd, 1, sizeof(cmd), in); if (readbytes<=0) { break; } if (first) { if (strncmp(cmd, "sh: ", 4) == 0) { /* assume this is an error */ suhosin_log(S_FILES, "error while executing fileupload verification script %s - file dropped", sname); if (!SUHOSIN_G(simulation)) { goto continue_with_failure; } else { goto continue_with_next; } } else { retval = atoi(cmd) == 1 ? SUCCESS : FAILURE; first = 0; } } } pclose(in); } if (retval != SUCCESS) { suhosin_log(S_FILES, "fileupload verification script disallows file - file dropped"); if (!SUHOSIN_G(simulation)) { goto continue_with_failure; } } SUHOSIN_G(num_uploads)++; break; case MULTIPART_EVENT_END: /* nothing todo */ break; default: /* unknown: return failure */ goto continue_with_failure; } continue_with_next: #if HAVE_RFC1867_CALLBACK if (php_rfc1867_callback != NULL) { return php_rfc1867_callback(event, event_data, extra TSRMLS_CC); } #endif return SUCCESS; continue_with_failure: SUHOSIN_G(abort_request) = 1; return FAILURE; } /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */