I have a very very strange thing only on some websites. I have restarted the server where many websites are hosted (for maintenance reasons) and after reboot, some websites only have a ? at the end of their URL. At the end of website URL I get index.php? instead of index.php only previously.
Normally URL is https://www.example.com/index.php , but now suddenly is https://www.example.com/index.php?
For info, before restart everything was fine. Nothing has been changed (on nginx or admin tools file maker..nothing)
Do you have an idea why? Do you think admin tools nginx file maker can be the root cause?
I don't understand why and how, as everything was ok before server reboot.
I'm using debian 9.5, nginx 1.15.5, PHP 7.2.11, MySQL 5.7.24
Below more infos about my Nginx conf files.
Main file nginx.conf located here : /etc/nginx/
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
load_module modules/ngx_http_modsecurity_module.so;
events {
worker_connections 1024;
}
http {
# Basic Settings
disable_symlinks off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
server_tokens off;
sendfile on;
tcp_nopush on;
#tcp_nodelay on;
server_names_hash_max_size 1024;
server_names_hash_bucket_size 64;
types_hash_max_size 2048;
# (default is 8k or 16k) The directive specifies the client request body buffer size.
# If the request body is more than the buffer, then the entire request body or some part is written in a temporary file.
client_body_buffer_size 16K;
# Directive sets the headerbuffer size for the request header from client. For the overwhelming
# majority of requests a buffer size of 1K is sufficient. Increase this if you have a custom header
# or a large cookie sent from the client (e.g., wap client).
client_header_buffer_size 1k;
# Directive assigns the maximum accepted body size of client request, indicated by the line Content-Length
# in the header of request. If size is greater the given one, then the client gets the error
# "Request Entity Too Large" (413). Increase this when you are getting file uploads via the POST method.
client_max_body_size 32m;
# Directive assigns the maximum number and size of buffers for large headers to read from client request.
# By default the size of one buffer is equal to the size of page, depending on platform this either 4K or 8K,
# if at the end of working request connection converts to state keep-alive, then these buffers are freed.
# 2x1k will accept 2kB data URI. This will also help combat bad bots and DoS attacks.
large_client_header_buffers 4 8k;
# The first parameter assigns the timeout for keep-alive connections with the client.
# The server will close connections after this time. The optional second parameter assigns
# the time value in the header Keep-Alive: timeout=time of the response. This header can
# convince some browsers to close the connection, so that the server does not have to. Without
# this parameter, nginx does not send a Keep-Alive header (though this is not what makes a connection "keep-alive").
keepalive_timeout 300 300;
# Directive sets the read timeout for the request body from client.
# The timeout is set only if a body is not get in one readstep. If after
# this time the client send nothing, nginx returns error "Request time out"
# (408). The default is 60.
client_body_timeout 600;
# Directive assigns timeout with reading of the title of the request of client.
# The timeout is set only if a header is not get in one readstep. If after this
# time the client send nothing, nginx returns error "Request time out" (408).
client_header_timeout 600;
# Directive assigns response timeout to client. Timeout is established not on entire
## transfer of answer, but only between two operations of reading, if after this time
# client will take nothing, then nginx is shutting down the connection.
send_timeout 600;
# Solve upstream sent too big header while reading response header from upstream
# http://wiki.nginx.org/HttpProxyModule
# This directive set the buffer size, into which will be read the first part of the response, obtained from the proxied server.
# Default: 4k|8k
#proxy_buffer_size 128k;
# This directive sets the number and the size of buffers, into which will be
read the answer, obtained from the proxied server.
# By default, the size of one buffer is equal to the size of page. Depending
on platform this is either 4K or 8K.
#proxy_buffers 4 256k;
#proxy_busy_buffers_size 256k;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
fastcgi_buffers 8 128k;
fastcgi_buffer_size 256k;
fastcgi_read_timeout 600;
fastcgi_ignore_client_abort on;
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_min_length 1000;
gzip_buffers 4 32k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/xhtml application/json
application/x-javascript text/xml application/xml application/xml+rss
text/javascript application/x-font-ttf application/javascript font/eot
font/opentype image/svg+xml image/x-icon;
#gzip_disable "MSIE [1-6]\.";
gzip_disable "MSIE [1-6].(?!.*SV1)";
include /etc/nginx/conf.d/*.conf;
}
File 00-default.conf located here : /etc/nginx/conf.d/
server {
server_name _;
listen 80 default_server;
listen 443 ssl default_server;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
return 404;
}
File example.conf for each website hosted on the server located here : /etc/nginx/conf.d/
server {
listen 80;
listen [::]:80;
server_name www.example.fr example.fr;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.example.fr example.fr;
root /home/example/www/;
index index.html index.htm index.php;
access_log /var/log/nginx/example.access_log;
error_log /var/log/nginx/example.error_log info;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.2-fpm-example.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
include /etc/nginx/conf/security.conf;
location ^~ /administrator {
auth_basic "Authentification Requise";
auth_basic_user_file /home/example/www/administrator/.htpasswd;
}
include /etc/nginx/conf/joomla.conf;
ssl_certificate /etc/letsencrypt/live/example.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.fr/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.fr/chain.pem;
include /etc/nginx/conf/ssl.conf;
}
File security.conf for global security settings located here : /etc/nginx/conf/
### Prevent access to this file
location = /nginx.conf {
log_not_found off;
access_log off;
return 404;
break;
}
######################################################################
## Protect against common file injection attacks
######################################################################
set $file_injection 0;
if ($query_string ~ "[a-zA-Z0-9_]=http://") {
set $file_injection 1;
}
if ($query_string ~ "[a-zA-Z0-9_]=(\.\.//?)+") {
set $file_injection 1;
}
if ($query_string ~ "[a-zA-Z0-9_]=/([a-z0-9_.]//?)+") {
set $file_injection 1;
}
if ($file_injection = 1) {
return 403;
break;
}
######################################################################
## Disable PHP Easter Eggs
######################################################################
if ($query_string ~ "\=PHP[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}") {
return 403;
break;
}
######################################################################
## Block access to configuration.php-dist and htaccess.txt
######################################################################
location = /configuration.php-dist {
log_not_found off;
access_log off;
return 404;
break;
}
location = /htaccess.txt {
log_not_found off;
access_log off;
return 404;
break;
}
location = /web.config {
log_not_found off;
access_log off;
return 404;
break;
}
location = /configuration.php {
log_not_found off;
access_log off;
return 404;
break;
}
location = /CONTRIBUTING.md {
log_not_found off;
access_log off;
return 404;
break;
}
location = /joomla.xml {
log_not_found off;
access_log off;
return 404;
break;
}
location = /LICENSE.txt {
log_not_found off;
access_log off;
return 404;
break;
}
location = /phpunit.xml {
log_not_found off;
access_log off;
return 404;
break;
}
location = /README.txt {
log_not_found off;
access_log off;
return 404;
break;
}
location = /web.config.txt {
log_not_found off;
access_log off;
return 404;
break;
}
## Protect against clickjacking
add_header X-Frame-Options SAMEORIGIN;
######################################################################
## Directory indices and no automatic directory listings
## Forces index.php to be read before the index.htm(l) files
## Also disables showing files in a directory automatically
######################################################################
index index.php index.html index.htm;
######################################################################
### Redirect non-www to www
#######################################################################
if ($host = 'alex-alu.fr' ) {
rewrite ^/(.*)$ $scheme://www.example.fr/$1 permanent;
}
######################################################################
## Disable following symlinks
######################################################################
disable_symlinks if_not_owner;
######################################################################
## Automatic compression of static resources
## Compress text, html, javascript, css, xml and other static resources
## May kill access to your site for old versions of Internet Explorer
######################################################################
# The following is the actual automatic compression setup
gzip on;
gzip_vary on;
gzip_comp_level 6;
gzip_proxied expired no-cache no-store private auth;
gzip_min_length 1000;
gzip_http_version 1.1;
gzip_types text/plain text/css application/xhtml+xml
application/xml+rss application/rss+xml application/x-javascript
application/javascript text/javascript application/json text/xml
application/xml image/svg+xml;
gzip_buffers 16 8k;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
## HSTS Header - See
http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
add_header Strict-Transport-Security max-age=31536000;
## Referrer-policy
add_header Referrer-Policy "unsafe-url";
## Disable HTTP methods TRACE and TRACK (protect against XST)
if ($request_method ~ ^(TRACE|TRACK)$ ) {
return 405;
}
## Reduce MIME type security risks
add_header X-Content-Type-Options "nosniff";
## Reflected XSS prevention
add_header X-XSS-Protection "1; mode=block";
## Prevent content transformation
add_header Cache-Control "no-transform";
# -- Socket settings, see http://wiki.nginx.org/HttpCoreModule
connection_pool_size 8192;
client_header_buffer_size 4k;
large_client_header_buffers 8 8k;
request_pool_size 8k;
# -- Performance, see http://wiki.nginx.org/HttpCoreModule
sendfile on;
sendfile_max_chunk 1m;
postpone_output 0;
tcp_nopush on;
tcp_nodelay on;
# -- Output buffering, see http://wiki.nginx.org/HttpCoreModule
output_buffers 8 32k;
# -- Filehandle Cache, useful when serving a large number of static files
(Joomla! sites do that)
open_file_cache max=2000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# -- Character encoding, see http://wiki.nginx.org/HttpCharsetModule
charset utf-8;
source_charset utf-8;
# -- Security options, see http://wiki.nginx.org/HttpCoreModule
server_name_in_redirect off;
server_tokens off;
ignore_invalid_headers on;
# -- Maximum client body size set to 1 Gigabyte
client_max_body_size 1G;
set $common_exploit 0;
if ($query_string ~ "proc/self/environ") {
set $common_exploit 1;
}
if ($query_string ~ "mosConfig_[a-zA-Z_]{1,21}(=|\%3D)") {
set $common_exploit 1;
}
if ($query_string ~ "base64_(en|de)code\(.*\)") {
set $common_exploit 1;
}
if ($query_string ~ "(<|%3C).*script.*(>|%3E)") {
set $common_exploit 1;
}
if ($query_string ~ "GLOBALS(=|\[|\%[0-9A-Z]{0,2})") {
set $common_exploit 1;
}
if ($query_string ~ "_REQUEST(=|\[|\%[0-9A-Z]{0,2})") {
set $common_exploit 1;
}
if ($common_exploit = 1) {
return 403;
}
## Enable SEF URLs
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~* /index.php$ {
fastcgi_pass unix:/var/run/php/php7.2-fpm-example.sock;
fastcgi_index index.php;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
break;
}
######################################################################
## Advanced server protection rules exceptions
######################################################################
location = /administrator/components/com_akeeba/restore.php {
fastcgi_pass unix:/var/run/php/php7.2-fpm-example.sock;
fastcgi_index index.php;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
break;
}
location = /administrator/components/com_admintools/restore.php {
fastcgi_pass unix:/var/run/php/php7.2-fpm-example.sock;
fastcgi_index index.php;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
break;
}
location = /administrator/components/com_joomlaupdate/restore.php {
fastcgi_pass unix:/var/run/php/php7.2-fpm-example.sock;
fastcgi_index index.php;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
break;
}
location = /robots.txt {
break;
}
location ~* ^/cache/.*\.php$
{
break;
}
location ~* ^/cache/.*$
{
break;
}
location ~* ^/cache\/nextend/.*\.php$
{
break;
}
location ~* ^/cache\/nextend/.*$
{
break;
}
location ~* ^/cache\/t3_assets/.*\.php$
{
break;
}
location ~* ^/cache\/t3_assets/.*$
{
break;
}
location ~* ^/cache\/t3_pages/.*\.php$
{
break;
}
location ~* ^/cache\/t3_pages/.*$
{
break;
}
location ~* ^/images/.*\.php$
{
break;
}
location ~* ^/images/.*$
{
break;
}
location ~* ^/t3\-assets/.*\.php$
{
break;
}
location ~* ^/t3\-assets/.*$
{
break;
}
location ~* ^/t3\-assets\/css/.*\.php$
{
break;
}
location ~* ^/t3\-assets\/css/.*$
{
break;
}
location ~* ^/t3\-assets\/js/.*\.php$
{
break;
}
location ~* ^/t3\-assets\/js/.*$
{
break;
}
######################################################################
## Advanced server protection
######################################################################
# Allow media files in select back-end directories
location ~*
^/administrator/(components|modules|templates|images|plugins)/.*. (jpe|jpg|jpeg|jp2|jpe2|png|gif|bmp|css|js|swf|html|mpg|mp3|mpeg|mp4|avi|wav|ogg|ogv|xls|xlsx|doc|docx|ppt|pptx|zip|rar|pdf|xps|txt|7z|svg|odt|ods|odp|flv|mov|htm|ttf|woff|woff2|eot|JPG|JPEG|PNG|GIF|CSS|JS|TTF|WOFF|WOFF2|EOT)$ {
break;
}
# Allow access to the back-end index.php file
location = /administrator/index.php {
fastcgi_pass unix:/var/run/php/php7.2-fpm-example.sock;
fastcgi_index index.php;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
break;
}
location ~* ^/administrator$ {
return 301 /administrator/index.php?$args;
}
location ~* ^/administrator/$ {
return 301 /administrator/index.php?$args;
}
# Disable access to everything else.
location ~* /administrator.*$ {
# If it is a file, directory or symlink and I haven't deliberately
# enabled access to it, forbid any access to it!
if (-e $request_filename) {
return 403;
}
# In any other case, just treat as a SEF URL
try_files $uri $uri/ /administrator/index.php?$args;
}
# Allow media files in select front-end directories
location ~* ^/(components|modules|templates|images|plugins|media|libraries|media/jui/fonts)/.*. (jpe|jpg|jpeg|jp2|jpe2|png|gif|bmp|css|js|swf|html|mpg|mp3|mpeg|mp4|avi|wav|ogg|ogv|xls|xlsx|doc|docx|ppt|pptx|zip|rar|pdf|xps|txt|7z|svg|odt|ods|odp|flv|mov|ico|htm|ttf|woff|woff2|eot|JPG|JPEG|PNG|GIF|CSS|JS|TTF|WOFF|WOFF2|EOT)$ {
break;
}
## Disallow front-end access for certain Joomla! system directories (unless
access to their files is allowed above)
location ~* ^/includes/js/ {
return 403;
}
location ~* ^/(cache|includes|language|logs|log|tmp)/ {
return 403;
}
# Allow access to /
location ~* ^/$ {
return 301 /index.php?$args;
}
# Disable access to everything else.
location ~* ^/.*$ {
# If it is a file, directory or symlink and I haven't deliberately
# enabled access to it, forbid any access to it!
if (-e $request_filename) {
return 403;
}
# In any other case, just treat as a SEF URL
try_files $uri $uri/ /index.php?$args;
}
Thanks L.
There isn't enough information here to determine the cause, but it's harmless.
In a URL, a
?
character indicates the end of the resource's location and anything after the?
is a parameter which should be passed to the resource at that location. For example, in the URL https://www.google.com/search?q=testing, the resource is https://www.google.com/search (everything before the?
), and it will be given a single parameter namedq
with the valuetesting
(q=testing
after the?
).index.php
andindex.php?
are thus equivalent - both of them mean to accessindex.php
and give it no parameters.As for possible causes, I'd guess that it's probably either a rewrite rule or a page template which is appending a
?
on the off chance that there might be parameters added to the URL later, so that the code doesn't need to keep track of whether it's already been added or not.