应该在用户名框中输入什么来对以下代码执行sqlinject攻击?我应该如何降低这种风险?



我知道我需要加盐哈希,我只是好奇sqlinject攻击将如何针对此执行,我想降低风险

if (username && password) {
db.get(`SELECT * FROM users WHERE username = ? AND password = ?`, [username, hashString], (err, row) => {
if (err) {
console.error(err);
} else {
if (row) {
console.log('Login sucessful');
console.log('username input: ' + username + ' password input: ' + password + ' hash of password: ' + hashString);
console.log(row);
response.redirect('/index.html');
} else {
console.log('username input: ' + username + ' password input: ' + password + ' hash of password: ' + hashString);
console.log(row);
console.log('Invalid username or password');

response.redirect('/login.html');
response.end();
}
}
});
} else {
response.send('Please enter a username and password!');
response.end();
}
});

我尝试在用户名和密码槽中添加一些sql命令。密码框中没有任何变化,因为它在插入sql命令

之前已经被散列了

代码似乎使用了参数化查询,这有助于防止SQL注入攻击。然而,代码中的一个潜在风险是hashString参数没有在提供的代码片段中定义,因此不清楚它是如何生成的。如果它是以不安全的方式生成的,它可能被攻击者操纵来执行SQL注入攻击。

例子可以通过输入包含SQL代码的用户名和密码组合来尝试SQL注入攻击。例如,攻击者可以输入以下输入作为密码:

password' OR 1=1 --

这个输入将导致SQL查询的计算如下:

SELECT * FROM users WHERE username = 'username' AND password = 'password' OR 1=1 --'

输入末尾的双破折号在SQL中是一个注释标记,它导致查询的其余部分被忽略。OR 1=1条件始终为真,这意味着查询将返回users表中的所有行,从而允许攻击者在没有有效密码的情况下登录。

迁移此风险

为了降低这种风险,建议确保SQL查询中使用的任何输入参数在使用之前都经过适当的清理和验证。此外,建议对准备好的语句使用参数化查询,以防止SQL注入攻击。

基于hashString的评论更新

使用SHA-512散列密码不会直接增加SQL注入攻击的风险。

然而,与bcryptscryptArgon2等专用密码散列算法相比,使用SHA-512进行密码散列的安全性较差。它没有提供足够的保护来防止暴力攻击,也没有为每个用户提供唯一的盐,这使得它很容易受到预先计算的散列密码表(如彩虹表)的攻击。

这与你最初的问题无关,但很重要,所以这里有一个快速的例子。如果这对你来说很重要,我建议你考虑一下如何在你的代码库中实现它。

const bcrypt = require('bcrypt');const saltround = 10;//该值决定了"成本";哈希算法。值越高意味着需要更多的计算能力来散列和验证密码,这通常更安全。您可以根据需要调整此值。

npm install bcrypt
# or
yarn add bcrypt
// Hash a password (saltRounds is kind of the "cost" or "work factor")
bcrypt.hash(password, saltRounds, (err, hash) => {
if (err) {
console.error(err);
} else {
// Save the hashed password to the database
}
});
// Verify a password
bcrypt.compare(password, hash, (err, result) => {
if (err) {
console.error(err);
} else {
// If 'result' is true, the password is correct.
}
});

概念

这个概念很简单,它可以归结为核心的SQL查询。这些都是需要记住的事情:

  • '——'表示注释。
  • 是必需的,取决于你把它放在哪里。

现在回答问题:

SELECT * FROM users WHERE username =? AND password =?

上面是SQL查询,问号是输入的端点。而且没有适当的卫生设施。因此,要对服务器进行操作,我们必须注释掉check特性,并且查询必须返回true。

'--:将在用户名部分注入

结果如下:

SELECT * FROM users WHERE username =''-- AND password =?

结果将像密码部分将被注释并且检查将被忽略。

让我们稍微改变一下,将有效载荷设置为:'1=1--

现在,这将是最后的查询:SELECT * FROM users WHERE username =''1=1 -- AND password =?

现在1=1为True,这是通用的,因此"将不返回任何内容,1=1将返回True,密码部分被忽略,登录成功被绕过。

预防

对于预防,有两种方法可以很好地协同工作,它们是:

杀毒软件
  • WAF

在正常应用程序上使用WAF是不合适的,但使用消毒是有效的。WAF的运作方式是一旦检测到此类攻击就阻止它们,但消毒程序严格禁止某些输入。

Python中的基本清理代码:

import re

def s_u(username):
# Remove any characters that are not letters, numbers, or underscores
sanitized_username = re.sub(r'[^w]', '', username)
# Remove any leading or trailing spaces
sanitized_username = sanitized_username.strip()
return sanitized_username


def s_p(password):
# Remove any characters that are not letters, numbers, or underscores
sanitized_username = re.sub(r'[^w]', '', username)
# Remove any leading or trailing spaces
sanitized_password = password.strip()
return sanitized_password

上面的代码块字符,如',-[]等,因为这些是注入此类攻击最常用的代码。根据您的使用情况,您可以操作它以使用额外或不使用额外字符,但越干净越好。

最新更新