我正在编写一些单元测试,以确保我的代码在各种字符集下不易受SQL注入攻击.
根据这个答案,你可以通过注入创建一个漏洞\xbf\x27使用下列字符集之一:big5,cp932,gb2312,gbk和sjis
这是因为如果未正确配置您的escaper,它将会看到0x27并尝试将其转义为它\xbf\x5c\x27.但是,\xbf\x5c实际上这些字符集中只有一个字符,因此quote(0x27)未被转义.
然而,正如我通过测试发现的那样,这并非完全正确.它的工作原理为big5,gb2312和gbk但也0xbf27还是0xbf5c在有效的字符sjis和cp932.
都
mb_strpos("abc\xbf\x27def","'",0,'sjis')
Run Code Online (Sandbox Code Playgroud)
和
mb_strpos("abc\xbf\x27def","'",0,'cp932')
Run Code Online (Sandbox Code Playgroud)
返回4.即,PHP不会将其\xbf\x27视为单个字符.这将返回false了big5,gb2312和gbk.
这个:
mb_strlen("\xbf\x5c",'sjis')
Run Code Online (Sandbox Code Playgroud)
返回2(返回1的gbk).
所以,问题是:是否有另一个字符序列,使sjis和cp932容易受到SQL注入,或者是他们居然不容易呢?或者是PHP撒谎,我完全错了,MySQL会完全不同地解释这个吗?
我正在学习避免SQL注入,我有点困惑.
使用bind_param时,我不明白其目的.在手册页上,我找到了这个例子:
$stmt = mysqli_prepare($link, "INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt, 'sssd', $code, $language, $official, $percent);
$code = 'DEU';
$language = 'Bavarian';
$official = "F";
$percent = 11.2;
Run Code Online (Sandbox Code Playgroud)
现在,假设这4个变量是用户输入的,我不明白这是如何阻止SQL注入的.根据我的理解,他们仍然可以在那里输入任何他们想要的东西.
我也找不到'sssd'那里的解释.它有什么作用?这是什么使它安全?
最后一个问题:我读到了另一个mysqli_real_escape_string被弃用的问题,但它没有在手册中说明.它是如何弃用的?由于某种原因,它不能再逃避特殊角色吗?
注意:这个问题解释了bind_param的作用,但我仍然不明白为什么它更安全或更受保护. Bind_param解释
我一直在发现这句话PHP PDO's prepared statements prevents SQL injection.
- php PDO(PDO准备好的语句)如何阻止sql注入?
- 使用PDO(PDO准备好的声明)的其他优缺点是什么?
- 使用PDO(PDO准备好的声明)会降低效率吗?
我已经读过:PDO准备好的语句是否足以阻止SQL注入? 但那里的数据并不完全清楚.
可能重复:
预处理语句如何防止SQL注入攻击?
对于我们这些刚接触PDO的人来说,我们认为它更安全,使用起来更好,但是我无法理解的是,这是如何安全的?
<?php
$db = new PDO('mysql:host=localhost;dbname=testdb;charset=UTF-8', 'username', 'password');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
try {
//connect as appropriate as above
$db->query('hi'); //invalid query!
} catch(PDOException $ex) {
echo "An Error occured!"; //user friendly message
some_logging_function($ex->getMessage());
}
foreach($db->query('SELECT * FROM table') as $row) {
echo $row['field1'].' '.$row['field2']; //etc...
}
?>
Run Code Online (Sandbox Code Playgroud)
请注意,我确实理解它的作用,但它究竟对消毒输入做了什么呢?我知道只mysql_*使用mysql_real_escape_string文字的用法\.PDO是否使用同一系统?如果没有,我们在卫生方面依赖什么?
使用预准备语句和mysqli_stmt_bind_param时是否仍存在注入风险?
例如:
$malicious_input = 'bob"; drop table users';
mysqli_stmt_bind_param($stmt, 's', $malicious_input);
Run Code Online (Sandbox Code Playgroud)
在幕后,mysqli_stmt_bind_param将此查询字符串传递给mysql:
SET @username = "bob"; drop table users";
Run Code Online (Sandbox Code Playgroud)
或者它是通过API执行SET命令,还是使用某种类型的保护来防止这种情况发生?
从安全验证的角度来看,两者之间是否存在差异:
stmt.setObject(1, theObject);
和
stmt.setString(1, theObject);?
我知道在这种情况下theObject是一个,String但我有兴趣使这部分代码更通用,以涵盖其他情况,并想知道输入验证的安全性角度是否受到影响
我看到很多人说你应该总是使用预准备语句进行数据库查询.但是,PHP文档说:
每个准备好的语句占用服务器资源.声明应在使用后立即明确关闭.如果没有显式完成,则在PHP释放语句句柄时将关闭该语句.
使用预准备语句并不总是执行语句的最有效方式.仅执行一次的预准备语句会导致客户端 - 服务器往返次数超过未准备好的语句.
来自http://php.net/manual/en/mysqli.quickstart.prepared-statements.php
鉴于上述情况,如果您只打算使用一次查询,那么最好不要使用预准备语句吗?
在PHP中,我发现了一些防止Sql Injection的方法。绑定参数是其中之一。但是我无法找到有关绑定参数实际上如何防止Sql Injection的完整说明。我的想法是,将参数绑定不同的数据到同一个Sql语句中,绑定参数可以节省时间。如何防止Sql注入?
我有这个有效:
sqlString = "SELECT * FROM employees WHERE lastname = '" & last_name & "'"
Set cmd = Server.CreateObject("ADODB.Command")
Set cmd.ActiveConnection = dbConn
cmd.CommandText = sqlString
cmd.Prepared = True
Set recs = cmd.Execute
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是在动态部分之上sqlString是在准备好的语句命令之前.我不认为我上面的东西在保护我.
在执行预准备语句之前,我不必修复此sqlString吗?阅读本文让我想到: 准备好的语句如何防止SQL注入攻击?:
"虽然在准备好的陈述中,我们不会改变我们的计划,但它仍然完好无损.这就是重点.
我们首先将程序发送到服务器
$db->prepare("SELECT * FROM users where id=?");
Run Code Online (Sandbox Code Playgroud)
数据被称为"占位符"的变量替换,然后我们分别发送数据:
$db->execute($data);
Run Code Online (Sandbox Code Playgroud)
所以,它不能改变我们的计划并造成任何伤害.很简单 - 不是吗?"
但我不知道如何使我的查询正确.我也不知道他是怎么prepare来的$data.希望得到指导.谢谢.
我有一个 Springboot 应用程序,它使用 Spring Data JPA 模块进行数据库操作。当我们扫描代码时,checkmarx 报告了许多有关 SQL_Injection 攻击的高和中评级问题。以下是用例之一,我需要帮助来确定是否将问题标记为误报。如果不是误报,我应该做什么来解决这个问题?
应用程序控制器.Java
@Controller
public class AppController
{
private static final Logger logger = LoggerFactory.getLogger(AppController.class);
@Autowired
private AppService appService;
@RequestMapping(value = "/propertiesHistory", method = RequestMethod.POST)
public String getPropertiesHistory(@ModelAttribute("propSearchForm") @Validated PropertiesSearch propertiesSearch, BindingResult result, Model model, final RedirectAttributes redirectAttributes)
{
String instanceName = propertiesSearch.getInstanceName();
if (!propertiesSearch.getInstanceName().equalsIgnoreCase("NONE"))
{
List<String> propVersionDates = appService.getPropertyHistoryDates(instanceName);
//Some Businees Logic
}
if (result.hasErrors())
{
logger.warn("getPropertiesHistory() : Binding error - " + result.getAllErrors());
}
else
{
//Some Businees Logic
} …Run Code Online (Sandbox Code Playgroud) 我用的方法是使用MySQLi插入数据吗?它有效,但足够安全吗?
$login = stripslashes($login);
$login = htmlspecialchars($login);
$password = stripslashes($password);
$password = htmlspecialchars($password);
$login = trim($login);
$password = trim($password);
$result2=mysqli_query($db,"INSERT INTO users (login,password) VALUES('$login','$password')");
Run Code Online (Sandbox Code Playgroud) php ×9
sql ×4
security ×3
java ×2
mysql ×2
mysqli ×2
pdo ×2
asp-classic ×1
checkmarx ×1
encoding ×1
jdbc ×1
sanitization ×1
spring ×1
spring-boot ×1
validation ×1