Câu hỏi

28/05/2013 07:32
Ngăn ngừa XSS như thế nào?
help
honghiquan
28/05/2013 07:32
Danh sách câu trả lời (1)

gười ta không lường hết được mức độ nguy hiểm của XSS nhưng cũng không quá khó khăn để ngăn ngừa XSS. Có rất nhiều cách để có thể giải quyết vấn đề này. OWASP (The Open Web Application Standard Project) nói rằng để có thể xây dựng các website bảo mật cao, đối với các dữ liệu của người sử dụng bạn nên
* Chỉ chấp nhận những dữ liệu hợp lệ.
* Từ chối nhận các dữ liệu hỏng.
* Liên tục kiểm tra và thanh lọc dữ liệu.
Tuy nhiên trên thực tế, một số trường hợp bạn phải chấp nhận mọi loại dữ liệu hay không có một bộ lọc phù hợp. Chính vì vậy bạn phải có những cách riêng để giải quyết.
Một trong những cách hay sử dụng là bạn mã hoá các kí tự đặc biệt trước khi in ra website, nhất là những gì có thể gây nguy hiểm cho người sử dụng. Trong trường hợp này thẻ script sẽ được đổi thành script. Như vậy nó sẽ vẫn được in ra màn hình mà không hề gây nguy hiểm cho người sử dụng.
Tôi lấy ví dụ với script search.cgi với mã nguồn là:
CODE
#!/usr/bin/perl
use CGI;
my $cgi = CGI->new();
my $query = $cgi->param('query');
print $cgi->header();
print "You entered $query";
Đây hoàn toàn là một script có lỗi bởi vì nó in ra trực tiếp dữ liệu được nhập vào. Dĩ nhiên là khi in ra, nó sẽ in ra dưới dạng đoạn mã HTML, như thế nó không chỉ không in ra chính xác những dữ liệu vào một cách trực quan mà còn có tiềm ẩn lỗi XSS.
Như đã nói ở trên, để có thể giải quyết vấn đề này, chúng ta có thể mã hoá các kí tự đặc biệt của HTML với hàm HTML::Entities::encode(). Như vậy ta có thể có một mã nguồn hoàn hảo hơn như sau:
CODE
#!/usr/bin/perl
use CGI;
use HTML::Entities;
my $cgi = CGI->new();
my $text = $cgi->param('text');
print $cgi->header();
print "You entered ", HTML::Entities::encode($text);
Tất nhiên với phương pháp này bạn cũng có thể áp dụng đối với các ngôn ngữ Web Application khác (ASP, PHP...). Để kiểm tra việc lọc và mã hoá dữ liệu trước khi in ra, các bạn có thể dùng một chương trình được viết bằng ngôn nhữ PHP, đặc biệt nó được thiết kế để phòng chống các lỗi XSS. Bạn có thể lấy mã nguồn chương trình từ http://www.mricon.com/html/phpfilter.html Lọc và mã hoá các dữ liệu cho vấn là cách tốt nhất để chống XSS nhưng nếu bạn đang sử dụng mod_perl trên Apache Server thì bạn có thể dùng ngay module Apache::TaintRequest. Khi đó mã nguồn chương trình sẽ có dạng:
CODE
use Apache::TaintRequest;
my $apr = Apache::TaintRequest->new(Apache->request);
my $text = $apr->param('text');
$r->content_type("text/html");
$r->send_http_header;
$text =~ s/[^A-Za-z0-9 ]//;
$r->print("You entered ", $text);
Kĩ thuật XSS được mô tả lần đầu tiên cách đây 2 năm và hầu hết các khả năng tiềm ẩn của kĩ thuật này đã được biết đến. Tuy nhiên chúng ta mới chỉ khắc phục được một phần của nó. Không phải vô tình mà Yahoo Mail lại để sót một lỗi XSS trong bộ lọc của mình. Một phương pháp tối ưu vẫn còn đang ở phía trước.
* Chỉ chấp nhận những dữ liệu hợp lệ.
* Từ chối nhận các dữ liệu hỏng.
* Liên tục kiểm tra và thanh lọc dữ liệu.
Tuy nhiên trên thực tế, một số trường hợp bạn phải chấp nhận mọi loại dữ liệu hay không có một bộ lọc phù hợp. Chính vì vậy bạn phải có những cách riêng để giải quyết.
Một trong những cách hay sử dụng là bạn mã hoá các kí tự đặc biệt trước khi in ra website, nhất là những gì có thể gây nguy hiểm cho người sử dụng. Trong trường hợp này thẻ script sẽ được đổi thành script. Như vậy nó sẽ vẫn được in ra màn hình mà không hề gây nguy hiểm cho người sử dụng.
Tôi lấy ví dụ với script search.cgi với mã nguồn là:
CODE
#!/usr/bin/perl
use CGI;
my $cgi = CGI->new();
my $query = $cgi->param('query');
print $cgi->header();
print "You entered $query";
Đây hoàn toàn là một script có lỗi bởi vì nó in ra trực tiếp dữ liệu được nhập vào. Dĩ nhiên là khi in ra, nó sẽ in ra dưới dạng đoạn mã HTML, như thế nó không chỉ không in ra chính xác những dữ liệu vào một cách trực quan mà còn có tiềm ẩn lỗi XSS.
Như đã nói ở trên, để có thể giải quyết vấn đề này, chúng ta có thể mã hoá các kí tự đặc biệt của HTML với hàm HTML::Entities::encode(). Như vậy ta có thể có một mã nguồn hoàn hảo hơn như sau:
CODE
#!/usr/bin/perl
use CGI;
use HTML::Entities;
my $cgi = CGI->new();
my $text = $cgi->param('text');
print $cgi->header();
print "You entered ", HTML::Entities::encode($text);
Tất nhiên với phương pháp này bạn cũng có thể áp dụng đối với các ngôn ngữ Web Application khác (ASP, PHP...). Để kiểm tra việc lọc và mã hoá dữ liệu trước khi in ra, các bạn có thể dùng một chương trình được viết bằng ngôn nhữ PHP, đặc biệt nó được thiết kế để phòng chống các lỗi XSS. Bạn có thể lấy mã nguồn chương trình từ http://www.mricon.com/html/phpfilter.html Lọc và mã hoá các dữ liệu cho vấn là cách tốt nhất để chống XSS nhưng nếu bạn đang sử dụng mod_perl trên Apache Server thì bạn có thể dùng ngay module Apache::TaintRequest. Khi đó mã nguồn chương trình sẽ có dạng:
CODE
use Apache::TaintRequest;
my $apr = Apache::TaintRequest->new(Apache->request);
my $text = $apr->param('text');
$r->content_type("text/html");
$r->send_http_header;
$text =~ s/[^A-Za-z0-9 ]//;
$r->print("You entered ", $text);
Kĩ thuật XSS được mô tả lần đầu tiên cách đây 2 năm và hầu hết các khả năng tiềm ẩn của kĩ thuật này đã được biết đến. Tuy nhiên chúng ta mới chỉ khắc phục được một phần của nó. Không phải vô tình mà Yahoo Mail lại để sót một lỗi XSS trong bộ lọc của mình. Một phương pháp tối ưu vẫn còn đang ở phía trước.
Trả lời câu hỏi
Câu hỏi lĩnh vực Câu hỏi khác
Rao vặt Siêu Vip