2016-09-06 5 views
4

私は、ユーザが自分自身のSQL文を入力することを許可していますが、それはSELECT文の場合に限ります。 SQL文がこれ以外のもの、つまりALTER、INSERT、DROPなどであるかどうかを検出する方法はありますか?私は、テーブルをロックするクエリなどの他の懸念について心配しますが、これは今すぐ概念の証明です。私は、アプリケーションを実行しているサーバー上のサービスアカウントをdbに対して読み取り専用権限に制限することができますが、アプリで処理されていることに興味があります。非SELECT SQL文の防止

これは私のアプローチでは、クエリの最初の単語を検出することによって、これは脆弱です。この検出を行うためのよりクリーンな方法がありますか?

public void ExecuteQuery(string connectionString, int id) 
{ 
    //The SQL statement will be user input 
    var sql = "SELECT ColumnA, ColumnB, ColumnC FROM MyTable where MyTableId = @Id"; 
    var split = sql.Split(' '); 

    if (split[0].ToUpper() != "SELECT") Console.WriteLine("Only use a SELECT statement."); 
    else 
    { 
     using (var connection = new SqlConnection(connectionString)) 
     using (var cmd = new SqlCommand(sql, connection)) 
     { 
      cmd.Parameters.AddWithValue("@Id", SqlDbType.Int); 
      cmd.Parameters["@Id"].Value = id; 
      connection.Open(); 

      var reader = cmd.ExecuteReader(); 
      try 
      { 
       while (reader.Read()) 
       { 
        Console.WriteLine($"{reader["ColumnA"]}, {reader["ColumnB"]}, 
             {reader["ColumnC"]}"); 
       } 
      } 
      finally 
      { 
       reader.Close(); 
      } 

      cmd.ExecuteNonQuery(); 
     } 
    } 
} 
+2

「TransactionScope」にすべてのものをラップし、決してコミットしないようにすることで、どんなDMLでもロールバックされます。 – Crowcoder

+5

SQL Serverのユーザー権限を管理できますか?どのアカウントでもSQLを実行しているため、SELECT権限のみを付与する必要があります。私はこれが、あなたの提案されたソリューションまたは "コード"ベースのソリューションに対する推奨ソリューションだと思います。 – SimonGates

+0

なぜユーザーは自分のSQL文を作成できるのですか?これは本当に悪い考えです。 sys.columns、sys.columns、sys.columnsから*を選択すると、システム全体が何時間も不自由な状態になります。私にとっては、概念の証明は、SQLデータベースの近くのどこでもこのタイプのアプリケーションを許可しない理由です。 –

答えて

2

これをアプリケーションコードで管理しようとする試みを取り除きます。代わりにSQL Serverを使用します。

物事を管理するための良い方法は、以下を行うことです。

  1. 新しいスキーマを作成します。
  2. データベースロールを作成します。ロールはスキーマを所有する必要があります。
  3. 公開するビューを1:1にしても、スキーマに表示する必要があります。
  4. ロールにサービスアカウントを追加します。

サービスアカウントはビューからのみ選択でき、公開するものと選択できるデータを完全に制御できます。

これは、他の開発者やDBAの場合でも、簡単に検索/監査可能です。また、スキーマの変更による影響を把握することもできます。

+0

これは書かれたとおりに動作しません。ロールがスキーマを所有していて、他の誰かが基本オブジェクトを所有している場合は、所有権チェーンが壊れてしまい、依然として基本オブジェクトに権限が必要になります。 –

+0

これはコードとより良いアプローチでそれを扱わない方法なので、これを受け入れます。パーミッションを少し違って管理しますが、これはアプリ内アプリより優先されます。ありがとう! –