输入验证与表示问题是由元字符、交替编码和数字表示引起的。安全问题源于信任输入。这些问题包括:“Buffer Overflows”、“Cross-Site Scripting”攻击、“SQL Injection”等其他问题。
owner
与被授予权限的当前用户一致的条目。
...
string userName = ctx.GetAuthenticatedUserName();
string query = "SELECT * FROM items WHERE owner = '"
+ userName + "' AND itemname = '"
+ ItemName.Text + "'";
List items = sess.CreateSQLQuery(query).List();
...
SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;
ItemName
不包含单引号字符时,才会正确执行这一查询。如果一个用户名为 wiley
的攻击者为 ItemName
输入字符串“name' OR 'a'='a
”,那么查询就会变成:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';
OR 'a'='a'
会使 where 从句永远评估为 true,因此该查询在逻辑上将等同于一个更为简化的查询:
SELECT * FROM items;
items
表中的所有条目,而不论其指定所有者是谁。Example 1
.中构造和执行的查询所带来的影响。如果一个用户名为 wiley
的攻击者为 ItemName
输入字符串“name'; DELETE FROM items; --
”,则该查询就会变为以下两个查询:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
--'
Example 1
.中所用的技巧进行攻击。如果攻击者输入字符串“name'; DELETE FROM items; SELECT * FROM items WHERE 'a'='a
”,将创建以下三个有效语句:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
SELECT * FROM items WHERE 'a'='a';
owner
与当前经过身份验证的用户的名称一致的条目。
...
string userName = identity.User;
string itemName = apiGatewayProxyRequest.QueryStringParameters['item'];
string statement = $"SELECT * FROM items WHERE owner = '{userName}' AND itemname = '{itemName}'";
var executeStatementRequest = new ExecuteStatementRequest();
executeStatementRequest.Statement = statement;
var executeStatementResponse = await dynamoDBClient.ExecuteStatementAsync(executeStatementRequest);
return displayResults(executeStatementResponse.Items);
...
SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;
itemName
不包含单引号字符时,该查询才能正常运行。如果一个用户名为 wiley
的攻击者为 itemName
输入字符串“name' OR 'a'='a
”,则该查询会变成:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';
OR 'a'='a'
,where 子句的值将始终为 true,这样该查询在逻辑上就等同于一个更为简单的查询:owner
与当前经过身份验证的用户的名称一致的条目。
...
String userName = identity.getUser();
String itemName = apiGatewayProxyRequest.getQueryStringParameters('item');
String statement = String.format("SELECT * FROM items WHERE owner = '%s' AND itemname = '%s'", userName, itemName);
ExecuteStatementRequest executeStatementRequest = new ExecuteStatementRequest();
executeStatementRequest.setStatement(statement);
ExecuteStatementResponse executeStatementResponse = dynamoDBClient.executeStatement(executeStatementRequest);
return displayResults(executeStatementResponse.items());
...
SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;
itemName
不包含单引号字符时,该查询才能正常运行。如果一个用户名为 wiley
的攻击者为 itemName
输入字符串“name' OR 'a'='a
”,则该查询会变成:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';
OR 'a'='a'
,where 子句的值将始终为 true,这样该查询在逻辑上就等同于一个更为简单的查询:
...
String userName = ctx.getAuthenticatedUserName();
String itemName = request.getParameter("itemName");
String query = "SELECT * FROM items WHERE owner = '"
+ userName + "' AND itemname = '"
+ itemName + "'";
ResultSet rs = stmt.execute(query);
...
SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;
itemName
不包含单引号字符时,才会正确执行这一查询。如果一个用户名为 wiley
的攻击者为 itemName
输入字符串“name' OR 'a'='a
”,那么查询就会变成:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';
OR 'a'='a'
会使 where 从句永远评估为 true,因此该查询在逻辑上将等同于一个更为简化的查询:
SELECT * FROM items;
items
表中的所有条目,而不论其指定所有者是谁。Example 1
.中构造和执行的查询所带来的影响。如果一个用户名为 wiley
的攻击者为 itemName
输入字符串“name'; DELETE FROM items; --
”,则该查询就会变为以下两个查询:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
--'
Example 1
中所用的技巧进行攻击。如果攻击者输入字符串“name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a
”,将创建以下三个有效语句:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
SELECT * FROM items WHERE 'a'='a';
Example 1
以适应 Android 平台。
...
PasswordAuthentication pa = authenticator.getPasswordAuthentication();
String userName = pa.getUserName();
String itemName = this.getIntent().getExtras().getString("itemName");
String query = "SELECT * FROM items WHERE owner = '"
+ userName + "' AND itemname = '"
+ itemName + "'";
SQLiteDatabase db = this.openOrCreateDatabase("DB", MODE_PRIVATE, null);
Cursor c = db.rawQuery(query, null);
...
mysql_real_escape_string()
等编码函数可避免一部分 SQL Injection 漏洞,但不能完全避免。依靠此类编码函数等同于用一个安全性较差的拒绝列表来防止 SQL Injection 攻击,并且可能允许攻击者修改语句的含义或者执行任意 SQL 命令。由于在动态解释代码的给定部分中不可能总是静态确定输入显示的位置,因此 Fortify 安全编码规则包可能会将经过验证的动态 SQL 数据显示为“SQL Injection: Poor Validation”问题,即使验证可能足以防止在该上下文中出现 SQL Injection 攻击时也是如此。mysqli_real_escape_string()
的行为。 将 SQL 模式设置为“NO_BACKSLASH_ESCAPES” 时,反斜杠字符会被视为正常字符,而不是转移字符[5]。 由于 mysqli_real_escape_string()
将此情况考虑在内,因此鉴于数据库配置,当 "
不再转义为 \"
时,以下查询易受到 SQL Injection 的攻击。
mysqli_query($mysqli, 'SET SQL_MODE="NO_BACKSLASH_ESCAPES"');
...
$userName = mysqli_real_escape_string($mysqli, $_POST['userName']);
$pass = mysqli_real_escape_string($mysqli, $_POST['pass']);
$query = 'SELECT * FROM users WHERE userName="' . $userName . '"AND pass="' . $pass. '";';
$result = mysqli_query($mysqli, $query);
...
password
字段留空并为 userName
输入 " OR 1=1;--
,则不对引号进行转义,最后的查询如下所示:
SELECT * FROM users
WHERE userName = ""
OR 1=1;
-- "AND pass="";
OR 1=1
会导致 where 子句的值始终为 true 且双连字符会导致剩余语句被视为注释,因此该查询在逻辑上就等同于一个更为简单的查询:
SELECT * FROM users;
owner
与被授予权限的当前用户一致的条目。
...
string userName = ctx.getAuthenticatedUserName();
string query = "SELECT * FROM items WHERE owner = '"
+ userName + "' AND itemname = '"
+ ItemName.Text + "'";
IDataReader responseReader = new InlineQuery().ExecuteReader(query);
...
SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;
itemName
不包含单引号字符时,才会正确执行这一查询。如果一个用户名为 wiley
的攻击者为 itemName
输入字符串“name' OR 'a'='a
”,那么查询就会变成:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';
OR 'a'='a'
会使 where 从句永远评估为 true,因此该查询在逻辑上将等同于一个更为简化的查询:
SELECT * FROM items;
items
表中的所有条目,而不论其指定所有者是谁。Example 1
.中构造和执行的查询所带来的影响。如果一个用户名为 wiley
的攻击者为 itemName
输入字符串“name'); DELETE FROM items; --
”,则该查询就会变为以下两个查询:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
--'
Example 1
.中所用的技巧进行攻击。如果攻击者输入字符串“name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a
”,将创建以下三个有效语句:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
SELECT * FROM items WHERE 'a'='a';