php-suhosin question

Hi,

Sorry if this should go in the 'Off-Topic' section but I wasn't sure..
I have php7 running and I have a need to enable proc_open().
As I am using security/php-suhosin I want to add the following in my /etc/php.ini file
Code:
suhosin.executor.func.whitelist = proc_open
Question is do I need to keep the following in the FILE]/etc/php.ini[/FILE] file?
Code:
disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitin
fo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority
or do I need to move the above in suhosin.executor.func.blacklist =

Also is it possible to enable proc_open() per directory?
Thank you in advance
 
php disable_finctions and suhosin blacklist work in different ways, understanding the difference will help you decide which is better for your environment.

php disable_functions will block the function but the rest of the code will be executed.
suhosin will block the entire script calling the code.

suhosin has its own blacklist, so basically the suhosin whitelist has no interaction with your php disable_functions

By default suhosin blocks no functions as the blacklist and whitelist are empty by default.

Now if you use the suhosin whitelist, it will then block everything that is not whitelisted in suhosin. This is on top of what php is filtering. The suhosin whitelist will "not" overide disable_functions as that is a php not suhosin directive.
 
Last edited:
php-fpm and suhosin are different things.

Urm.. You're right. I was thinking if suexec which isn't needed if using open_basedir and disable_functions.

suhosin does protect the webserver from such things like sql-injection, remote-file-injection, etc. I don't use suhosin since my server have Snort IPS on the frontend that blocks such attacks. It won't prevent all attacks but its better than none but open_basedir is very important as it locks everything inside the directory so the php code won't be able to read/write/execute anything outside of the directory.

If want absolute security then use suexec, suhosin, mod_security, snort which is difficult to configure and fine-tune, open_basedir, and disable_functions.
 
Remington ,
How would you enable proc_open oer directory in php-fpm?

This is what I have for my web servers:

Code:
php_admin_value[open_basedir]      = /usr/local/www:/usr/local/php/7.0/lib/php
php_admin_value[disable_functions] = "exec,passthru,shell_exec,system,proc_open,popen,show_source"

You don't want to overdo the security otherwise it'll break some php codes. That's why I have open_basedir to basically chroot all php codes to its directory. I don't use suhosin, suexec or mod_security since above parameters are sufficient.

PHP-FPM allows you to have separate open_basedir for each users so everything can be confined to user's directory. BTW, all my web servers use Nginx and suhosin, suexec or mod_security don't work with Nginx.
 
Remington
Thank you for the code above.
What is the difference between adding disable_functions and open_basedir in php-fpm or php.ini?
 
Remington
Thank you for the code above.
What is the difference between adding disable_functions and open_basedir in php-fpm or php.ini?

If you use open_basedir in php.ini and it will apply to all users. If you include open_basedir in /usr/local/etc/php-fpm.d/john.conf for user John then it'll be confined to that user which will be more specific directories such as /home/john/public_html. I would recommend having a separate php-fpm pool config for each users so the rules and sockets will be tied to that specific user without sharing with other users which could be a security risk.

Here is an example of john.conf but you'll have to modify it to your specs. Group www is required for Nginx web server.

Code:
;;;;;;;;;;;;;;;;;;;;
; Pool Definitions ;
;;;;;;;;;;;;;;;;;;;;

[john]
user                               = john
group                              = www

listen                             = /var/run/john.sock
listen.owner                       = john
listen.group                       = www
listen.mode                        = 0660

pm                                 = ondemand
pm.max_children                    = 10
pm.max_requests                    = 200
pm.status_path                     = /status
pm.process_idle_timeout            = 60s
request_terminate_timeout          = 120s

env[HOSTNAME]                      = $HOSTNAME
env[TMP]                           = /home/john/tmp
env[TMPDIR]                        = /home/john/tmp
env[TEMP]                          = /home/john/tmp

php_admin_value[open_basedir]      = /home/john/public_html:/usr/local/php70/lib/php
php_admin_value[disable_functions] = "exec,passthru,shell_exec,system,proc_open,popen,show_source"
php_admin_value[date.timezone]     = Europe/Moscow

php_flag[display_errors]           = off
php_admin_flag[log_errors]         = on
php_admin_value[error_reporting]   = 30711
php_admin_value[error_log]         = /var/log/php-fpm/john.error.log
php_admin_value[memory_limit]      = 128M
php_admin_value[upload_tmp_dir]    = /home/john/tmp
php_admin_value[session.save_path] = /home/john/tmp
 
Remington This sample is awsome I can see for the first time what the fuzz is all about and yes it make sense now.
last question..Does the user 'john' need to exist in /etc/passwd or can it be any name?
 
Remington This sample is awsome I can see for the first time what the fuzz is all about and yes it make sense now.
last question..Does the user 'john' need to exist in /etc/passwd or can it be any name?

Can be any name and you don't need to create account for each user since unless if user will login using ssh or sftp.
 
hi Remington
I am trying to implement the example you gace me above on test site..
Could you please tell me how to tell the webserver to use the pool john.conf?
 
hi Remington
I am trying to implement the example you gace me above on test site..
Could you please tell me how to tell the webserver to use the pool john.conf?

You will need to add this john.sock line in your nginx config file.

Code:
location ~ \.php$ {
    try_files                         $uri =404;
    fastcgi_split_path_info           ^(.+\.php)(/.+)$;
    fastcgi_pass                      unix:/var/run/php-fpm/john.sock;
    fastcgi_index                     index.php;
    ....
}
 
Remington
Still setting up my php.ini and reading a lot on the stuff but the file has so many comment and that I am getting overwelmed...

I got to a finished point now but I was wondering if we could compare notes..
Would you mind posting your php.ini so I can see how different mine is and look at the differences?
This is mine so far:
Code:
;;;;;;;;;;;;;;;;;;;;
; Language Options ;
;;;;;;;;;;;;;;;;;;;;

engine = On
short_open_tag = Off
precision = 14
output_buffering = 4096
zlib.output_compression = On
zlib.output_compression_level = 6
implicit_flush = Off
serialize_precision = 17
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl,curl_multi_exec,parse_ini_file,show_source
zend.enable_gc = On

;;;;;;;;;;;;;;;;;
; Miscellaneous ;
;;;;;;;;;;;;;;;;;

expose_php = Off
cgi.fix_pathinfo=0

;;;;;;;;;;;;;;;;;;;
; Resource Limits ;
;;;;;;;;;;;;;;;;;;;

max_execution_time = 60
max_input_time = 60
max_input_vars = 3000
memory_limit = 128M

[Suhosin]
;suhosin.memory_limit = 0
;suhosin.request.max_vars = 3000
;suhosin.request.max_value_length = 1000000
;suhosin.request.max_array_index_length = 256
;suhosin.request.max_totalname_length = 8192
;suhosin.post.max_vars = 3000
;suhosin.post.max_array_index_length = 256
;suhosin.post.max_totalname_length = 8192
;suhosin.post.max_value_length = 1000000
;suhosin.get.max_vars = 3000
;suhosin.get.max_array_index_length = 256
;suhosin.get.max_totalname_length = 8192
;suhosin.get.max_value_length = 1000000
;suhosin.sql.bailout_on_error = Off
;suhosin.log.phpscript.is_safe = Off
;suhosin.log.script = 0
;suhosin.log.use-x-forwarded-for = Off

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Error handling and logging ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors = Off    #Do not expose PHP error messages to all site visitors
display_startup_errors = Off
log_errors = On
error_log = /var/log/php_errors.log
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
track_errors = Off
html_errors = On

;;;;;;;;;;;;;;;;;
; Data Handling ;
;;;;;;;;;;;;;;;;;

variables_order = "GPCS"
request_order = "GP"
register_argc_argv = Off
auto_globals_jit = On
post_max_size = 48M
default_mimetype = "text/html"
default_charset = "UTF-8"


cgi.rfc2616_headers = 0


;;;;;;;;;;;;;;;;;;;;;;;;;
; Paths and Directories ;
;;;;;;;;;;;;;;;;;;;;;;;;;

enable_dl = Off

;;;;;;;;;;;;;;;;
; File Uploads ;
;;;;;;;;;;;;;;;;

file_uploads = On
upload_max_filesize = 2M
max_file_uploads = 20

;;;;;;;;;;;;;;;;;;
; Fopen wrappers ;
;;;;;;;;;;;;;;;;;;

allow_url_fopen = Off
allow_url_include = Off
default_socket_timeout = 60

;;;;;;;;;;;;;;;;;;;
; Module Settings ;
;;;;;;;;;;;;;;;;;;;

[CLI Server]
cli_server.color = On

[Date]
date.timezone = Europe/London

[Pdo_mysql]
pdo_mysql.cache_size = 2000

[mail function]
SMTP = localhost
smtp_port = 25
mail.add_x_header = On

[SQL]
sql.safe_mode = Off

[ODBC]
odbc.allow_persistent = On
odbc.check_persistent = On
odbc.max_persistent = -1
odbc.max_links = -1
odbc.defaultlrl = 4096
odbc.defaultbinmode = 1

[Interbase]
ibase.allow_persistent = 1
ibase.max_persistent = -1
ibase.max_links = -1
ibase.timestampformat = "%Y-%m-%d %H:%M:%S"
ibase.dateformat = "%Y-%m-%d"
ibase.timeformat = "%H:%M:%S"

[MySQLi]
mysqli.max_persistent = -1
mysqli.allow_persistent = On
mysqli.max_links = -1
mysqli.cache_size = 2000
mysqli.default_port = 3306
mysqli.reconnect = Off

[mysqlnd]
mysqlnd.collect_statistics = On
mysqlnd.collect_memory_statistics = Off

[PostgreSQL]
pgsql.allow_persistent = On
pgsql.auto_reset_persistent = Off
pgsql.max_persistent = -1
pgsql.max_links = -1
pgsql.ignore_notice = 0
pgsql.log_notice = 0

[bcmath]
bcmath.scale = 0

[Session]
session.save_handler = files
session.use_strict_mode = 0
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.referer_check =
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.hash_function = 0
session.hash_bits_per_character = 5
url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry"

[Assertion]
zend.assertions = -1

[Tidy]
tidy.clean_output = Off

[soap]
soap.wsdl_cache_enabled=1
soap.wsdl_cache_dir="/tmp"
soap.wsdl_cache_ttl=86400
soap.wsdl_cache_limit = 5

[ldap]
ldap.max_links = -1

[opcache]
opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=32
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=3000
opcache.validate_timestamps=2
opcache.revalidate_freq=180
opcache.revalidate_path=0
opcache.fast_shutdown=0
opcache.max_file_size=0
opcache.file_cache=/usr/local/www/production/httpdocs/.opcache
opcache.file_cache_only=1
and my test user ...
Code:
[r610]
user = r610
group = www

listen = /var/run/r610.sock

listen.owner = r610
listen.group = www
listen.mode = 0660

pm = ondemand
pm.max_children = 20
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.process_idle_timeout = 60s;
pm.max_requests = 200
pm.status_path = /status
request_terminate_timeout = 0

env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /home/r610/tmp
env[TMPDIR] = /home/r610/tmp
env[TEMP] = /home/r610/tmp

;php_admin_value[open_basedir]      = /home/r610/public_html:/home/r610/tmp:/usr/local/share/pear:/usr/local/php70/lib/php
php_admin_value[disable_functions] = "exec,passthru,shell_exec,system,proc_open,popen,show_source"
php_admin_value[date.timezone]     = Europe/London

php_flag[display_errors]           = off
php_admin_flag[log_errors]         = on
php_admin_value[error_reporting]   = 30711
php_admin_value[error_log]         = /var/log/php-fpm/r610.error.log
php_admin_value[memory_limit]      = 128M
php_admin_value[upload_tmp_dir]    = /home/r610/tmp
php_admin_value[session.save_path] = /home/r610/tmp
I have wordpress runing with that config but looking at way to inprove on security and improve performence
 
Back
Top