Turned on cgi.fix_pathinfo still "dangerous" in Nginx?

I would not describe this change as "critical" per se, but it still has security implications. I'm not aware of anything that has fundamentally changed since that advice became relevant -- PHP's behavior tends strongly towards backwards compatibility, even when that has security implications. Imagine you have a server that allows people to upload files to the server, say in a directory called upload. Now, your upload script is careful to only allow files with certain extensions (say only .png) to ensure nobody uploads a malicious PHP file.

Now, as an attacker, I'll try to write a PHP shell into a file, name the file evil.png, and upload it. When it uploads, I'll visit http://example.com/upload/evil.png, but I'll discover that this just downloads the file to me -- nginx never dispatched the request to php-fcgi to be processed as php, because the filename ends in .png.

If I'm an attacker who's aware of PATH_INFO, next I'll try http://example.com/upload/evil.png/index.php. If your server is so configured, this will result in PHP being executed (because nginx sees the index.php at the end) and PHP will walk the path until it finds a component that is a file, not a directory (evil.png) and attempt to execute it. Then my shell gets executed and I win.

That being said, there's better ways to deal with this by having the NGINX config split the path in advance, so PHP isn't walking the filesystem.

From Neal Poole's excellent blog post on the issue:

# Pass all .php files onto a php-fpm/php-fcgi server.
location ~ \.php$ {
   # Zero-day exploit defense.
   # http://forum.nginx.org/read.php?2,88845,page=3
   # Won't work properly (404 error) if the file is not stored on this server, which is entirely possible with php-fpm/php-fcgi.
   # Comment the 'try_files' line out if you set up php-fpm/php-fcgi on another machine.  And then cross your fingers that you won't get hacked.
   try_files $uri =404;

   fastcgi_split_path_info ^(.+\.php)(/.+)$;
   include fastcgi_params;
   fastcgi_index index.php;
   fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
   fastcgi_pass php;
}

Even now it seems to carry danger because of how PHP is still processing script from the 1st occurence of found file. So why did they keep the default as ;cgi.fix_pathinfo=1 then?

Because CGI is independent of PHP and have its own standard. CGI (Common Gateway Interface) is an interface that instructs the server on how to communicate data with applications, how request information and body is passed, from input to output. Servers of Web can be configured to execute a program as a CGI, which means they will forward the request data to a specific program. And that's how NGinx passes request to PHP.

Speaking of CGI Standard, PHP-FPM developers have to comply with CGI standard as they stated in the PHP-FPM ini file ex : /etc/php/7.2/fpm/php.ini :

; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI.  PHP's
; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok
; what PATH_INFO is.  For more information on PATH_INFO, see the cgi specs.  Setting
; this to 1 will cause PHP CGI to fix its paths to conform to the spec.  A setting
; of zero causes PHP to behave as before.  Default is 1.  You should fix your scripts
; to use SCRIPT_FILENAME rather than PATH_TRANSLATED.
; http://php.net/cgi.fix-pathinfo
;cgi.fix_pathinfo=1

So I suppose the text Setting this to 1 will cause PHP CGI to fix its paths to conform to the spec. A setting of zero causes PHP to behave as before. explains the choice. Here is the PATH_INFO CGI Spec.