サーチ…


文字列として提供されたSQL文を実行する

場合によっては、stringに配置されたSQLクエリを実行する必要があります。 EXEC、EXECUTE、またはシステム・プロシージャsp_executesqlは、stringとして指定されたSQL問合せを実行できます。

sp_executesql N'SELECT * FROM sys.objects'
-- or
sp_executesql @stmt = N'SELECT * FROM sys.objects'
-- or
EXEC sp_executesql N'SELECT * FROM sys.objects'
-- or
EXEC('SELECT * FROM sys.columns')
-- or
EXECUTE('SELECT * FROM sys.tables')

このプロシージャは、文のテキストとして提供されるSQL問合せと同じ結果セットを戻します。 sp_executesqlは、文字列リテラル、変数/パラメータ、または偶数式として提供されるSQLクエリを実行できます。

declare @table nvarchar(40) = N'product items'
EXEC(N'SELECT * FROM ' + @table)
declare @sql nvarchar(40) = N'SELECT * FROM ' + QUOTENAME(@table);
EXEC sp_executesql @sql

@table変数の特殊文字をエスケープするには、QUOTENAME関数が必要です。 @table変数にスペース、角かっこなどの特殊文字が含まれていると、この関数がなければ構文エラーが発生します。

異なるユーザーとして実行される動的SQL

AS USER = 'データベースユーザーの名前'を使用して、異なるユーザーとしてSQLクエリを実行できます。

EXEC(N'SELECT * FROM product') AS USER = 'dbo'

SQLクエリはdboデータベースユーザーの下で実行されます。 dboユーザーに適用されるすべての権限チェックは、SQLクエリでチェックされます。

動的SQLを使用したSQLインジェクション

動的クエリは

SET @sql = N'SELECT COUNT(*) FROM AppUsers WHERE Username = ''' + @user + ''' AND Password = ''' + @pass + ''''
EXEC(@sql)

ユーザー変数の値がmyusername '' OR 1 = 1 - の場合 、次のクエリが実行されます。

SELECT COUNT(*)
FROM AppUsers 
WHERE Username = 'myusername' OR 1=1 --' AND Password = ''

変数@usernameの値の最後にあるコメントは、クエリの後続部分をコメントアウトし、条件1 = 1が評価されます。このクエリによって返された少なくとも1人のユーザーがそこをチェックするアプリケーションは、0より大きいカウントを返し、ログインは成功します。

この方法を使用すると、攻撃者は有効なユーザー名とパスワードを知らなくてもアプリケーションにログインできます。

パラメータを使用した動的SQL

注入やエスケープの問題を避けるために、動的SQLクエリは次のようなパラメータで実行する必要があります。

SET @sql = N'SELECT COUNT(*) FROM AppUsers WHERE Username = @user AND Password = @pass
EXEC sp_executesql @sql, '@user nvarchar(50), @pass nvarchar(50)', @username, @password

2番目のパラメータは、そのタイプでクエリで使用されるパラメータのリストです。このリストには、パラメータ値として使用される変数が提供されています。

sp_executesqlは特殊文字をエスケープし、SQLクエリを実行します。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow