Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagebash
mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER
     > ON 'prestashop'ALL ON prestashop.* TO 'new_user'@'localhost';
mysql> FLUSH PRIVILEGES;

...

You can now install PrestaShop safely.

Basic authentication establishment (.htaccess)

In order to better protect your PrestaShop install, we need to establish a basic authentication on the admin directory.

One of the aims of the .htaccess file is to protect your folders and all its sub-folders (read http://en.wikipedia.org/wiki/Htaccess). It only works on Apache servers, and a few others. Make sure your web server is Apache before creating a .htaccess file.

To achieve basic authentication on your admin folder, we need to add a .htaccess file in that folder (for instance, /var/www/prestashop/admin):

Code Block
languagenone
AuthUserFile /var/www/.prestashop_admin
AuthName "Prestashop Admin Access"
AuthType Basic
Require valid-user
Options -Indexes

Explanation:

  • AuthUserFile: Shows the path to the file containing allowed users and their passwords. .prestashop_admin is a text file.
  • AuthName: Defines the message to show when the authentication window pops up.
  • AuthType: Defines the authentication type.
  • Require: Requires users to log in in order to access the content. valid-user enables multiple users to connect and access the folder.
  • Options: Defines the folder's options. -Indexes disables automatic generation of a directory index if no index file is available.

Here is a sample content for the .prestashop_admin file, with a login and a password:

Code Block
languagenone
login1:$apr1$/wJeliK8$e9OzgRaVL8J8wSsFBXjor1
login2:$apr1$yV65Kqqz$cFt3sV2.Q7hhLRRUJDo5a/

This file contains logins and hashed password who are allowed to access to the folder.
To hash password, you can use a .htpasswd file generator: http://aspirine.org/htpasswd_en.html.

It is strongly recommended to put this file into a directory that is inaccessible to your web applications, so before the /openbase_dir folder. It prevents .htpasswd file injection, in case one of yours web applications is vulnerable.

It is also possible to perform IP and domain restrictions using your .htaccess file:

Code Block
languagenone
Order Allow, Deny
Deny from all
Allow from .myprestashop.com
Allow from 127.0.0.1

However, you should not put this kind of directive:

Code Block
languagenone
<LIMIT GET POST>
Require valid-user
</LIMIT>

Making your PrestaShop install more secure

The recommendations below are sorted by order of importance:

  1. Secure your back-office
    1. Rename your /admin folder after the PrestaShop installation. This is a must, and you actually cannot access your PrestaShop administration if you haven't performed that change. Make sure to pick a really unique name, ideally a mix of letter and number, such as "my4dm1n".
    2. Protect your admin folder with the .htaccess and .htpasswd files, or ask your web host to do it for you.
    3. Do not let your browser keep traces of your password (cookie or any other helper).
    4. Pick a complex password, by mixing letters, numbers and even punctuation marks, such as "5r3XaDR#". You can and should use a password generator, such as Symantec's (http://www.pctools.com/guides/password/) or GRC's (https://www.grc.com/passwords.htm).

      Tip

      Safer than a password: you can use a passphrase. Not only is a passphrase easier to remember, but it is also much harder to crack, even when the hacker is using automatic tools (brute force attack or dictionary attack).

      A passphrase only needs to be long and easy to remember for you. Any popular saying should do ("Don’t Throw the Baby Out with the Bathwater"), but an absurd phrase will have even less risk of being discovered by a hacker. For instance, "Many reckless drivers confuse tractor with record sleeves".

      There are some good passphrase generators online, which help you get a unique phrase for you only. For instance: http://passphra.se/ or http://www.fourmilab.ch/javascrypt/pass_phrase.html.

      PrestaShop's passwords are not limited in either number of characters or types of characters.

  2. Securing your PHP installation
    1. See the required and recommended PHP settings, at the beginning of this very guide.
  3. Always delete the /install folder after having installed or updated PrestaShop
  4. Always delete useless files from production server:
    1. All readme_xx.txt files.
    2. The CHANGELOG file.
    3. The /docs folder.
  5. Forbid access to your theme's files/templates, using a .htaccess file with the following content:

    Code Block
    languagenone
    <FilesMatch "\.tpl$">
    order deny,allow
    deny from all
    </FilesMatch>
    

Updates

Your applications' PHP code is the only vulnerable path to your server. It is therefore strongly recommended to always update your server's applications: PHP, MySQL, Apache and any other application on which your website runs.

Security

Read this dedicated page, full of easy-to-apply advices.

Fine-tuning & performances

This section will help you better understand configuration variables than are not handled using the back-officeback office, but directly in configuration files.

...

You can also enable the code profiling tool, which displays a lot of information at the bottom of every page: set the define('_PS_DEBUG_PROFILING_', false); line to true, then open front-office front office or back - office page. At the bottom of it, you will find a summary of the page loading performances. Note that you should really disable your store, so that visitors cannot see this information.

...

  • $smarty->caching = false;: Smarty's cache system must be disabled because it is not compatible with PrestaShop.
  • IMPORTANT: in production mode, $smarty->force_compile must be set to "false", as it will give a 30% improvement on page load time. On the other hand, when editing a .tpl file, you will have to delete the content of the /tools/smarty/compile folder (except index.php) in order to see the changes live. Note that this setting can also be done in the back-officeback office, in the "Advanced parameters" > "Performance" page, in the "Smarty" section.
  • $smarty->compile_check should be left to "false".
  • $smarty->debugging gives you access to Smarty's debugging information when your pages are displayed.

...

Code Block
languagephp
if ( $_SERVER['REMOTE_ADDR'] != '127.0.0.1' )
{
  define( '_THEME_IMG_DIR_',   'http://img2.xxxyourdomain.com/'       );
  define( '_THEME_CSS_DIR_',   'http://css.xxxyourdomain.com/'        );
  define( '_THEME_JS_DIR_',    'http://js.xxxyourdomain.com/'         );
  define( '_THEME_CAT_DIR_',   'http://img1.xxxyourdomain.com/c/'     );
  define( '_THEME_PROD_DIR_',  'http://img1.xxxyourdomain.com/p/'     ); 
  define( '_THEME_MANU_DIR_',  'http://img1.xxxyourdomain.com/m/'     ); 
  define( '_PS_IMG_',          'http://img1.xxxyourdomain.com/'       ); 
  define( '_PS_ADMIN_IMG_',    'http://img1.xxxyourdomain.com/admin/' ); 
} else { 
  define( '_THEME_IMG_DIR_',   _THEMES_DIR_ . _THEME_NAME_ . '/img/' ); 
  define( '_THEME_CSS_DIR_',   _THEMES_DIR_ . _THEME_NAME_ . '/css/' ); 
  define( '_THEME_JS_DIR_',    _THEMES_DIR_ . _THEME_NAME_ . '/js/'  ); 
  define( '_THEME_CAT_DIR_',   __PS_BASE_URI__ . 'img/c/'            ); 
  define( '_THEME_PROD_DIR_',  __PS_BASE_URI__ . 'img/p/'            ); 
  define( '_THEME_MANU_DIR_',  __PS_BASE_URI__ . 'img/m/'            ); 
  define( '_PS_IMG_',          __PS_BASE_URI__ . 'img/'              ); 
  define( '_PS_ADMIN_IMG_',    _PS_IMG_.'admin/'                     ); 
}

...

Code Block
location /PRESTASHOP_FOLDER/ {
  index /PRESTASHOP_FOLDER/index.php;

  rewrite ^/PRESTASHOP_FOLDER/api/?(.*)$ /PRESTASHOP_FOLDER/webservice/dispatcher.php?url=$1 last;
  rewrite ^/PRESTASHOP_FOLDER/([0-9])(-[_a-zA-Z0-9-]*)?/(-[_a-zA-Z0-9-]*.0-9]+)?/.+\.jpg$ /PRESTASHOP_FOLDER/img/p/$1/$1$2.jpg last;
  rewrite ^/PRESTASHOP_FOLDER/([0-9])([0-9])(-[_a-zA-Z0-9-]*)?/(-[_a-zA-Z0-9-]*.0-9]+)?/.+\.jpg$ /PRESTASHOP_FOLDER/img/p/$1/$2/$1$2$3.jpg last;
  rewrite ^/PRESTASHOP_FOLDER/([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?/(-[_a-zA-Z0-9-]*.0-9]+)?/.+\.jpg$ /PRESTASHOP_FOLDER/img/p/$1/$2/$3/$1$2$3$4.jpg last;
  rewrite ^/PRESTASHOP_FOLDER/([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?/(-[_a-zA-Z0-9-]*.0-9]+)?/.+\.jpg$ /PRESTASHOP_FOLDER/img/p/$1/$2/$3/$4/$1$2$3$4$5.jpg last;
  rewrite ^/PRESTASHOP_FOLDER/([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?/(-[_a-zA-Z0-9-]*.0-9]+)?/.+\.jpg$ /PRESTASHOP_FOLDER/img/p/$1/$2/$3/$4/$5/$1$2$3$4$5$6.jpg last;
  rewrite ^/PRESTASHOP_FOLDER/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?/(-[_a-zA-Z0-9-]*.0-9]+)?/.+\.jpg$ /PRESTASHOP_FOLDER/img/p/$1/$2/$3/$4/$5/$6/$1$2$3$4$5$6$7.jpg last;
  rewrite ^/PRESTASHOP_FOLDER/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?/(-[_a-zA-Z0-9-]*.0-9]+)?/.+\.jpg$ /PRESTASHOP_FOLDER/img/p/$1/$2/$3/$4/$5/$6  /$7/$1$2$3$4$5$6$7$8.jpg last;
  rewrite ^/PRESTASHOP_FOLDER/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?/(-[_a-zA-Z0-9-]*.0-9]+)?/.+\.jpg$ /PRESTASHOP_FOLDER/img/p/$1/$2/$3/$4/$5/$6/$7/$8/$1$2$3$4$5$6$7$8$9.jpg last;
  rewrite ^/PRESTASHOP_FOLDER/c/([0-9]+)(-[_a-zA-Z0-9-]*)/(-[_a-zA-Z0-9-]*.0-9]+)?/.+\.jpg$ /PRESTASHOP_FOLDER/img/c/$1$2.jpg last;
  rewrite ^/PRESTASHOP_FOLDER/c/([a-zA-Z-]+)/(-[a0-zA-Z0-9-]+)?/.+\.jpg$ /PRESTASHOP_FOLDER/img/c/$1.jpg last;
  rewrite ^/PRESTASHOP_FOLDER/([0-9]+)(-[_a-zA-Z0-9-]*)/(-[_a-zA-Z0-9-]*.0-9]+)?/.+\.jpg$ /PRESTASHOP_FOLDER/img/c/$1$2.jpg last;
  try_files $uri $uri/ /PRESTASHOP_FOLDER/index.php?$args;
}

...

Code Block
location / {
  index /index.php;

  rewrite ^/api/?(.*)$ /webservice/dispatcher.php?url=$1 last;
  rewrite ^/([0-9])(-[_a-zA-Z0-9-]*)?/(-[_a-zA-Z0-9-]*.0-9]+)?/.+\.jpg$ /img/p/$1/$1$2.jpg last;
  rewrite ^/([0-9])([0-9])(-[_a-zA-Z0-9-]*)?/(-[_a-zA-Z0-9-]*.0-9]+)?/.+\.jpg$ /img/p/$1/$2/$1$2$3.jpg last;
  rewrite ^/([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?/(-[_a-zA-Z0-9-]*.0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$1$2$3$4.jpg last;
  rewrite ^/([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?/(-[_a-zA-Z0-9-]*.0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$1$2$3$4$5.jpg last;
  rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?/(-[_a-zA-Z0-9-]*.0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$1$2$3$4$5$6.jpg last;
  rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?/(-[_a-zA-Z0-9-]*.0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$1$2$3$4$5$6$7.jpg last;
  rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?/(-[_a-zA-Z0-9-]*.0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$7/$1$2$3$4$5$6$7$8.jpg last;
  rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?/(-[_a-zA-Z0-9-]*.0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$7/$8/$1$2$3$4$5$6$7$8$9.jpg last;
  rewrite ^/c/([0-9]+)(-[_a-zA-Z0-9-]*)/(-[_a-zA-Z0-9-]*.0-9]+)?/.+\.jpg$ /img/c/$1$2.jpg last;
  rewrite ^/c/([a-zA-Z-]+)/(-[a0-zA-Z0-9-]+)?/.+\.jpg$ /img/c/$1.jpg last;
  rewrite ^/([0-9]+)(-[_a-zA-Z0-9-]*)/(-[_a-zA-Z0-9-]*.0-9]+)?/.+\.jpg$ /img/c/$1$2.jpg last;
  try_files $uri $uri/ /index.php?$args;
}

...

Code Block
location /PRESTASHOP_FOLDER/high-tech/ {
  rewrite ^/PRESTASHOP_FOLDER/high-tech/(.*)$ /PRESTASHOP_FOLDER/$1 last;
  try_files $uri $uri/ /PRESTASHOP_FOLDER/index.php?$args;
}

Complete example configuration for nginx:

Code Block
server {
    listen 80;
    #listen [::]:80;            # Uncomment this line if you also want to enable IPv6 support
    server_name example.com www.example.com;
    root /var/www/example;
    access_log /var/log/nginx/example.access.log;
    error_log /var/log/nginx/example.error.log;

    index index.php index.html; # Letting nginx know which files to try when requesting a folder


    location = /favicon.ico {
        log_not_found off;      # PrestaShop by default does not provide a favicon.ico
        access_log off;         # Disable logging to prevent excessive log sizes
    }


     location = /robots.txt {
         auth_basic off;        # Whatever happens, always let bots know about your policy
         allow all;
         log_not_found off;     # Prevent excessive log size
         access_log off;
    }

    # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }

    ##
	# Gzip Settings
	##

	gzip on;
	gzip_disable "msie6";                                             # Do people still use Internet Explorer 6? In that case, disable gzip and hope for the best!
	gzip_vary on;                                                     # Also compress content with other MIME types than "text/html"
    gzip_types application/json text/css application/javascript;      # We only want to compress json, css and js. Compressing images and such isn't worth it
	gzip_proxied any;
	gzip_comp_level 6;                                                # Set desired compression ratio, higher is better compression, but slower
	gzip_buffers 16 8k;                                               # Gzip buffer size
    gzip_http_version 1.0;                                            # Compress every type of HTTP request
	
    rewrite ^/api/?(.*)$ /webservice/dispatcher.php?url=$1 last;
    rewrite ^/([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$1$2.jpg last;
    rewrite ^/([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$1$2$3.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$1$2$3$4.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$1$2$3$4$5.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$1$2$3$4$5$6.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$1$2$3$4$5$6$7.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$7/$1$2$3$4$5$6$7$8.jpg last;
    rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$7/$8/$1$2$3$4$5$6$7$8$9.jpg last;
    rewrite ^/c/([0-9]+)(-[_a-zA-Z0-9-]*)(-[0-9]+)?/.+\.jpg$ /img/c/$1$2.jpg last;
    rewrite ^/c/([a-zA-Z-]+)(-[0-9]+)?/.+\.jpg$ /img/c/$1.jpg last;
    rewrite ^/([0-9]+)(-[_a-zA-Z0-9-]*)(-[0-9]+)?/.+\.jpg$ /img/c/$1$2.jpg last;
    try_files $uri $uri/ /index.php?$args;

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_keep_conn on;
        include /etc/nginx/fastcgi_params;
	    fastcgi_pass 127.0.0.1:9000;                    # When using TCP
        #fastcgi_pass unix:/var/run/php/php-fpm.sock;   # When using unix sockets 
    }
}

Miscellaneous

The PrestaShop file structure

...

  1. Put your shop in maintenance mode, so as to not lose new customers or orders while moving the data.
    Go to your back - office, and under the "Preference" menu, open the "Maintenance" page and set the "Enable shop" option to "No".
  2. Move your files:
    1. Make a backup of all the files: connect to your FTP server, and copy all the files and folders to your local hard-drive.
    2. Transfer your files to your new host: Connect to the FTP server for your new host, and copy all the files and folders that you just downloaded to your local hard-drive, as is.
  3. Move your data:
    1. Make a backup of you database (a "dump"): connect to phpMyAdmin, click on the "Export" tab, select the database of your PrestaShop installation, and click the "Go" button. Save the downloaded file on your hard-drive. If phpMyAdmin times out before it is able to export all your data, contact your host.
    2. Transfer the SQL dump to the new database: connect to the new server's phpMyAdmin, click on the "Import" tab, click the "Browse..." button, find the SQL file you just downloaded, and click the "Go" button to upload it. If phpMyAdmin times out before it is able to import all your data, contact your new host.
  4. Configure your shop:
    1. On the new server, open the /config/settings.inc.phpfile and update the settings for the new database server (with your own settings instead of the examples here):
      • define('_DB_SERVER_', 'sql.domainname.com');
      • define('_DB_NAME_', 'prestashop');
      • define('_DB_USER_', 'PS-user');
      • define('_DB_PASSWD_', 'djsf15');
      • define('_DB_PREFIX_', 'ps_');
    2. Log in to your back - office, go to the "Preferences" menu, select the "SEO & URLs" page, and in the "Set shop URL" section change the domain name to your new domain. Do the same for the SSL domain.
      In effect, this will update the "ps_shop_url" SQL table (as well as the "PS_SHOP_DOMAIN" and "PS_SHOP_DOMAIN_SSL" rows in the "ps_configuration" SQL table, for retrocompatibility reasons).
  5. Connect to your new FTP server and delete everything except the index.phpfiles in the following folders:
    • /cache/smarty/cache
    • /cache/smarty/compile
  6. Go to your back - office, and in the "Maintenance" preference page, set the "Enable shop" option back to "Yes".

...

  1. Put your shop in maintenance mode, so as to not lose new customers or orders will moving the data.
    Go to your back-office, and under the "Preference" menu, open the "Maintenance" page and set the "Enable shop" option to "No".
  2. Move your files
    1. Make a backup of all the files: connect to your FTP server, and copy all the files and folders to your local hard-drive.
    2. Transfer your files to your new host: Connect to the FTP server for your new host, and copy all the files and folders that you just downloaded to your local hard-drive, as is.
  3. Configuration
    1. On the new server, open the /config/settings.inc.php file and update the settings for the new database server (with your own settings instead of the examples here):
      • define('_DB_SERVER_', 'sql.domainname.com');
      • define('_DB_NAME_', 'prestashop');
      • define('_DB_USER_', 'PS-user');
      • define('_DB_PASSWD_', 'djsf15');
      • define('_DB_PREFIX_', 'ps_');
    2. Log in to your back - office, go to the "Preferences" menu, select the "SEO & URLs" page, and in the "Set shop URL" section change the domain name to your new domain. Do the same for the SSL domain.
      In effect, this will update the "PS_SHOP_DOMAIN" and "PS_SHOP_DOMAIN_SSL" rows in the "ps_configuration" SQL table.
  4. Connect to your new FTP server and delete everything except the index.phpfiles in the following folders:
    • /tools/smarty/cache
    • /tools/smarty/compile
    • /tools/smarty_v2/cache
    • /tools/smarty_v2/compile
  5. Go to your back - office, and in the "Maintenance" preference page, set the "Enable shop" option back to "Yes".

...