security.limit_extensions ?
danmbox opened this issue · 4 comments
Wouldn't security.limit_extensions = .php .php3 .php4 .php5
also be useful? Perhaps a warning about cgi.fix_pathinfo
?
Aren't those Nginx settings not php.ini
ones?
That is a PHP-FPM config setting. That is not set via php.ini
, but rather in the php-fpm.conf
and/or php-fpm.d/*
PHP-FPM config files. Keep in mind this is per pool so each pool config file should be parsed.
; Limits the extensions of the main script FPM will allow to parse. This can
; prevent configuration mistakes on the web server side. You should only limit
; FPM to .php extensions to prevent malicious users to use other extensions to
; exectute php code.
; Note: set an empty value to allow all extensions.
; Default Value: .php
;security.limit_extensions = .php .php3 .php4 .php5 .php7
If we are scanning those config files we can also check the setting for chroot
as well.
; Chroot to this directory at the start. This value must be defined as an
; absolute path. When this value is not set, chroot is not used.
; Note: you can prefix with '$prefix' to chroot to the pool prefix or one
; of its subdirectories. If the pool prefix is not set, the global prefix
; will be used instead.
; Note: chrooting is a great security feature and should be used whenever
; possible. However, all PHP paths will be relative to the chroot
; (error_log, sessions.save_path, ...).
; Default Value: not set
;chroot =
PHP-FPM config files allow setting all php.ini
settings. That being the case, any security checks done on php.ini
's settings should be done to the PHP-FPM config files as well. Since they can overwrite anything set previously.
; Additional php.ini defines, specific to this pool of workers. These settings
; overwrite the values previously defined in the php.ini. The directives are the
; same as the PHP SAPI:
; php_value/php_flag - you can set classic ini defines which can
; be overwritten from PHP call 'ini_set'.
; php_admin_value/php_admin_flag - these directives won't be overwritten by
; PHP call 'ini_set'
; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no.
; Defining 'extension' will load the corresponding shared extension from
; extension_dir. Defining 'disable_functions' or 'disable_classes' will not
; overwrite previously defined php.ini values, but will append the new value
; instead.
; Note: path INI options can be relative and will be expanded with the prefix
; (pool, global or @prefix@)
; Default Value: nothing is defined by default except the values in php.ini and
; specified at startup with the -d argument
;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M
Hmm, yeah - sounds like PHP-FPM handling might need to be a different beast than the current parsing. I'm not sure how to fit this in best. I assume that the *.conf
files can be in any location the user wants. Do you know if they're included in the "loaded configuration files" list when a PHP CLI is run (or is it only on the web side)?
PHP compile options allow setting php.ini
and php-fpm.conf
locations via the following from their defaults outlined here :
Fine tuning of the installation directories:
--bindir=DIR user executables [EPREFIX/bin]
--sbindir=DIR system admin executables [EPREFIX/sbin]
--libexecdir=DIR program executables [EPREFIX/libexec]
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
--datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
--datadir=DIR read-only architecture-independent data [DATAROOTDIR]
--infodir=DIR info documentation [DATAROOTDIR/info]
--localedir=DIR locale-dependent data [DATAROOTDIR/locale]
--mandir=DIR man documentation [DATAROOTDIR/man]
--docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE]
--htmldir=DIR html documentation [DOCDIR]
--dvidir=DIR dvi documentation [DOCDIR]
--pdfdir=DIR pdf documentation [DOCDIR]
--psdir=DIR ps documentation [DOCDIR]
The ones that affect the files we want are the following. But keep in mind their default paths could be a combination of prefixes from other paths set above in addition to a user supplied path.
--sysconfdir=[DIR] # php-fpm.conf and php-fpm.d/*
--with-config-file-path=[DIR] # php.ini
--with-config-file-scan-dir=[DIR] # conf.d/*
Getting the location of .ini
files is easy either through CLI (php --ini
) or through web-side (php_ini_loaded()
or php_ini_scanned_files()
). However, I can't find a way to get the location set for PHP-FPM config files. The only way I see is parsing the output of phpinfo(INFO_GENERAL)
and getting it from the compile options string if path is set by user, and falling back to using the default path if not found.
As for where or if present the php-fpm.d/*
directory is would be harder. Since it can be set to anything and is usually wildcard included from within the php-fpm.conf
file, like the default setup:
; Multiple pools of child processes may be started with different listening
; ports and different management options. The name of the pool will be
; used in logs and stats. There is no limitation on the number of pools which
; FPM can handle. Your system will tell you anyway :)
; Include one or more files. If glob(3) exists, it is used to include a bunch of
; files from a glob(3) pattern. This directive can be used everywhere in the
; file.
; Relative path can also be used. They will be prefixed by:
; - the global prefix if it's been set (-p argument)
; - @prefix@ otherwise
include=@php_fpm_sysconfdir@/php-fpm.d/*.conf
This poses a problem since unlike .ini
files the .conf
files allow includes from within the file. So making sure all of them are included in the scan would need to be addressed as they can point anywhere and (I have not tested) be multiple includes deep.