ŚℇℒℇℂƮ;ŚℇℒℇℂƮ*:Unicode象形文字将如何破坏您的自定义SQL注入清理功能...

Niketh Vellanki Unsplash 拍摄的 照片

在过去的几周中,我一直在撰写有关如何保护数据库免受SQL注入攻击的文章 。 今天,我们将通过研究隐式unicode转换如何使您的数据易受攻击来保持趋势。

您也可以在我的 YouTube 频道 上观看此内容

什么是象形文字?

同源字符是看起来像另一个字符的字符。 l(小写字母“ L”)和1(数字)被视为单字形。 O(字母)和0(数字)也是如此。

同形异义字可以存在于字符集中(例如上述拉丁字符集示例),也可以存在字符集之间 。 例如,您可能有Unicode撇号ʼ,它是拉丁单引号字符'的同形符号。

SQL Server如何处理Unicode象形文字?

你应该问有趣。 如果将Unicode字符传递给非Unicode数据类型(如char),则SQL会将Unicode字符隐式转换为与其最相似的非Unicode象形文字。

为了了解这一点,我们可以使用上例中的Unicode撇号:

SELECT
CAST(N'ʼ' AS nchar) AS UnicodeChar,
CAST(N'ʼ' AS char) AS NonUnicodeChar

您可以在第二列中看到SQL自动将撇号转换为单引号:

尽管这种隐式字符转换可以方便地显示非Unicode字符集中的Unicode字符,但对于SQL Server 安全性却可能造成灾难。

Unicode象形文字SQL注入

如果在构建动态SQL查询时已经在使用sp_executesqlQUOTENAME() ,则可以避免这种SQL注入。

知道当拥有上述可靠,安全和经过测试的功能时,您不是那种会编写自己的安全功能的人。 但是,仅此一次,让我们假装您认为您可以编写自己的引号分隔代码来胜过黑客。

使用与上周相同的数据集 ,让我们创建一个新的存储过程,该过程将从用户的配置文件中返回一些数据:

DROP PROCEDURE IF EXISTS dbo.GetProfile
GO
CREATE PROCEDURE dbo.GetProfile
@Username nvarchar(100)
AS
BEGIN
-- Add quotes to escape injection...or not?
SET @Username = REPLACE( @Username , '''','''''')
DECLARE @Query varchar(max)
SET @Query = 'SELECT 
FullName,
JoinDate
FROM
dbo.RegisteredUser
WHERE
UserName = ''' + @Username + '''
'
EXEC( @Query )
END
GO

代替使用sp_executesql或QUOTENAME(),让我们尝试编写自己的巧妙的REPLACE()函数,该函数将用两套单引号替换单引号。 从理论上讲,这应该防止SQL注入。

如果我们测试SQL注入的“正常”尝试,您会注意到此逻辑很好用。 拍拍自己的背部!

但是,如果我们将Unicode撇号传递给……:

发生这种情况的原因是因为我们将@Query参数声明为varchar而不是unicode nvarchar。 当我们构建动态SQL语句时,SQL 会将 nvarchar @Username参数隐式转换为非Unicode varchar:

因此,如果我替换撇号,那会使我安全吗?

没有。

我知道,黑名单/替换Unicode撇号似乎可以解决我们所有的问题。

而且它将……仅在这种情况下。 但是,除了单引号之外,还有更多的同名同音字。

出于好奇,我编写了一个脚本来搜索Unicode字符空间,以查看还存在其他同形文字:

DECLARE @FirstNumber INT=0;
-- number of possible characters in the unicode space
DECLARE @LastNumber INT=1114112;

WITH Numbers AS (
SELECT @FirstNumber AS n
UNION ALL
SELECT n+1 FROM Numbers WHERE n+1<= @LastNumber
), UnicodeConversion AS (
SELECT
n AS CharacterNumber,
CASE CAST(NCHAR(n) as CHAR(1))
WHEN '''' THEN NCHAR(n)
WHEN ';' THEN NCHAR(n)
END AS UnicodeCharacter,
CAST(NCHAR(n) as CHAR(1)) AS ASCIICharacter
FROM Numbers
)
SELECT
*
FROM
UnicodeConversion
WHERE
UnicodeCharacter IS NOT NULL
OPTION (MAXRECURSION 0)

尽管上面的屏幕截图中的字符看起来很相似,但它们实际上是同形文字。

我决定只搜索单引号和分号,因为它们经常在SQL注入攻击中使用,但这绝不是要列入黑名单的所有字符的详尽列表。

要把所有危险的象形文字都可靠地列入黑名单不仅非常困难,而且还要一直在Unicode中添加新字符,因此维护黑名单将是一场噩梦。 特别是如果将来维护此代码的人员对这些类型的注入攻击不熟悉。

并且不要厚​​颜无耻地认为您也可以过滤掉危险的SQL关键字-即使您替换(@ Username,'SELECT',”),也要记住有人可以通过并传递“ŚεℒℇℂƮ”之类的值。

结论

不要编写自己的安全功能-它们会失败。

防止SQL注入的最佳方法是不使用动态SQL。 如果必须使用动态SQL,请使用sp_executesql和QUOTENAME()。

您可能还喜欢 在Twitter上关注我

From: https://hackernoon.com/ʼ-śℇℒℇℂʈ-how-unicode-homoglyphs-will-break-your-custom-sql-injection-sanitizing-functions-1224377f7b51

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值