Solved

How to secure a form's login ID and password

Posted on 2014-01-18
18
359 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
  • 7
  • 4
  • 3
  • +3
18 Comments
 
LVL 58

Expert Comment

by:Gary
Comment Utility
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
Comment Utility
Yes we did place in the php code. Abny recommendation?
0
 
LVL 4

Expert Comment

by:ravikantninave
Comment Utility
Store UserName and Password in DB and check from it.
Should I post some code?
0
 
LVL 30

Accepted Solution

by:
Marco Gasi earned 500 total points
Comment Utility
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 108

Expert Comment

by:Ray Paseur
Comment Utility
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
Comment Utility
ravikantninave, yes please provide codes if you have for my reference.
0
 
LVL 30

Expert Comment

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

Author Comment

by:swpui
Comment Utility
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 30

Expert Comment

by:Marco Gasi
Comment Utility
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
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
... 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 33

Expert Comment

by:Slick812
Comment Utility
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
Comment Utility
slick812 here are the codes. pls guide me. Thanks.
adminLoginCheck.php
news-details.php
connectDB.php
0
 

Author Comment

by:swpui
Comment Utility
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 30

Expert Comment

by:Marco Gasi
Comment Utility
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 33

Expert Comment

by:Slick812
Comment Utility
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
Comment Utility
<?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 33

Expert Comment

by:Slick812
Comment Utility
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
Comment Utility
we had used the solution. tq
0

Featured Post

Easy Project Management (No User Manual Required)

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

I imagine that there are some, like me, who require a way of getting currency exchange rates for implementation in web project from time to time, so I thought I would share a solution that I have developed for this purpose. It turns out that Yaho…
This article discusses how to create an extensible mechanism for linked drop downs.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

771 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now