User Tools

Site Tools


opencart:start

OpenCart

Security

Essential steps to do after installation

  1. Immediately delete the /install/ directory
  2. chmod the config.php file in both the root and /admin/ directories to 444

Securing directories

You can use .htaccess in root directory. Example:

ErrorDocument 403 http://<your-domain>/404.shtml
Options +FollowSymlinks
Options -Indexes
<FilesMatch "\.(tpl|ini|log|pdf)">
Order Deny,Allow
Deny from all
</FilesMatch>

Hardening the security of /system/ directory

Certain files are wide-open by default. If you have installed OpenCart in your root directory, just go to http://www.yourdomain.com/system/logs/error.log and you should be able to download your error log, even if you’re a public user. You should protect these files, so create a .htaccess with the following code:

<Files *.*>
Order Deny,Allow
Deny from all
</Files>

Then put that .htaccess file in the following 2 directories:

  • /system/
  • /system/logs/

Order Deny,Allow Deny from all

Hardening the security of /catalog/ directory

This folder contains your images, Javascript files, and template files. Anything other than that should not be served, but that’s not the case. Just look at http://www.yourdomain.com/catalog/controller/account/address.php. You can see that the file is still being attempted to run, which poses a security risk. Either a malicious user can get more clues about your system from these error codes, or if the malicious user can find a way to upload his own malicious PHP file, then your whole system could be at jeopardy.

The solution is to put a .htaccess file in the /catalog/ folder with the following code:

Options +FollowSymlinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !^(.+)\.jpg$
RewriteCond %{REQUEST_FILENAME} !^(.+)\.jpeg$
RewriteCond %{REQUEST_FILENAME} !^(.+)\.png$
RewriteCond %{REQUEST_FILENAME} !^(.+)\.gif$
RewriteCond %{REQUEST_FILENAME} !^(.+)\.css$
RewriteCond %{REQUEST_FILENAME} !^(.+)\.js$
RewriteRule ^(.+)$ /404.html [NC] 

This way, anything other than the allowed file types of jpg, jpeg, png, gif, css, and js are blocked. So whenever someone or something accesses any prohibited file types (such as PHP), they’ll be redirected to the 404.html file that you created in the first step of this tutorial.

Hardening the security of /image/ directory

As above, the /image/ folder requires protection as well, and you need a similar .htaccess file to achieve this. Create another .htaccess file in your /image/ folder with this code:

Options +FollowSymlinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !^(.+)\.jpg$
RewriteCond %{REQUEST_FILENAME} !^(.+)\.jpeg$
RewriteCond %{REQUEST_FILENAME} !^(.+)\.png$
RewriteCond %{REQUEST_FILENAME} !^(.+)\.gif$
RewriteRule ^(.+)$ /404.html [NC] 

Note: If you use other file types in your /catalog/ or /image/ directories such as .swf or .flv, then you have to add another RewriteCond line to the .htaccess for that specific file extension.

301 redirection

Redirect your domain.com to www.domain.com. Read how to redirect a webpage.

Add code to .htaccess file:

RewriteCond %{HTTP_HOST} ^domain.com$ [NC]
RewriteRule ^(.*) http://www.domain.com/$1 [R=301,L]

Create rewrite rules for sitemap.xml and googlebase.xml

Add code to .htaccess file:

RewriteRule ^sitemap.xml$ index.php?route=feed/google_sitemap [L]
RewriteRule ^googlebase.xml$ index.php?route=feed/google_base [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css)
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]

Note: The rewrite rule must be declared after 301 redirection.

Create robots.txt file

Create robots.txt file and copy it to the root directory:

User-agent: *
Disallow: /download/
Disallow: /js/
Disallow: /pdf/

Change your encryption key

Changing the encryption key will help increase security for your store as a whole. By default the encryption key for processing orders is set to 12345. To change it to a unique series, in Admin go to System → Settings and click Edit for your store. Encryption Key can be found under the Server tab.

Disable Display Errors

By default OpenCart displays errors on pages. While useful for debugging purposes it gives hackers a useful tool in attacking your website and looks just plain ugly for regular customers. To disable it go to System → Settings and click Edit for your store. Under the Server tab select No for Display Errors. Don't worry. As long as you keep Log Errors on the same page as Yes you'll be able to access those errors by going to System → Error Logs in Admin.

Remove "Powered By OpenCart"

The Powered By OpenCart footer that appears on every store page is a great way to promote the best ecommerce platform around but has the downside of making websites that run on OpenCart very easy to track down and target.

To remove it go to /catalog/view/theme/[default]/template/common/footer.tpl and remove or change:

<div id="powered"><?php echo $powered; ?></div>

.htaccess file example

Example of .htaccess file:

ErrorDocument 404 http://<domain-name>/404.shtml

Options +FollowSymlinks
Options -Indexes

RewriteCond %{HTTP_HOST} ^<domain-name>$ [NC]
RewriteRule ^(.*) http://<www-domain-name>/$1 [R=301,L]

RewriteRule ^sitemap.xml$ index.php?route=feed/google_sitemap [L]
RewriteRule ^googlebase.xml$ index.php?route=feed/google_base [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css)
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]

<FilesMatch "\.(tpl|ini|log|pdf)">
Order Deny,Allow
Deny from all
</FilesMatch>

<IfModule mod_deflate.c>
<FilesMatch "\.(js|css)$">
SetOutputFilter DEFLATE
</FilesMatch>
</IfModule>

# Turn on Expires and set default to 0
ExpiresActive On
ExpiresDefault A0

# Set up caching on media files for 5 weeks
<FilesMatch "\.(flv|ico|pdf|avi|mov|ppt|doc|mp3|wmv|wav)$">
ExpiresDefault A3024000
Header append Cache-Control "public"
</FilesMatch>

# Set up caching on media files for 3 weeks
<FilesMatch "\.(gif|jpg|jpeg|png|swf)$">
ExpiresDefault A1814400
Header append Cache-Control "public"
</FilesMatch>

# Set up caching on rarely modified files for 3 weeks
<FilesMatch "\.(js|css)$">
ExpiresDefault A1814400
Header append Cache-Control "public"
</FilesMatch>

# Set up 1 day caching on commonly updated files
<FilesMatch "\.(xml|txt|html|shtml)$">
ExpiresDefault A86400
Header append Cache-Control "proxy-revalidate"
</FilesMatch>

# Force no caching for dynamic files
<FilesMatch "\.(php|cgi|pl|htm)$">
ExpiresActive Off
Header set Cache-Control "private, no-cache, no-store, proxy-revalidate, no-transform"
Header set Pragma "no-cache"
</FilesMatch>

Tricks

Slow down slideshow

In file: catalog/view/theme/default/template/module/slideshow.tpl:

find

$('#slideshow<?php echo $module; ?>').nivoSlider();

and change to:

$('#slideshow<?php echo $module; ?>').nivoSlider({pauseTime:8000});

Step 1

Modify /catalog/view/theme/default/template/common/header.tpl file.
Add new <div> section, right after <?php if ($logo) and before <?php echo $language; ?>

[...]
 
<div id="header">
  <?php if ($logo) { ?>
  <div id="logo"><a href="<?php echo $home; ?>"><img src="<?php echo $logo; ?>" title="<?php echo $name; ?>" alt="<?php echo $name; ?>" /></a></div>
  <?php } ?>
 
  <div id="fb-like"><a href="http://www.facebook.com/<facebook-name>" target="_blank"><img src="http://<link-to-facebook-graphics.png" alt="facebook.com/<facebook-name>" /></a></div>  
 
  <?php echo $language; ?>
 
[...]
</div>
[...]

Step 2

Modify /catalog/view/theme/default/stylesheet/stylesheet.css file.
Add new id:

#header #fb-like {
	position: absolute;
	top: 52px;
	left: 420px;
}

You can position your graphics by manipulating top and left values according to your needs.a href=

Fixes

Cannot send e-mails

Modify file: admin/view/template/sale/contact.tpl. At line 244 you need to replace:

$('textarea[name=\'message\']').html($('textarea[name=\'message\']').val());

with:

$('textarea[name=\'message\']').html(CKEDITOR.instances.message.getData());

Reset Order and Invoice IDs

TRUNCATE `oc_order`;
TRUNCATE `oc_order_download`;
TRUNCATE `oc_order_history`;
TRUNCATE `oc_order_option`;
TRUNCATE `oc_order_product`;
TRUNCATE `oc_order_total`;

Speed up the currency update frequency

Currencies are updated based on 1 of 2 conditions.

  1. When you add a new currency, they all get updated immediately
  2. When you load your admin dashboard, they all get updated, but only once every 24 hours.

You can easily force it to happen everytime you load your admin dashboard by changing this:

EDIT: admin/controller/common/home.php

FIND:

  $this->model_localisation_currency->updateCurrencies();

REPLACE WITH:

  $this->model_localisation_currency->updateCurrencies(true);

But the problem is that the updatecurrency system in general only works if you login to the admin. If you don't check your admin for days at a time, then the currencies won't update. So this should really be moved to the catalog side and have it auto-update once every X hours when someone loads the homepage or something. This can be done by doing the following:

EDIT: catalog/controller/common/header.php

FIND:

Code: Select all
    class ControllerCommonHeader extends Controller {

ADD AFTER:

  public function updateCurrencies($force = false) {
    if (extension_loaded('curl')) {
      $data = array();
             
      if ($force) {
        $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "currency WHERE code != '" . $this->db->escape($this->config->get('config_currency')) . "'");
      } else {
        $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "currency WHERE code != '" . $this->db->escape($this->config->get('config_currency')) . "' AND date_modified < '" .  $this->db->escape(date('Y-m-d H:i:s', strtotime('-1 day'))) . "'");
      }
             
      foreach ($query->rows as $result) {
        $data[] = $this->config->get('config_currency') . $result['code'] . '=X';
      }   
             
      $curl = curl_init();
             
      curl_setopt($curl, CURLOPT_URL, 'http://download.finance.yahoo.com/d/quotes.csv?s=' . implode(',', $data) . '&f=sl1&e=.csv');
      curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
             
      $content = curl_exec($curl);
             
      curl_close($curl);
            
      $lines = explode("\n", trim($content));
                
      foreach ($lines as $line) {
        $currency = utf8_substr($line, 4, 3);
        $value = utf8_substr($line, 11, 6);
                
        if ((float)$value) {
          $this->db->query("UPDATE " . DB_PREFIX . "currency SET value = '" . (float)$value . "', date_modified = '" .  $this->db->escape(date('Y-m-d H:i:s')) . "' WHERE code = '" . $this->db->escape($currency) . "'");
        }
      }
             
      $this->db->query("UPDATE " . DB_PREFIX . "currency SET value = '1.00000', date_modified = '" .  $this->db->escape(date('Y-m-d H:i:s')) . "' WHERE code = '" . $this->db->escape($this->config->get('config_currency')) . "'");
             
      $this->cache->delete('currency');
    }
  }	

THEN FIND:

protected function index() {

ADD AFTER:

    $this->updateCurrencies();

:!: Note: If you need to speed up process, change the “-1 day” part to something more often like “-3 hour”. Not too often, though.

opencart/start.txt · Last modified: 2014/06/28 02:49 (external edit)