【发布时间】:2015-11-14 13:30:29
【问题描述】:
我正在尝试创建一个安全的注册表单,这只是前几个字段,接下来还会有大约十几个字段,但这无关紧要。我有点安全意识,我想知道以下代码是否充分保护了 XSS 和 SQL 注入。
- 我正在使用 htmlentities,因为如果任何条目有误,我会将一些用户输入显示给用户。
- 我相信我正确地使用了准备好的语句。
-
我已经包含了表格的开头,只是为了表明因为我要发布到自我,所以需要htmlentities。
if(isset($_POST['submit'])){ $firstname = htmlentities($_POST['firstname'], ENT_QUOTES, 'UTF-8'); $lastname = htmlentities($_POST['lastname'], ENT_QUOTES, 'UTF-8'); $email = htmlentities($_POST['email'], ENT_QUOTES, 'UTF-8'); $emailrepeat = htmlentities($_POST['emailrepeat'], ENT_QUOTES, 'UTF-8'); $password = htmlentities($_POST['password'], ENT_QUOTES, 'UTF-8'); $passwordrepeat = htmlentities($_POST['passwordrepeat'], ENT_QUOTES, 'UTF-8'); if (empty($firstname)) { $fnError = "Please Enter Your First Name"; } if (empty($lastname)) { $lnError = "Please Enter Your Last Name"; } $getEmail = $mysqli->prepare('SELECT * FROM users WHERE email=?'); $getEmail->bind_param('s', $email); $getEmail->execute(); $getEmail->store_result(); $countRows = $getEmail->num_rows; if ($countRows > 0) { $emError = "Email Address Already Exists"; $countRows = 0; } else if (empty($email)) { $emError = "Please Enter an Email Address"; } else if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { $emError = "Invalid Email Address"; } else if ($email != $emailrepeat) { $emError = "Emails do not match"; } if (empty($password)) { $pwError = "Please Enter a Password"; } else if (strlen($password)<6) { $pwError = "Password must be atleast 6 characters"; } else if ($password != $passwordrepeat) { $pwError = "Emails do not match"; } if (filter_var($email, FILTER_VALIDATE_EMAIL)) { if ($password == $passwordrepeat and !empty($password) and strlen($password)>5) { $pwhash = password_hash($password, PASSWORD_BCRYPT, array("cost" => 11)); if($stmt = $mysqli->prepare("INSERT INTO users (first_name, last_name, email, password) VALUES (?, ?, ?, ?)")) { $stmt->bind_param("ssss", $firstname, $lastname, $email, $pwhash); $stmt->execute(); $stmt->close(); } } } } <form id="addnewuser" action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>" method="POST"> </form>
【问题讨论】:
-
这对我来说看起来不错。我没有看到任何重大问题。除了下面 MonkeyZeus 的担忧,还有什么特别的原因让你选择了
PASSWORD_BCRYPT而不是PASSWORD_DEFAULT?现在它们是等价的,但请记住,PASSWORD_DEFAULT旨在随着时间的推移随着 PHP 中添加新的和更强大的算法而改变。只是需要考虑... -
@IanDrake 我可能会误解一些东西,但是如果本周
PASSWORD_DEFAULT是Algorithm1024下周是Algorithm2048那么第一周的用户将不再能够登录在? -
@MonkeyZeus 根据我的理解,
password_hash()总是在生成的哈希中编码算法信息,所以password_verify()总是知道如何验证它。文档说,“使用的算法、成本和盐作为散列的一部分返回。因此,验证散列所需的所有信息都包含在其中。这允许 password_verify() 函数验证散列而无需单独存储用于盐或算法信息。”这两个函数的文档页面都提到了这一点。 -
@IanDrake 显然是我的误解;有时我们都需要一个好的 RTFM 时刻 ;-)
-
@MattM 一般来说,是的,我会选择
PASSWORD_DEFAULT。除非您的系统有某种特殊要求,否则它将有助于使您的代码更加“面向未来”。文档页面上的这条评论重申了这一理念:php.net/manual/en/function.password-hash.php#112495。另外,我以前使用过那个库,我可以确认它可以使用PASSWORD_DEFAULT常量,所以我认为这不是问题。
标签: php mysql mysqli xss sql-injection