tek4

Một số hàm xử lý an toàn trong PHP

by - September. 21, 2021
Kiến thức
Học
<p>Trong b&agrave;i viết n&agrave;y, ta sẽ c&ugrave;ng t&igrave;m hiểu về một số h&agrave;m xử l&yacute; an to&agrave;n trong PHP nhằm ngăn chặn một số tấn c&ocirc;ng nhằm v&agrave;o c&aacute;c trang Web.</p> <h1>C&aacute;c mối đe dọa bảo mật tiềm ẩn</h1> <p>Về cơ bản, c&oacute; 2 nh&oacute;m người c&oacute; thể g&acirc;y hại tới hệ thống:</p> <ul> <li>Tin tặc c&oacute; mục đ&iacute;ch gi&agrave;nh quyền truy cập v&agrave;o dữ liệu tr&aacute;i ph&eacute;p hoặc l&agrave;m hỏng ứng dụng.</li> <li>Người d&ugrave;ng c&oacute; thể nhập sai c&aacute;c th&ocirc;ng số v&agrave;o c&aacute;c biểu mẫu v&agrave; c&oacute; thể t&aacute;c động ti&ecirc;u cực đến một trang Web hoặc ứng dụng Web.</li> </ul> <p>SQL Injection: Kiểu tấn c&ocirc;ng n&agrave;y sẽ th&ecirc;m đoạn m&atilde; c&oacute; hại v&agrave;o c&aacute;c c&acirc;u lệnh SQL. Điều n&agrave;y được thực hiện bằng c&aacute;ch sử dụng biểu mẫu nhập đầu v&agrave;o của người d&ugrave;ng hoặc bằng đường dẫn URL. Đoạn m&atilde; được th&ecirc;m sẽ ch&uacute; th&iacute;ch cho điều kiện trong mệnh đề WHERE của c&acirc;u lệnh SQL. Đoạn m&atilde; được th&ecirc;m c&oacute; thể ch&egrave;n một điều kiện m&agrave; lu&ocirc;n đ&uacute;ng, từ đ&oacute; sẽ x&oacute;a dữ liệu khỏi bảng hoặc cập nhật dữ liệu trong bảng, g&acirc;y hại tới dữ liệu. Loại tấn c&ocirc;ng n&agrave;y thường được sử dụng để truy cập tr&aacute;i ph&eacute;p v&agrave;o một ứng dụng.</p> <p>Cross-site scripting: Kiểu tấn c&ocirc;ng n&agrave;y sẽ ch&egrave;n đoạn m&atilde; c&oacute; hại bằng JavaScript. Điều n&agrave;y được thực hiện bằng c&aacute;ch sử dụng c&aacute;c biểu mẫu đầu v&agrave;o của người d&ugrave;ng. Kiểu tấn c&ocirc;ng n&agrave;y thường được thực hiện để:</p> <ul> <li>Truy xuất th&ocirc;ng tin nhạy cảm như dữ liệu Cookie.</li> <li>Chuyển hướng người d&ugrave;ng đến một URL kh&aacute;c.</li> </ul> <h1>Một số h&agrave;m xử l&yacute; an to&agrave;n trong PHP</h1> <h2>1. H&agrave;m strip_tags()</h2> <p>H&agrave;m strip_tags() được sử dụng để loại bỏ c&aacute;c thẻ HTML, JavaScript hoặc PHP khỏi một chuỗi k&yacute; tự. H&agrave;m n&agrave;y rất hữu &iacute;ch trong việc bảo vệ ứng dụng chống lại c&aacute;c cuộc tấn c&ocirc;ng.</p> <p><em>C&uacute; ph&aacute;p:</em></p> <pre class="EnlighterJSRAW" data-enlighter-language="generic">strip_tags(chuỗi k&yacute; tự , c&aacute;c thẻ được ph&eacute;p giữ lại)</pre> <p>H&agrave;m tr&ecirc;n sẽ trả về gi&aacute; trị l&agrave; chuỗi k&yacute; tự đ&atilde; được loại bỏ c&aacute;c thẻ HTML, Javascript hoặc PHP.</p> <p>V&iacute; dụ:</p> <pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php echo strip_tags("Lập tr&igrave;nh PHP!&lt;br&gt; PHP","&lt;br&gt;"); ?&gt;</pre> <p>Kết quả:</p> <pre>Lập tr&igrave;nh PHP! PHP</pre> <p>Trong đoạn m&atilde; tr&ecirc;n, ta đ&atilde; sử dụng h&agrave;m strip_tags để loại bỏ c&aacute;c thẻ HTML, XML hoặc PHP. Tuy nhi&ecirc;n, ta đ&atilde; truyền k&yacute; tự sẽ được giữ lại l&agrave; &lt;br&gt; trong chuỗi k&yacute; tự l&agrave;: Lập tr&igrave;nh PHP!&lt;br&gt; PHP. Do đ&oacute;, kết quả l&agrave; chuỗi k&yacute; tự PHP sẽ vẫn được xuống d&ograve;ng mới.</p> <p>V&iacute; dụ 2:</p> <pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php $inp = "&lt;script&gt;alert('Bạn đ&atilde; bị tấn c&ocirc;ng!');&lt;/script&gt;"; echo $inp; ?&gt;</pre> <p>Giả sử người d&ugrave;ng sẽ nhập v&agrave;o một đoạn m&atilde; l&agrave;:</p> <pre class="EnlighterJSRAW" data-enlighter-language="generic">&lt;script&gt;alert('Bạn đ&atilde; bị tấn c&ocirc;ng!');&lt;/script&gt;</pre> <p>V&agrave;o trong một biểu mẫu. V&agrave; khi ph&iacute;a b&ecirc;n m&aacute;y chủ thực thi c&acirc;u lệnh, đoạn m&atilde; sẽ được thực thi v&agrave; đưa ra th&ocirc;ng b&aacute;o tấn c&ocirc;ng. Nếu b&ecirc;n m&aacute;y chủ kh&ocirc;ng xử l&yacute; c&aacute;c đoạn m&atilde; như n&agrave;y, th&igrave; sẽ rất dễ d&agrave;ng bị tấn c&ocirc;ng v&agrave; bị đ&aacute;nh cắp dữ liệu hoặc g&acirc;y hư hại cho hệ thống.</p> <p>Do đ&oacute;, để xử l&yacute; điều n&agrave;y, h&agrave;m strip_tags() sẽ được sử dụng trong đoạn m&atilde; b&ecirc;n dưới như sau:</p> <pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php $inp = "&lt;script&gt;alert('Bạn đ&atilde; bị tấn c&ocirc;ng!');&lt;/script&gt;"; $proc = strip_tags($inp); echo $proc; ?&gt;</pre> <p>Kết quả:</p> <pre>alert('Bạn đ&atilde; bị tấn c&ocirc;ng!');</pre> <p>Trong đoạn m&atilde; tr&ecirc;n, ta đ&atilde; sử dụng h&agrave;m strip_tags để loại bỏ c&aacute;c thẻ &lt;script&gt; trong đầu v&agrave;o của người d&ugrave;ng v&agrave; tr&aacute;nh được c&aacute;c c&acirc;u lệnh tấn c&ocirc;ng c&oacute; thể được thực thi bằng thẻ &lt;script&gt; n&agrave;y.</p> <h2>2. H&agrave;m filter_var()</h2> <p>H&agrave;m filter_var() được sử dụng để x&aacute;c thực v&agrave; l&agrave;m sạch dữ liệu. X&aacute;c thực nhằm kiểm tra xem dữ liệu c&oacute; đ&uacute;ng kiểu dữ liệu hay kh&ocirc;ng v&agrave; x&oacute;a c&aacute;c k&yacute; tự kh&ocirc;ng hợp lệ ra khỏi một chuỗi k&yacute; tự.</p> <p><em>C&uacute; ph&aacute;p:</em></p> <pre class="EnlighterJSRAW" data-enlighter-language="generic">filter_var(var, filtername, options)</pre> <p>Trong đ&oacute;:</p> <ul> <li>var l&agrave; biến cần được lọc dữ liệu.</li> <li>filtername l&agrave; bộ lọc được sử dụng để lọc dữ liệu.</li> <li>option l&agrave; tham số chỉ định c&aacute;c t&ugrave;y chọn hoặc c&aacute;c cờ được sử dụng.</li> </ul> <p>Gi&aacute; trị trả về của h&agrave;m n&agrave;y l&agrave; dữ liệu được lọc th&agrave;nh c&ocirc;ng, hoặc gi&aacute; trị FALSE nếu kh&ocirc;ng được lọc th&agrave;nh c&ocirc;ng.</p> <p>V&iacute; dụ: Ta sẽ lọc đầu v&agrave;o của người d&ugrave;ng nhập l&agrave; email.</p> <pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php $inp = "NguyenA@mail.com"; $inp = filter_var($inp, FILTER_SANITIZE_EMAIL); if (filter_var($inp, FILTER_SANITIZE_EMAIL)) { &nbsp;&nbsp;&nbsp; echo("Địa chỉ Email hợp lệ"); } else { &nbsp;&nbsp;&nbsp; echo("Địa chỉ Email kh&ocirc;ng hợp lệ"); } ?&gt;</pre> <p>Trong đoạn m&atilde; tr&ecirc;n, ta sử dụng h&agrave;m filter_var để loại bỏ c&aacute;c k&yacute; tự kh&ocirc;ng hợp lệ ra khỏi chuỗi đầu v&agrave;o bằng:</p> <p>Bộ lọc FILTER_SANITIZE_EMAIL để x&oacute;a tất cả c&aacute;c k&yacute; tự kh&ocirc;ng hợp lệ khỏi địa chỉ email.</p> <p>V&iacute; dụ 2: Ta sẽ lọc đầu v&agrave;o người d&ugrave;ng.</p> <pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php $inp = "https://tek4.com"; $inp = filter_var($inp, FILTER_SANITIZE_URL); if (filter_var($inp, FILTER_SANITIZE_URL)) { &nbsp;&nbsp;&nbsp; echo("$inp l&agrave; đường dẫn URL hợp lệ"); } else { &nbsp;&nbsp;&nbsp; echo("Đường dẫn URL kh&ocirc;ng hợp lệ"); } ?&gt;</pre> <p>Kết quả:</p> <pre>httpstek4.com l&agrave; đường dẫn URL hợp lệ</pre> <p>Trong đoạn m&atilde; tr&ecirc;n, ta sử dụng bộ lọc FILTER_SANITIZE_URL để x&oacute;a tất cả c&aacute;c k&yacute; tự kh&ocirc;ng hợp lệ khỏi đường dẫn URL.</p> <p>V&iacute; dụ 3: Xử l&yacute; loại bỏ c&aacute;c k&yacute; tự kh&ocirc;ng hợp lệ trong chuỗi k&yacute; tự.</p> <pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php $inp = "&lt;script&gt;alert('Bạn đ&atilde; bị tấn c&ocirc;ng!');&lt;/script&gt;"; $inp = filter_var($inp, FILTER_SANITIZE_STRIPPED); if(filter_var($inp, FILTER_SANITIZE_STRIPPED)){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo "Tấn c&ocirc;ng thất bại&lt;br&gt;"; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo $inp; } ?&gt;</pre> <p>Trong đoạn m&atilde; tr&ecirc;n, ta đ&atilde; sử dụng bộ lọc FILTER_SANITIZE_STRIPPED để loại bỏ c&aacute;c k&yacute; tự kh&ocirc;ng hợp lệ trong chuỗi đầu v&agrave;o của người d&ugrave;ng.</p> <p>V&iacute; dụ 4: Kiểm tra số nguy&ecirc;n.</p> <pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php $so_nguyen = 16.5; if (filter_var($so_nguyen, FILTER_VALIDATE_INT)) { &nbsp; echo("L&agrave; số nguy&ecirc;n."); } else { &nbsp; echo("Kh&ocirc;ng phải số nguy&ecirc;n."); } ?&gt;</pre> <p>Trong đoạn m&atilde; tr&ecirc;n, ta sử dụng bộ lọc FILTER_VALIDATE_INT để kiểm tra xem gi&aacute; trị của biến $so_nguyen l&agrave; số nguy&ecirc;n hay kh&ocirc;ng.</p> <h2>3. H&agrave;m filter_has_var()</h2> <p>H&agrave;m filter_has_var() kiểm tra xem một biến của kiểu đầu v&agrave;o được x&aacute;c định c&oacute; tồn tại hay kh&ocirc;ng. H&agrave;m n&agrave;y kiểm tra nội dung m&agrave; trang PHP nhận được, v&igrave; vậy biến phải được gửi đến trang th&ocirc;ng qua v&iacute; dụ như chuỗi k&yacute; tự truy vấn.</p> <p><em>C&uacute; ph&aacute;p:</em></p> <pre class="EnlighterJSRAW" data-enlighter-language="generic">filter_has_var(kiểu dữ liệu, biến)</pre> <p>Trong đ&oacute;:</p> <ul> <li>Thao số đầu ti&ecirc;n l&agrave;: Kiểu đầu v&agrave;o để kiểm tra. C&oacute; thể l&agrave; một trong c&aacute;c kiểu sau: <ul> <li>INPUT_GET</li> <li>INPUT_POST</li> <li>INPUT_COOKIE</li> <li>INPUT_SERVER</li> <li>INPUT_ENV</li> </ul> </li> <li>Tham số thứ 2 l&agrave; biến, l&agrave; bắt buộc cần phải được truyền v&agrave;o.</li> </ul> <p>V&iacute; dụ: Ta c&oacute; đoạn m&atilde; v&agrave; đường dẫn URL như sau.</p> <p>Đường dẫn URL: http://localhost:8080/index.php?mail=NguyenA@mail.com</p> <pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php if (!filter_has_var(INPUT_GET, "mail")) { &nbsp;&nbsp;&nbsp; echo("Kh&ocirc;ng tồn tại"); } else { &nbsp;&nbsp;&nbsp; echo("Tồn tại"); } ?&gt;</pre> <p>Kết quả:</p> <pre>Tồn tại.</pre> <p>Trong đoạn m&atilde; tr&ecirc;n, v&igrave; trong đường dẫn c&oacute; chứa biến mail được truy vấn bằng phương thức GET. Do đ&oacute;, h&agrave;m filter_has_var sẽ kiểm tra biến n&agrave;y c&oacute; tồn tại.</p> <h2>4. H&agrave;m filter_input()</h2> <p>H&agrave;m filter_input() nhận một biến b&ecirc;n ngo&agrave;i (v&iacute; dụ từ đầu v&agrave;o của biểu mẫu) v&agrave; thực hiện bộ lọc cho n&oacute;. H&agrave;m n&agrave;y được sử dụng để x&aacute;c thực c&aacute;c biến từ c&aacute;c nguồn kh&ocirc;ng an to&agrave;n, chẳng hạn như đầu v&agrave;o của người d&ugrave;ng.</p> <p><em>C&uacute; ph&aacute;p:</em></p> <pre class="EnlighterJSRAW" data-enlighter-language="generic">filter_input(type, variable, filter, options)</pre> <p>Trong đ&oacute;:</p> <ul> <li>Type l&agrave; kiểu loại bao gồm: <ul> <li>INPUT_GET</li> <li>INPUT_POST</li> <li>INPUT_COOKIE</li> <li>INPUT_SERVER</li> <li>INPUT_ENV</li> </ul> </li> <li>Variable l&agrave; biến được lọc.</li> <li>Filter l&agrave; bộ lọc được &aacute;p dụng.</li> <li>Options l&agrave; c&aacute;c t&ugrave;y chọn được th&ecirc;m cho việc lọc.</li> </ul> <p>V&iacute; dụ: Ta sẽ kiểm tra đầu v&agrave;o của người d&ugrave;ng với số nhập c&oacute; phải l&agrave; số nguy&ecirc;n hay kh&ocirc;ng bằng bộ lọc FILTER_VALIDATE_INT</p> <pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;!DOCTYPE html&gt; &lt;html&gt; &lt;body&gt; &lt;form method="get" action="&lt;?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?&gt;"&gt; Nhập số nguy&ecirc;n: &lt;input type="text" name="mail"&gt; &lt;input type="submit" name="submit" value="Submit"&gt; &lt;/form&gt; &lt;?php if (isset($_GET["mail"])) { &nbsp;&nbsp;&nbsp; if (filter_input(INPUT_GET, "mail", FILTER_VALIDATE_INT)) { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo("Số nhập v&agrave;o l&agrave; số nguy&ecirc;n"); &nbsp;&nbsp;&nbsp; } else { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo("Số nhập v&agrave;o kh&ocirc;ng phải l&agrave; số nguy&ecirc;n"); &nbsp;&nbsp;&nbsp; } } ?&gt; &lt;/body&gt; &lt;/html&gt;</pre> <p>Tr&ecirc;n đ&acirc;y l&agrave; kh&aacute;i niệm v&agrave; v&iacute; dụ cơ bản về một số h&agrave;m xử l&yacute; an to&agrave;n trong PHP. Hy vọng mọi người c&oacute; thể &aacute;p dụng v&agrave;o trong chương tr&igrave;nh của m&igrave;nh. Mọi người h&atilde;y tiếp tục theo d&otilde;i c&aacute;c b&agrave;i tiếp theo v&agrave; cập nhật c&aacute;c b&agrave;i mới nhất tr&ecirc;n <a href="http://tek4.vn">tek4</a> nh&eacute;!</p> <p>P/s: Cảm ơn mọi người!</p>