php安全 过滤、验证、转义
不要相信外部源
- $_GET
- $_POST
- $_REQUEST
- $_COOKIE
- $argv
- php://stdin
- php://input
- file_get_contents()
- 远程数据库
- 远程api
- 来自客户端的数据
1 <?php 2 $input = '<p><script>alert("You won the Nigerian lottery!");</script></p>'; 3 echo htmlentities($input, ENT_QUOTES, 'UTF-8').PHP_EOL; 4 // <p><script>alert("You won the Nigerian lottery!");</script></p> 5 6 $email = 'john介样子@example.com'; 7 $emailSafe = filter_var($email, FILTER_SANITIZE_EMAIL); 8 echo $emailSafe.PHP_EOL; 9 // john@example.com 10 11 $string = "\ni18n说的话\t"; 12 $safeString = filter_var( 13 $string, 14 FILTER_SANITIZE_STRING, 15 FILTER_FLAG_STRIP_LOW | FILTER_FLAG_ENCODE_HIGH 16 ); 17 echo $safeString.PHP_EOL; 18 // i18n说的话 19 20 // 转义输出 21 $output = '<p><script>alert("NSA backdoor installed")</script></p>'; 22 echo htmlentities($output, ENT_QUOTES, 'UTF-8').PHP_EOL; 23 // <p><script>alert("NSA backdoor installed")</script></p>
模板引擎
一些加密函数
md5, sha1, bcrypt, scrypt
* 注册用户
POST /register.php HTTP/1.1
Content-Length: 43
Content-Type: application/x-www-form-urlencoded
email=john@example.com&password=sekritshhh!
<?php /** * Created by PhpStorm. * User: Mch * Date: 7/17/18 * Time: 22:47 */ try { // 验证电子邮箱地址 $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL); if (!$email) { throw new Exception('Invalid email'); } // 验证密码 $password = filter_input(INPUT_POST, 'password'); if (!$password || mb_strlen($password) < 8) { throw new Exception('Password must contain 8+ characters'); } // 创建密码的hash $passwordHash = password_hash($password, PASSWORD_DEFAULT, ['cost'=>12]); if ($passwordHash === false) { throw new Exception('Password hash failed'); } // 创建用户账户(pseudo code) $user = new User(); $user->email = $email; $user->pasword_hash = $passwordHash; $user->save(); // 重定向到登录页面 header('HTTP/1.1 302 Redirect'); header('Location: /login.php'); } catch (Exception $e) { // 报告错误 header('HTTP/1.1 400 Bad request'); echo $e->getMessage(); }
1 <?php 2 /** 3 * POST /login.php HTTP/1.1 4 * Content-Length: 43 5 * Content-Type: application/x-www-form-urlencoded 6 * 7 * email=john@example.com&password=sekritshhh! 8 */ 9 session_start(); 10 11 try { 12 $email = filter_input(INPUT_POST, 'email'); 13 $password = filter_input(INPUT_POST, 'password'); 14 15 // (pseudo code) 16 $user = User::findByEmail($email); 17 // 如果需要, 重新计算密码的hash值 18 if (password_verify($password, $user->password_hash)===false) { 19 throw new Exception('Invalid password'); 20 } 21 22 // 如果需要, 重新计算密码的hash值 23 $currentHashAlgorithm = PASSWORD_DEFAULT; 24 $currentHashOptions = ['cost' => 15]; 25 $passwordNeedsRehash = password_needs_rehash( 26 $user->password_hash, 27 $currentHashAlgorithm, 28 $currentHashOptions 29 ); 30 if ($passwordNeedsRehash === true) { 31 // 保存新计算得到的密码hash值 (pseudo code) 32 $user->password_hash = password_hash( 33 $password, 34 $currentHashAlgorithm, 35 $currentHashOptions 36 ); 37 $user->save(); 38 } 39 $_SESSION['user_logged_in'] = 'yes'; 40 $_SESSION['user_email'] = $email; 41 42 // redirect 43 header('HTTP/1.1 302 Redirect'); 44 header('Location: /user-profile.php'); 45 46 } catch (Exception $e) { 47 header('HTTP/1.1 401 Unauthorized'); 48 echo $e->getMessage(); 49 }