我可以通过使用存储过程而不是查询来避免 SQL 注入吗?
Am I safe from SQL Injection by using a stored procedure instead of query?
这里是新手。我一直在研究 SQLSVR 如何利用准备好的语句来防止注入,但它们所防止的通常是查询本身,而不是存储过程之类的东西。我当前的代码是否安全?
我一直在努力理解这里的 PHP 手册:https://www.php.net/manual/en/function.sqlsrv-query.php 但我不确定这会是什么样子,因为我使用的是存储过程。
感谢您花时间阅读本文并提供指导。
<?php
include('config.php');
$mysqli = sqlsrv_connect($serverName, $conn_array);
// For error or success messages place the following functions in your functions.php file and include the file here.
// The following functions are based on bootstrap classes for error and success message. If you are not using bootstrap you can stylize your own.
function alertSuccess($msg){
$alert = "<div class='alert alert-success'>".$msg."</div>";
return $alert;
}
function alertError($msg){
$alert = "<div class='alert alert-danger'>".$msg."</div>";
return $alert;
}
function alertInfo($msg){
$alert = "<div class='alert alert-info'>".$msg."</div>";
return $alert;
}
// Storing Form Inputs
$username = ($_POST['username']);
$email = ($_POST['email']);
$region =($_POST['region']);
$password = (!empty($_POST['password']))?$_POST['password']:null;
$password2 = (!empty($_POST['confirmpassword']))?$_POST['confirmpassword']:null;
if(isset($_POST['register'])) {
// Set "Creating Account" message.
echo alertInfo("Attempting to initiate Account Creation...");
// If username is null then rest of the code will not be executed
if($username == null){
echo alertError("Invalid username!");
header("Location: failed.php");
exit();
}
// If password is not equal then rest of the code will not be executed
if($password != $password2){
echo alertError("Password mismatch");
header("Location: failed.php");
exit();
}
// If username is less than 6 characters long then rest of the code will not be executed
if(strlen($username) < 6){
echo alertError("Username must contain at least 6 characters.");
header("Location: failed.php");
exit();
}
if($region > 2){
echo alertError("Invalid Region.");
header("Location: failed.php");
exit();
}
// All checks done already (including password check). Now process the query.
$password = $password;
$sql = "SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_WARNINGS ON
SET ANSI_PADDING ON
exec membership.dbo.CreateAccount '$username','$password','$email', '$region'
";
if(sqlsrv_query($mysqli, $sql)){
echo alertSuccess("Registration Successful! Please wait....");
header("Location: info.php");
exit();
}else{
echo alertError("Sorry, something went wrong! Please refresh the page and try again.");
}
}
挖掘了一下。答案是否定的,如果使用动态 SQL.
存储过程是不安全的
通过阅读手册几千遍,我能够使用准备好的语句。
这里是新手。我一直在研究 SQLSVR 如何利用准备好的语句来防止注入,但它们所防止的通常是查询本身,而不是存储过程之类的东西。我当前的代码是否安全?
我一直在努力理解这里的 PHP 手册:https://www.php.net/manual/en/function.sqlsrv-query.php 但我不确定这会是什么样子,因为我使用的是存储过程。
感谢您花时间阅读本文并提供指导。
<?php
include('config.php');
$mysqli = sqlsrv_connect($serverName, $conn_array);
// For error or success messages place the following functions in your functions.php file and include the file here.
// The following functions are based on bootstrap classes for error and success message. If you are not using bootstrap you can stylize your own.
function alertSuccess($msg){
$alert = "<div class='alert alert-success'>".$msg."</div>";
return $alert;
}
function alertError($msg){
$alert = "<div class='alert alert-danger'>".$msg."</div>";
return $alert;
}
function alertInfo($msg){
$alert = "<div class='alert alert-info'>".$msg."</div>";
return $alert;
}
// Storing Form Inputs
$username = ($_POST['username']);
$email = ($_POST['email']);
$region =($_POST['region']);
$password = (!empty($_POST['password']))?$_POST['password']:null;
$password2 = (!empty($_POST['confirmpassword']))?$_POST['confirmpassword']:null;
if(isset($_POST['register'])) {
// Set "Creating Account" message.
echo alertInfo("Attempting to initiate Account Creation...");
// If username is null then rest of the code will not be executed
if($username == null){
echo alertError("Invalid username!");
header("Location: failed.php");
exit();
}
// If password is not equal then rest of the code will not be executed
if($password != $password2){
echo alertError("Password mismatch");
header("Location: failed.php");
exit();
}
// If username is less than 6 characters long then rest of the code will not be executed
if(strlen($username) < 6){
echo alertError("Username must contain at least 6 characters.");
header("Location: failed.php");
exit();
}
if($region > 2){
echo alertError("Invalid Region.");
header("Location: failed.php");
exit();
}
// All checks done already (including password check). Now process the query.
$password = $password;
$sql = "SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_WARNINGS ON
SET ANSI_PADDING ON
exec membership.dbo.CreateAccount '$username','$password','$email', '$region'
";
if(sqlsrv_query($mysqli, $sql)){
echo alertSuccess("Registration Successful! Please wait....");
header("Location: info.php");
exit();
}else{
echo alertError("Sorry, something went wrong! Please refresh the page and try again.");
}
}
挖掘了一下。答案是否定的,如果使用动态 SQL.
存储过程是不安全的通过阅读手册几千遍,我能够使用准备好的语句。