Today I read a security article on the nginx fastcgi PATH_INFO (Chinese version on 80sec). I currently maintain several sites with nginx+php-fpm, so I decide to do some test and see if my configuration is in danger.
However, when I follow the article carefully and execute the test plan, it finally failed with an “Access denied.” 403 error message. the nginx configuration in my test is so simple that I believe it can’t generate such a 403 error, also tcpdump on php-fpm port confirms that it’s php that returned the 403 error message. After several minutes of googling for the “php-fpm access denied” message with no luck, I decide to have a look at the php souce code.
[Bash]
cd /usr/local/src/php-5.3.x/
grep -Fl ‘Access denied’ . -R
[/Bash]
it gives me the following output:
./ext/mysqli/tests/mysqli_connect_oo.phpt ./ext/mysqli/tests/mysqli_select_db.phpt ./ext/mysqli/tests/mysqli_connect.phpt ./ext/mysqli/tests/mysqli_report.phpt ./ext/mysqli/tests/mysqli_stmt_bind_param_many_columns.phpt ./ext/mysqli/tests/mysqli_real_connect_pconn.phpt ./ext/mysqli/tests/mysqli_report_wo_ps.phpt ./ext/mysqli/tests/mysqli_insert_packet_overflow.phpt ./ext/mysqli/tests/mysqli_real_connect.phpt ./ext/mysql/tests/mysql_connect.phpt ./ext/mysql/tests/mysql_pconnect.phpt ./ext/mysql/tests/mysql_sql_safe_mode.phpt ./ext/pdo_mysql/tests/pdo_mysql___construct.phpt ./sapi/cgi/cgi_main.c ./sapi/fpm/fpm/fpm_main.c
There’s nothing to do with mysql, and I use php-fpm, so I just look into ./sapi/fpm/fpm/fpm_main.c, and find this:
[c]
if (fpm_php_limit_extensions(SG(request_info).path_translated)) {
SG(sapi_headers).http_response_code = 403;
PUTS(“Access denied.\n”);
goto fastcgi_request_done;
}
[/c]
a glance of the “fpm_php_limit_extensions” function leads me to the following php-fpm configuration:
; 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
Until now, it’s obvious that it’s this security limit that caused that access denied message.
Conclusion: When you are bothered with some strange problem in open source software, and google gives you no luck, you may peek the source for some clue.