Veiligere PHP

PHP opzetten is altijd een beetje tricky, en je zult rekening moeten houden met wat valkuilen. De voorbeelden hieronder kunnen je hierbij op weg helpen.

Website met meerdere, direct benaderbare PHP-bestanden

De meeste websites zullen meerdere applicaties hosten (en niet alleen een CMS). Daarom heb je zoiets als hieronder nodig:

server {
    ...
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?xxx...; 
    }

    ...

    location ~ \.php$ {
        # This splits the URI into two variables:
        fastcgi_split_path_info ^(.+\.php)(/.+)$;

        # First, make a copy of $fastcgi_path_info, due to try_files
        # making $fastcgi_path_info empty after doing the try_files.
        set $path_info $fastcgi_path_info;

        # For the sake of security, don't pass non-existing files.
        try_files $fastcgi_script_name =404;

        # 1) $fastcgi_script_name for SCRIPT_FILENAME
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        # 2) The copied $fastcgi_path_info for PATH_INFO
        fastcgi_param PATH_INFO $path_info;

        # Include other environment defaults for FastCGI.
        include fastcgi_params;

        # This is the socket of the running PHP-FPM.
        fastcgi_pass finalx:9000;
    }
}

Websites with just one accessed PHP-file.

If you know that your entire website will be run through a single PHP-file (and its includes), like for example a CMS like Pagekit, you could use this instead. Safer (can't access other scripts) and performing slightly better (no more need for try_files).

Below an example:

server {
    ...

    index index.php;

    location / {
        try_files $uri $uri/ /index.php?xxx...; 
    }

    ...

    # The = in the location is an "exact"-identifier.
    # Without it, it would be matching the 404 section below.
    location = /index.php {
        # This splits the URI into two variables:
        fastcgi_split_path_info ^(.+\.php)(/.+)$;

        # 1) $fastcgi_script_name for SCRIPT_FILENAME
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        # 2) $fastcgi_path_info for PATH_INFO
        fastcgi_param PATH_INFO $fastcgi_path_info;

        # Include other environment defaults for FastCGI.
        include fastcgi_params;

        # This is the socket of the running PHP-FPM.
        fastcgi_pass finalx:9000;
    }

    # WARNING: Do not forget this or your PHP-scripts can be accessed
    # directly and possibly expose code you don't want others to see.
    # All other PHP-files should just return a "404 Not Found".
    location ~ \.php$ {
        # Use 404 and not 403, that way attackers will not be wiser as
        # to the existence of a file and think it does not exist.
        return 404;
    }
}