Writing Secure PHP – Bảo mật trong PHP – phần 4

Cross-Site Scripting (XSS)
Cross-site scripting (thường được viết tắt thành XSS để tránh nhầm lẫn với định dạng CSS) là một kiểu tấn công vào form nhập liệu, khi đó kẽ tấn công tìm được một form nhập liệu có thể nhập code điều khiển theo ý muốn của họ. Trong hầu hết các form nhập liệu, đơn giản việc quên lọc các tag HTML cũng có thể bị lợi dụng. ví dụ một hacker có thể chọn username của họ như sau:DaveChildVà bây giờ mổi khi tên sử dụng trên hiển thị về phía người dùng, đoạn script my_script trên sẽ được thực thi, và kẽ tấn công có thể làm được rất nhiều thứ từ script này như lấy thông tin tài khoản, ăn cắp cookie, cài keylog và một vài thứ khác.

Một developer có thể ngăn chặn kiểu tấn công này một cách đơn giản bằng cách encode nội dung form hoặc xóa một sổ tag HTML như embed, script, iframe… để tránh việc người dùng website của mình bị tấn công.

Cross-Site Request Forgery (CSRF)
Mặc dù hơi giống với XSS, nhưng CSRF là một hình thức tấn công khác bằng cách lợi dụng chứng thực (login) của người khác để sử dụng quyền của người đã chứng thực trên website.

Hãy giả sử rằng Jack có một tài khoản tại ngân hàng, ở thời điểm đăng nhập vào website đó, một cookie được tạo ra và lưu trên máy tính của Jack. Và khi thực hiện các thao tác trên website, cookie trên cùng với những thông tin truy vấn được gửi tới máy chủ. Máy chủ dựa vào cookie đó để biế được đó là Jack.

Bill là một chủ sở hửu website khác, và Jack có tham gia vào website này, nhân cơ hội này, Bill thu thập những cookie của Jack. Một trong những ứng dụng thực tế trên tài khoản ngân hàng của Jack là chuyển tiền từ tài khoản này đến tài khoản khác. Và nhờ có được cookie trong phiên đăng nhập của Jack, Bill sẽ gửi đến ngân hàng những Request yêu cầu chuyển tiền từ tài khoản của Jack vào tài khoản của Bill cùng với cookie trên, và vì cookie này được ăn cắp từ máy của Jack, yêu cầu chuyển tiền được chấp nhận.

Kiểu tấn công này rất khó để phòng bị, bởi còn phụ thuộc vào yếu tố khách hàng sử dụng website. Và là nhà phát triển web, bạn phải cố gắng ngăn chặn nó, lúc này, hãy nhớ đến quy tắc 1: không được tin vào người dùng mà tôi đã có dịp đề cập đến.

* Trong thực tế viết mã PHP, bạn có thể chống CSRF một cách tương đối bằng thói quen viết mã, ví dụ như luôn sử dụng phương thức POST thay cho GET nếu có thể.
* Hoặc luôn yêu cầu người dùng xác thực yes no và đưa ra một số thông tin chi tiết giúp người dùng chắc chắn về những gì mình sẽ làm.
* Và tốt hơn nữa, hãy xác nhận mật khẩu và captcha khi tiến hành những request quan trọng.
* Tạo ra một random token trên request kèm theo cookie để tăng tính kiểm soát.
* Khuyến khích người dùng luôn thoát khỏi tài khoản khi kết thúc tiến trình.
* Sử dụng chế độ bảo mật trong hàm setcookie.
* Kiểm tra các HTTP_REFERER nhằm mục đích chắc chắn đó không phải là một request từ kiểu tấn công CSRF như IP, browse agent.

Character Encoding
Character encoding trong PHP và hệ thống CSDL có cả loạt bài viết nói riêng về chủ đề này. Một request đơn giản, chứa trong đó nhiều phương thức mã hóa dữ liệu mà bạn có thể nghĩ đến.

Ví dụ với một request và response đơn giản như upload file và ghi dữ liệu vào csdl, có thể theo đó là rất nhiều kiểu mã hóa dữ liệu khác nhau: HTTP request headers, post data, PHP default encoding, PHP MySQL module, MySQL default set, file being opened and read, a new file being created and written, the response headers and the response body.

Một số developer viết website bằng tiếng Anh và họ không quan tâm đến mã hóa ký tự (vì sử dụng tiếng Anh và mã hóa ASCII là đủ để sử dụng) và kết quả để xãy ra những lỗi đáng tiếc trên website. Tuy nhiên, hãy nhớ rằng các bộ mã hóa ký tự, tuy rất đơn giản, nhưng là một thành phần cơ bản của website. Tiếng Anh cùng với bảng mã ASCII có thể hiển thị tốt ở bất cứ trình duyệt nào, và 2 bộ mã thường được sử dụng là UTF-8 và iso-8859-1.

Lý do tôi đưa character encoding vào lỗi bảo mật, là vì sự nhùng nhằng trong việc sử dụng nhiều kiểu mã hóa khác nhau, vô tình tạo ra những cạm bẫy mã hóa ký tự như việc một máy chủ PHP xữ lý mã hóa khác với máy chủ MySQL, bạn đã phòng ngự SQL Injection, nhưng trên thực tế vẫn có thể tấn công vào lỗi này.

Chuyên gia bảo mật Chris Shiflett đã viết một bài viết về vấn đề mysql_real_escape_string() và addslashes() để ngăn ngừa Injection attrack.

Giải pháp cho vấn đề này là luôn sử dụng hàm mysql_real_escape_string() thay cho addslashes() (hoặc sử dụng các thủ tục chẩn bị lưu trử).
Lý tưởng nhất, hãy luôn sử dụng cùng một bộ mã như UTF-8 trên toàn bộ hệ thống website. Và nơi nào PHP cho phép bạn chỉ định mã hóa dữ liệu (htmlspecialchars() hoặc htmlentities()) – hãy sử dụng nó.

PHP Login script tutorial
Learn to create a simple login system with php + mysql script, this tutorial easy to follow, teach you step by step.
//
//
Overview
In this tutorial create 3 files
1. main_login.php
2. checklogin.php
3. login_success.phpStep
1. Create table “members” in database “test”.
2. Create file main_login.php.
3. Create file checklogin.php.
4. Create file login_success.php.
5. Create file logout.phpIf you don’t know how to create databse, click here
Create table “members”
CREATE TABLE `members` (
`id` int(4) NOT NULL auto_increment,
`username` varchar(65) NOT NULL default ”,
`password` varchar(65) NOT NULL default ”,
PRIMARY KEY (`id`)
) TYPE=MyISAM AUTO_INCREMENT=2 ;–
— Dumping data for table `members`
–INSERT INTO `members` VALUES (1, ‘john’, ‘1234’);
Create file main_login.php
View In Browser

############### Code<table width=”300″ border=”0″ align=”center” cellpadding=”0″ cellspacing=”1″ bgcolor=”#CCCCCC”>
<tr>
<form name=”form1″ method=”post” action=”checklogin.php”>
<td>
<table width=”100%” border=”0″ cellpadding=”3″ cellspacing=”1″ bgcolor=”#FFFFFF”>
<tr>
<td colspan=”3″><strong>Member Login </strong></td>
</tr>
<tr>
<td width=”78″>Username</td>
<td width=”6″>:</td>
<td width=”294″><input name=”myusername” type=”text” id=”myusername”></td>
</tr>
<tr>
<td>Password</td>
<td>:</td>
<td><input name=”mypassword” type=”text” id=”mypassword”></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td><input type=”submit” name=”Submit” value=”Login”></td>
</tr>
</table>
</td>
</form>
</tr>
</table>
Create file checklogin.php
############### Code<?php
$host=”localhost”; // Host name
$username=””; // Mysql username
$password=””; // Mysql password
$db_name=”test”; // Database name
$tbl_name=”members”; // Table name// Connect to server and select databse.
mysql_connect(“$host”, “$username”, “$password”)or die(“cannot connect”);
mysql_select_db(“$db_name”)or die(“cannot select DB”);// username and password sent from form
$myusername=$_POST[‘myusername’];
$mypassword=$_POST[‘mypassword’];

// To protect MySQL injection (more detail about MySQL injection)
$myusername = stripslashes($myusername);
$mypassword = stripslashes($mypassword);
$myusername = mysql_real_escape_string($myusername);
$mypassword = mysql_real_escape_string($mypassword);

$sql=”SELECT * FROM $tbl_name WHERE username=’$myusername’ and password=’$mypassword'”;
$result=mysql_query($sql);

// Mysql_num_row is counting table row
$count=mysql_num_rows($result);
// If result matched $myusername and $mypassword, table row must be 1 row

if($count==1){
// Register $myusername, $mypassword and redirect to file “login_success.php”
session_register(“myusername”);
session_register(“mypassword”);
header(“location:login_success.php”);
}
else {
echo “Wrong Username or Password”;
}
?>

Create file login_success.php
############### Code// Check if session is not registered , redirect back to main page.
// Put this code in first line of web page.
<?
session_start();
if(!session_is_registered(myusername)){
header(“location:main_login.php”);
}
?><html>
<body>
Login Successful
</body>
</html>
Logout.php
If you want to logout, create this file// Put this code in first line of web page.
<?
session_start();
session_destroy();
?>
For PHP5 User – checklogin.php
############### Code<?php
ob_start();
$host=”localhost”; // Host name
$username=””; // Mysql username
$password=””; // Mysql password
$db_name=”test”; // Database name
$tbl_name=”members”; // Table name// Connect to server and select databse.
mysql_connect(“$host”, “$username”, “$password”)or die(“cannot connect”);
mysql_select_db(“$db_name”)or die(“cannot select DB”);// Define $myusername and $mypassword
$myusername=$_POST[‘myusername’];
$mypassword=$_POST[‘mypassword’];

// To protect MySQL injection (more detail about MySQL injection)
$myusername = stripslashes($myusername);
$mypassword = stripslashes($mypassword);
$myusername = mysql_real_escape_string($myusername);
$mypassword = mysql_real_escape_string($mypassword);

$sql=”SELECT * FROM $tbl_name WHERE username=’$myusername’ and password=’$mypassword'”;
$result=mysql_query($sql);

// Mysql_num_row is counting table row
$count=mysql_num_rows($result);
// If result matched $myusername and $mypassword, table row must be 1 row

if($count==1){
// Register $myusername, $mypassword and redirect to file “login_success.php”
session_register(“myusername”);
session_register(“mypassword”);
header(“location:login_success.php”);
}
else {
echo “Wrong Username or Password”;
}

ob_end_flush();
?>

Encrypting Password – Make your Login More Secure

 

Về vdhungbg
Tin tuc cap nhat - moi luc - moi noi

Gửi phản hồi

Please log in using one of these methods to post your comment:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s

%d bloggers like this: