Solved

How to secure a form's login ID and password

Posted on 2014-01-18
18
375 Views
Last Modified: 2014-06-30
We had made a form (using php and mysql) which is a content management page for handling events of our company. Whenever there is a new event, an authorized user are able to login to the page to upload jpg and write some wording.

The problem is this form had been injected by hackers several times. Even my friend showed me they are using a software to scan through the page he is able to detect the login username And password.

I heard there is a way to encrypt the username password. Please guide me how to protect the username and password for being expose to the outsider.
0
Comment
Question by:swpui
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 4
  • 3
  • +3
18 Comments
 
LVL 58

Expert Comment

by:Gary
ID: 39791615
It's not possible to find out the username/password unless you are actually placing it in the code so it is viewable in the browser.
0
 

Author Comment

by:swpui
ID: 39791744
Yes we did place in the php code. Abny recommendation?
0
 
LVL 4

Expert Comment

by:ravikantninave
ID: 39791814
Store UserName and Password in DB and check from it.
Should I post some code?
0
Get Database Help Now w/ Support & Database Audit

Keeping your database environment tuned, optimized and high-performance is key to achieving business goals. If your database goes down, so does your business. Percona experts have a long history of helping enterprises ensure their databases are running smoothly.

 
LVL 31

Accepted Solution

by:
Marco Gasi earned 500 total points
ID: 39791903
You have to store password in your database. You can create a nd5 hash for the pasword and store the hash in the databse and then compare two hashes instead of two clear strings. Once your md5 password is in your database you can do something like this:

<?php
if (isset($_POST('login')))
{
	$uname = $_POST['username'];
	$password = $_POST['pwd'];
	$stored_password = "";
	// Here place some validation/sanitization code: check if password have the required length
	// if it have required characters type and so on. Then
	// create a md5 hash for the submitted password in order to compare with stored password
	$password = md5($password);
	$sql = "SELECT password FROM users WHERE username='$username'";
	$result = mysqli_query($conn, $sql);
	$row = mysqli_fetch_row($result);
	if (mysqli_error())
	{
		echo "Error message: " . mysqli_error();
		exit;
	}
	$stored_password = $row['password'];
	if ($password == $stored_password)
	{
		// login success
	} else
	{
		// login failed
	}
}
?>
<form action="#" method="post">
<input type="text" name="username" />
<input type="password" name="pwd" />
<input type="submit" name="login" value="Login" />
</form>

Open in new window

0
 
LVL 110

Expert Comment

by:Ray Paseur
ID: 39792058
You probably want to use PHP client authentication, at a minimum.  
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_2391-PHP-login-logout-and-easy-access-control.html

And if you still think you're not sufficiently secure from 'bots, add a CAPTCHA test.
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_9849-Making-CAPTCHA-Friendlier-with-PHP-Image-Manipulation.html

If you're new to computer science in general, or to PHP, this article will point you in the direction of some good learning resources and more importantly, will steer you away from the many bad examples that litter the internet!
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_11769-And-by-the-way-I-am-new-to-PHP.html
0
 

Author Comment

by:swpui
ID: 39793178
ravikantninave, yes please provide codes if you have for my reference.
0
 
LVL 31

Expert Comment

by:Marco Gasi
ID: 39793396
@swpui Did you see the code I have posted here?
It shows how to manage passwords as you request.
0
 

Author Comment

by:swpui
ID: 39793493
Marco, I had seen your code. Let's say after I rectify the code, is there any software that I can use to scan and double check whether our website still vulnerable!?
0
 
LVL 31

Expert Comment

by:Marco Gasi
ID: 39793528
There are several. I post here some link but yoiu can find more googling a bit:

http://www.acunetix.com/websitesecurity/web-security/ (commercial)
http://ironwasp.org/download.html (free)

You can also check this site: http://sectools.org/tag/web-scanners/

Hope this helps.
0
 
LVL 110

Expert Comment

by:Ray Paseur
ID: 39794310
... is there any software that I can use to scan and double check whether our website still vulnerable!?
Information Systems Security is a full-time four year college major at the University of Maryland, and its graduates are in demand and very, very highly paid, often commanding six-figure salaries immediately upon graduation.  So it follows that any useful answer to the question you have here is an answer with many layers of deep background knowledge.

Suggest you join OWASP and get involved.  You can get some superficial guidance from an online forum, but you need to be aware that the attacks are always changing and it is nearly impossible to be ahead of all of them.  OWASP will help you avoid today's known issues.

As an example of the unknown (and therefore more dangerous) issues, I would cite Target Stores on Thanksgiving day, 2013.  They did not know that there was any vulnerability.
0
 
LVL 34

Expert Comment

by:Slick812
ID: 39795154
greetings swpui, , you have not shown any code for us to get some minimum idea of what you may mean by -
"form had been injected by hackers several times"
There are thousands of different ways to do what is called "Hack" a web site! !
You absolutely need to PREVENT SQL database injection from all FORM user inputs to the SQL SELECT or INSERT text.
Next you need to be sure there is no information sent to your web page or cookies that give any hint about the user-name, password, or database columns names.
You need to prevent XSS javascript injection into the "Events page" from the  form inputs. .
Please remember that almost ALL HACKS are done from a web server host, , and not from someone using a web browser on a personal computer.
If you want better help on this you might consider at least posting your html for the FORM, and any PHP code that would relate to that FORM input processing. But this is a very old and continuing problem in server programming, and has been covered many times in web articles like this in the PHP manual -
http://www.php.net/manual/en/security.database.sql-injection.php
0
 

Author Comment

by:swpui
ID: 39796100
slick812 here are the codes. pls guide me. Thanks.
adminLoginCheck.php
news-details.php
connectDB.php
0
 

Author Comment

by:swpui
ID: 39796163
This is what I get after using the scanner. If the password had been encrypted, they still manage to see the database, only the password was not reveal. How to totally block them to go into the database!?
Havij.jpg
mysql-password-hash.png
0
 
LVL 31

Expert Comment

by:Marco Gasi
ID: 39796234
if your server is Apache you ask your service provider to modify httpd.conf inserting these lines:

SetEnv DBUNAME, "yourusername"
SetEnv DBPWD, "strongpassword"

So in your site you'll use these constants to access your database. Obviously you can use less significant names :)
0
 
LVL 34

Expert Comment

by:Slick812
ID: 39797968
I looked at your additions in the code -
adminLoginCheck.php
news-details.php
connectDB.php

and the images -
Havij.jpg
mysql-password-hash.png

and maybe it's me, but I could NOT FIND any code for <form > where they enter text and upload jpg for your "events" listings page.

 now in the  adminLoginCheck.php  you have the essential injection SQL escape there as -
$admin_username = mysql_escape_string($admin_username);
$admin_password = mysql_escape_string($admin_password);

however I do NOT see any php code there to "HASH" the password such as -

$admin_password=$_POST['admin_password'];
$admin_password = hash_hmac('sha256', $admin_password, 'y$frB(l9#v!vGb8_k6VD-5GlqVy*jg5+');
$sql="SELECT admin_password FROM admin WHERE admin_username='$admin_username' ";
// do a  query and mysql_fetch_assoc($result)  here
 if ($row['admin_password'] == $admin_password) { The Hashed passwords MATCH, success login

the above code is NOT COMPLETE and only a possible example! !
I looked at your  mysql-password-hash.png , but I do not see HOW or WHY in any code you show this has meaning or what this image is about, sorry for my ignorance.

 HOWEVER this administrator "LOG IN" has little to do with your original QUESTION of -
"this events form had been injected by hackers several times",
but maybe I am concerned with your EVENTS PAGE?

I do not care about the connectDB.php  code, as this only connects to your MySQL database and is not a concern for this question, but I will tell you that the OLD mysql_connect( ) function is VERY VERY OUT OF DATE! ! You really should be using the new  mysqli_connect( ) function! !

as to the  Havij.jpg image , this is about the  news-details.php which has only ONE  mysql_query( ) , , which I have to guess that this news database Table has some admin_password column and is somehow used on this page? ? but I can NOT see anything about this page that has any "password" on it ? ? the Havij says that it found the admin database Table, which is NOT shown in the news-details.php  page as far as I can see, however according to your  adminLoginCheck.php  page the admin Table does have the  admin_password  column, But this should be HASHED, It is absolutely necessary to NOT have plain text passwords in a Table column!

But again, I am trying to do your original question about the injection to your events page, can you show the html for your <form> in the events addition page?
0
 

Author Comment

by:swpui
ID: 39887678
<?php
      $page = "news";
      $subPage = "";
      $flag = array_key_exists('flag', $_REQUEST) ? $_REQUEST['flag'] : false;
      $action = array_key_exists('action', $_REQUEST) ? $_REQUEST['action'] : false;      
      
      if ($action == "add") {
            $news_date_day = array_key_exists('news_date_day', $_REQUEST) ? $_REQUEST['news_date_day'] : false;
            $news_date_month = array_key_exists('news_date_month', $_REQUEST) ? $_REQUEST['news_date_month'] : false;
            $news_date_year = array_key_exists('news_date_year', $_REQUEST) ? $_REQUEST['news_date_year'] : false;      
            $news_subject_eng = array_key_exists('news_subject_eng', $_REQUEST) ? $_REQUEST['news_subject_eng'] : false;
            $news_subject_bm = array_key_exists('news_subject_bm', $_REQUEST) ? $_REQUEST['news_subject_bm'] : false;
            $news_subject_cn = array_key_exists('news_subject_cn', $_REQUEST) ? $_REQUEST['news_subject_cn'] : false;
            $news_data_eng = array_key_exists('news_data_eng', $_REQUEST) ? $_REQUEST['news_data_eng'] : false;
            $news_data_bm = array_key_exists('news_data_bm', $_REQUEST) ? $_REQUEST['news_data_bm'] : false;
            $news_data_cn = array_key_exists('news_data_cn', $_REQUEST) ? $_REQUEST['news_data_cn'] : false;
            $news_cat = array_key_exists('news_cat', $_REQUEST) ? $_REQUEST['news_cat'] : false;      
            
      
            
            include("../connectDB.php");                        
            mysql_query("INSERT INTO news values (news_id, \"$news_date_year-$news_date_month-$news_date_day\", \"$news_cat\", \"$news_subject_eng\", \"$news_subject_bm\", \"$news_subject_cn\", \"$news_data_eng\", \"$news_data_bm\", \"$news_data_cn\")") or die(mysql_error());
            

                  
            $select_id = "SELECT news_id FROM news ORDER BY news_id DESC LIMIT 1;";
            $find_id = mysql_query($select_id);
            $news_id = mysql_result($find_id,0,"news_id");
            
            // adding pictures
            for ($i = 1; $i < 11; $i++) {                        
                  $news_pic = '../uploads-news/newsPic'.$news_id.'_'.$i.'.jpg';
                  move_uploaded_file($_FILES['news_pic_'.$i]['tmp_name'], $news_pic);      
                  chmod("$news_pic", 0755);      
            }
            header("location:admin-news-manage.php?flag=add-success");      
      }
      
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Admin Control Panel (ACP)</title>
<link href="adminStyle.css" rel="stylesheet" type="text/css"/>
</head>

<body>

<div class="mainContainer">
      <div class="mainTitle">HSC.com.my Admin Control Panel</div>
<?php include("admin-navi.php"); ?>


<div class="title">News > Add News Item</div>
      <form method="post" action="?action=add" enctype="multipart/form-data">      
          <div class="itemLabel">News Categories</div>
        <table>
            <tr>
                    <td style="padding-right:5px;">
                        <select name="news_cat">
                            <option><?php if ($news_cat == NULL)
                                          echo 'SELECT Categories';
                                          else
                                          echo $news_cat ?></option>
                            <option>A</option>
                            <option>B</option>
                            <option>C</option>
                            <option>D</option>
                            <option>E</option>
                            <option>F</option>
                            <option>G</option>
                        </select>                                    
                    </td>
            </tr>
        </table>
            <div class="itemLabel">Date</div>
            <table>
                  <tr>
                        <td style="padding-right:5px;">
                              <select name="news_date_day">
                                    <option>Day</option>
                                    <?php
                                          for ($i = 1; $i < 32; $i++) {
                                                echo "<option>$i</option>";
                                          }
                                    ?>
                              </select>                                    
                        </td>
                        <td style="padding-right:5px;">
                              <select name="news_date_month">
                                    <option>Month</option>
                                    <?php
                                          for ($i = 1; $i < 13; $i++) {
                                                echo "<option>$i</option>";
                                          }
                                    ?>
                              </select>                                    
                        </td>
                        <td style="padding-right:5px;">
                              <select name="news_date_year">
                                    <option>Year</option>
                                    <?php
                                          $year = getdate();
                                          $pre_year_1 = $year[year];
                                          $pre_year = $pre_year_1 - 2;
                                          $after_year = $year[year] + 10;
                                          for ($i = $pre_year ; $i < $after_year; $i++) {
                                                echo "<option>$i</option>";
                                          }
                                    ?>
                              </select>                              
                        </td>                                                                                    
                  </tr>
            </table>            
            <div class="itemLabel">News Subject (English)</div>
            <div><input name="news_subject_eng" type="text" class="textBox"/></div>            
            <div class="itemLabel">News Subject (BM)</div>
            <div><input name="news_subject_bm" type="text" class="textBox" value="(No Bahasa Translation Yet)"/></div>      
            <div class="itemLabel">News Subject (Chinese)</div>
            <div><input name="news_subject_cn" type="text" class="textBox" value="(No Chinese Translation Yet)"/></div>      
            <div class="itemLabel">News Description (English)</div>
            <div><textarea name="news_data_eng" type="text" class="textArea"></textarea></div>            
            <div class="itemLabel">News Description (BM)</div>
            <div><textarea name="news_data_bm" type="text" class="textArea">(No Bahasa Translation Yet)</textarea></div>            
            <div class="itemLabel">News Description (Chinese)</div>
            <div><textarea name="news_data_cn" type="text" class="textArea">(No Bahasa Chinese Yet)</textarea></div>            
            <?php
                  for ($i = 1; $i < 11; $i++) {
                        echo "
                              <div class=\"itemLabel\">News Picture</div>
                              <div><input name=\"news_pic_$i\" type=\"file\"/></div>
                        ";      
                  }
            ?>            
            <br/>
            <div class="submitButton"><input type="submit" value="Add News" class="button"/></div>
      </form>      
      
</div> <!-- end of mainContainer -->

</body>
</html>
0
 
LVL 34

Expert Comment

by:Slick812
ID: 39889302
I separated out most of your code in the last comment, and looked at one code section at a time, and then tried to figure how it all works together. This code line -
$flag = array_key_exists('flag', $_REQUEST) ? $_REQUEST['flag'] : false;
    Should be DELETED, as the variable $flag  is NEVER used ! !

You start your FORM value retrieval with -
if ($action == "add") {
  $news_date_day = array_key_exists('news_date_day', $_REQUEST) ?
     $_REQUEST['news_date_day'] : false;

I must say that you do NOT use code for -
 array_key_exists('news_date_day', $_REQUEST) ? $_REQUEST['news_date_day'] : false;

   that is effective, I'd even call this code incorrect for your purposes here.
   FIRST for several reasons (slight code security is among them), If you have a FORM user input (as u do here), ALWAYS use the specific php  $_POST['news_date_day'] to get values and DON'T USE   $_REQUEST['news_date_day']  as you do here, because you do not want someone to make a GET access to your page and attempt to alter the strings that go to your database.

ALSO the call of  array_key_exists('news_date_day', $_REQUEST),  has NO ADVANTAGE or good purpose for this code work, this "Array Key" is almost sure to exist, even if the user did NOT place any text in a "form input text" value field.

Some code that helps me is -
$aryInputs = array( ); // Make an INPUT container Array to loop

// use empty($_POST['id']) to see if there is a VALUE and add to array
$aryInputs['id'] = (empty($_POST['id'])) ? "\0" : $_POST['id'];
$aryInputs['name'] = (empty($_POST['name'])) ? "\0" : $_POST['name'];

$errors = ''; // add ERRORS when CHECK for empty input or POST value verification
foreach ($aryInputs as $key => &$value) {
  if ($value == "\0") {
    $errors .= 'input '.$key.' is EMPTY, '; // add to errors
    } else { 
    if (($key == 'name') && (strlen($value) < 4)) // CHECK INPUT VALUES!
      $errors .= 'input '.$key.' needs 4 or more length, ';
      else $value = mysql_escape_string($value); // do SQL injection code here
    }
  }

if ($errors) {
  // CODE HERE, to NOT do database insert, and display form input 
  //  empty errors on the FORM PAGE
  }

Open in new window



in your code you do NO SQL injection prevention as you have -
mysql_query("INSERT INTO news values (news_id,
    \"$news_date_year-$news_date_month-$news_date_day\",

    but you never do a mysql_escape_string($news_date_year)  on the $news_date_year  variable.

You mix GET and POST in your form as -
<form method="post" action="?action=add"

I have used the way of giving the Submit button a NAME, and testin for the name in the $_POST to see if tha form was submitted as -
<input type="submit" value="Add News" name ="add" class="button"/>
change form to have NO GET -
<form method="post"

and change this -
$action = array_key_exists('action', $_REQUEST) ? $_REQUEST['action'] : false;      
if ($action == "add") {


to this -

if (isset($_POST['add'])) {


//  // // //
also in your input textarea you should not have the type="text"
<textarea name="news_data_bm" class="textArea">

These are just some suggestions, but there are hundreds of different ways in PHP to do FORM input checking and SQL injection preventions in PHP with different requirements for database querys.
Ask questions if you need more clarity or suggestions.
0
 

Author Closing Comment

by:swpui
ID: 40166463
we had used the solution. tq
0

Featured Post

NFR key for Veeam Backup for Microsoft Office 365

Veeam is happy to provide a free NFR license (for 1 year, up to 10 users). This license allows for the non‑production use of Veeam Backup for Microsoft Office 365 in your home lab without any feature limitations.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction Since I wrote the original article about Handling Date and Time in PHP and MySQL several years ago, it seemed like now was a good time to update it for object-oriented PHP.  This article does that, replacing as much as possible the pr…
This post contains step-by-step instructions for setting up alerting in Percona Monitoring and Management (PMM) using Grafana.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question