Post by daveybrown » Fri Aug 21, 2015 4:48 pm

I usually rename the admin folder of Opencart installations for security reasons. By doing this it means that anyone trying to log into your admin area must:
  1. Know that you’ve employed this tactic and,
  2. Know or figure out your, potentially long and obscure, admin folder name.
In my opinion this is a really good approach to improving security, I’ve read this suggestion on many forum posts so thank you to those who have shared this information. This solution isn’t always ideal, for example when installing modules you must remember to copy any applicable files to your renamed folder not ‘admin’.

Edit: This has only been tested in OC 2.0.3.1 (and is known not to work in OC 1.5.x)

I've thought of the following way around the shortcomings of renaming the admin folder, while still offering the same level of security (please correct me if I'm wrong, and feel free to suggest improvements). This is a learning exercise for me so please feel free to discuss it. I’ll explain the idea then paste the code.
  • Login by visiting yourstore.com/admin-login.php (rename to something obscure)
  • This starts a php session with a login token
  • Redirects you to the admin login with the login token as a query string at yourstore.com/admin?logintoken=…
  • Login attempts will only validate if the token stored in the session matches the query string (as well as user name and password match)
Contents of admin-login.php

Code: Select all

<?php

// Define admin folder, include trailing slash
define('ADMIN_FOLDER', 'admin/');

// Genreate random string for session login token
$logintoken = substr(str_shuffle(MD5(microtime())), 0, 32); 

// Save session token
session_start();
$_SESSION['logintoken'] = $logintoken;

// Concatenate login url
$loginurl = ADMIN_FOLDER . '?logintoken=' . $logintoken;

?>

<script type="text/javascript">
<!--// Go to admin login url with login token as query string 
window.location = "<?php echo $loginurl; ?>"
//-->
</script>

<noscript>
	<a href="<?php echo $loginurl; ?>">Admin login</a>
</noscript>
admin/controller/common/login.php

add the following

Code: Select all

elseif (!(isset($_GET['logintoken'])) || !(isset($this->session->data['logintoken'])) || ($_GET['logintoken'] !== $this->session->data['logintoken'])) {
	$this->error['warning'] = $this->language->get('error_login');
} else {
	unset($_SESSION['logintoken']);
}
after

Code: Select all

protected function validate() {	
if (!isset($this->request->post['username']) || !isset($this->request->post['password']) || !$this->user->login($this->request->post['username'], $this->request->post['password'])) {
	$this->error['warning'] = $this->language->get('error_login');
}
or this for 1.5.x

Code: Select all

protected function validate() {
if (isset($this->request->post['username']) && isset($this->request->post['password']) && !$this->user->login($this->request->post['username'], $this->request->post['password'])) {
	$this->error['warning'] = $this->language->get('error_login');
}
Similarly to before we now have a setup where; anyone trying to log into your admin area must:
  1. Know that you’ve employed this tactic and,
  2. Know or figure out your, potentially long and obscure, admin login file name.
...but, without the minor inconveniences of a renamed admin folder.

Davey
Last edited by daveybrown on Sun Aug 23, 2015 5:13 pm, edited 2 times in total.

Newbie

Posts

Joined
Thu Aug 20, 2015 6:39 pm

Post by IP_CAM » Sat Aug 22, 2015 1:09 am

tried it unsuccessfully on my OC v.1.5.6.5_rc, by adding it as shown below.
it refuses to accept the DEMO-ADMIN USER user/password as well as my personal Admin Access Data.
Ernie

Code: Select all

	protected function validate() {
		if (!isset($this->request->post['username']) || !isset($this->request->post['password']) || !$this->user->login($this->request->post['username'], $this->request->post['password'])) {
			$this->error['warning'] = $this->language->get('error_login');
		}
    elseif (!(isset($_GET['logintoken'])) || !(isset($this->session->data['logintoken'])) || ($_GET['logintoken'] !== $this->session->data['logintoken'])) {
       $this->error['warning'] = $this->language->get('error_login');
    } else {
       unset($_SESSION['logintoken']);
    }


		if (!$this->error) {
			return true;
		} else {
			return false;
		}
Last edited by IP_CAM on Sat Aug 22, 2015 11:43 pm, edited 2 times in total.

I don't use Forum Mail, to reach me, contact: jti@jacob.ch
-
Server Q & A Basic Information on Code + Settings
http://www.everyauction.info/serverinfo.html
Demoversion OpenCart LIGHT v.1.5.6.5
http://www.jti.li/shop/
1'400+ FREE OC Extensions - from OC v.1.5.x up,
on the world's largest OC-related Github Site: https://github.com/IP-CAM
-
Image


User avatar
Legendary Member

Posts

Joined
Tue Mar 04, 2014 1:37 am
Location - Switzerland

Post by daveybrown » Sat Aug 22, 2015 3:59 am

You're right, it's not working with 1.5. for some reason. I'll look into it. For now though this is working with Opencart 2 :)

Newbie

Posts

Joined
Thu Aug 20, 2015 6:39 pm

Post by straightlight » Fri Aug 28, 2015 7:48 am

Simple reason. 1.5x release.

In system/library/user.php file,

find:

Code: Select all

public function login($username) {
replace with:

Code: Select all

public function login($username, $password) {
Right below, replace:

Code: Select all

$user_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "user WHERE username = '" . $this->db->escape($username) . "' AND status = '1'");
with:

Code: Select all

$user_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "user WHERE username = '" . $this->db->escape($username) . "' AND (password = SHA1(CONCAT(salt, SHA1(CONCAT(salt, SHA1('" . $this->db->escape($password) . "'))))) OR password = '" . $this->db->escape(md5($password)) . "') AND status = '1'");
Then, you can test the modifications above posted on the first topic. Despite of what people may believe regarding OC v1.5x vs OC v2.0x releases, 1.5x releases sure fails a secured validation process for the administration. I would rather know that a password algorithm tests the password authentication to be able to access my console than nothing at all. Tested with v1.5.6.4.

The most generated errors being found on Opencart forum originates from contributed programming. The increased post counters are caused by redundancies of the same solutions that were already provided prior.


Regards,
Straightlight
Opencart.com Administrator / Quality Assurance Analyst / Programmer


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by IP_CAM » Fri Aug 28, 2015 10:51 am

/ Optimized by villagedefrance
/ contact@villagedefrance.net
/ public function login($username, $password)
/ plus the new query

@straightlight :
I already have this setup on my test version, but it still did not work.
Ernie

I don't use Forum Mail, to reach me, contact: jti@jacob.ch
-
Server Q & A Basic Information on Code + Settings
http://www.everyauction.info/serverinfo.html
Demoversion OpenCart LIGHT v.1.5.6.5
http://www.jti.li/shop/
1'400+ FREE OC Extensions - from OC v.1.5.x up,
on the world's largest OC-related Github Site: https://github.com/IP-CAM
-
Image


User avatar
Legendary Member

Posts

Joined
Tue Mar 04, 2014 1:37 am
Location - Switzerland

Post by straightlight » Fri Aug 28, 2015 10:55 am

IP_CAM wrote:/ Optimized by villagedefrance
/ contact@villagedefrance.net
/ public function login($username, $password)
/ plus the new query

@straightlight :
I already have this setup on my test version, but it still did not work.
Ernie
I'm sure you understand that did not work does not really explain in details what might be the source of the problem. Would it be possible to clarify what you notice after trying this code?

The most generated errors being found on Opencart forum originates from contributed programming. The increased post counters are caused by redundancies of the same solutions that were already provided prior.


Regards,
Straightlight
Opencart.com Administrator / Quality Assurance Analyst / Programmer


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by IP_CAM » Fri Aug 28, 2015 11:04 am

sorry, in Villagedefrance's 1.5x release, in the system/library/user.php file, I am using, in my v1.5.6.5 TestShops,
your 'advised' modifications are and have been part of, already, when testing the Modification.
That's, what I meant.
Ernie
Last edited by IP_CAM on Fri Aug 28, 2015 11:04 am, edited 1 time in total.

I don't use Forum Mail, to reach me, contact: jti@jacob.ch
-
Server Q & A Basic Information on Code + Settings
http://www.everyauction.info/serverinfo.html
Demoversion OpenCart LIGHT v.1.5.6.5
http://www.jti.li/shop/
1'400+ FREE OC Extensions - from OC v.1.5.x up,
on the world's largest OC-related Github Site: https://github.com/IP-CAM
-
Image


User avatar
Legendary Member

Posts

Joined
Tue Mar 04, 2014 1:37 am
Location - Switzerland

Post by straightlight » Fri Aug 28, 2015 11:04 am

An additional note I would like to indicate is that there are no indication of the initialization of the $this->session->data['logintoken'] anywhere in the code but simply validates and unsets; according to the IF statement. There is a separated file that shows the initialization but not amongst the Opencart's engine which is not entirely recommended since the object is being initiated from local API but does not get re-validated whether it's simply or not.

This is the statement I modified:

Code: Select all

protected function validate() {   
	if (!isset($this->request->post['username']) || !isset($this->request->post['password']) || !$this->user->login($this->request->post['username'], $this->request->post['password'])) {
		$this->error['warning'] = $this->language->get('error_login');
	} elseif (!empty($this->session->data['logintoken']) && !empty($this->request->get['logintoken']) && $this->request->get['logintoken'] != $this->session->data['logintoken']) {
		$this->error['warning'] = $this->language->get('error_login');
	} else {
		unset($this->session->data['logintoken']);
	}
}
Another note is that the local API file uses a GET statement while the opencart login form uses a POST method. It is not possible to use multiple form methods while one is already using a POST statement and the local API file to use a GET method. Otherwise, if both statements gets encountered, both will be confused since the else condition ends by unsetting a superglobals variable that originates from a GET method.

The most generated errors being found on Opencart forum originates from contributed programming. The increased post counters are caused by redundancies of the same solutions that were already provided prior.


Regards,
Straightlight
Opencart.com Administrator / Quality Assurance Analyst / Programmer


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON
Who is online

Users browsing this forum: Google [Bot] and 4 guests