SQLインジェクション攻撃を防ぐために、asp.netのグリッドビュー行のハイパーリンク選択から渡されるクエリ文字列値を暗号化したい。UrlRewritingメソッドまたはEncryptionメソッドでその作業を行うことに興味があります。どちらの方法を使用するのが良いですか?どうやってするか?
3 に答える
次のコードは、「firstName = stephen&surname=oberauer」を「arg=x2lk1rkBmXvilYTzLpfm5E9tkYSzEZnSkl7se0hNP0HsXbD82OYfiA==」に変換して元に戻します。
これが単純な暗号化/復号化クラスです(必ず独自のキーを使用してください)
public static class Crypt
{
// Must be random
private static readonly byte[] key = new byte[24] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4 };
public static string Encrypt(string input)
{
byte[] inputArray = UTF8Encoding.UTF8.GetBytes(input);
TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider();
tripleDES.GenerateKey();
tripleDES.Key = key;
tripleDES.Mode = CipherMode.ECB;
tripleDES.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tripleDES.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
tripleDES.Clear();
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
public static string Decrypt(string input)
{
byte[] inputArray = Convert.FromBase64String(input);
TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider();
tripleDES.Key = key;
tripleDES.Mode = CipherMode.ECB;
tripleDES.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tripleDES.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
tripleDES.Clear();
return UTF8Encoding.UTF8.GetString(resultArray);
}
}
次のようなグリッドビューがあると仮定します。
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:HyperLinkField DataNavigateUrlFields="Url" DataTextField="Name" />
</Columns>
</asp:GridView>
グリッドデータは次のように設定できます。
var gridData = new[]
{
new { Name = "Link 1", Url = "TargetPage.aspx?arg=" + Crypt.Encrypt("firstName=stephen&surname=oberauer") },
new { Name = "Link 2", Url = "TargetPage.aspx?arg=" + Crypt.Encrypt("firstName=joe&surname=smith") }
};
GridView1.DataSource = gridData;
GridView1.DataBind();
ターゲットページでは、次のように暗号化されたクエリ文字列をデコードできます。
var encryptedArgs = Request.QueryString["arg"];
var decryptedArgs = HttpUtility.ParseQueryString(Crypt.Decrypt(encryptedArgs));
FirstName.Text = decryptedArgs["firstName"];
Surname.Text = decryptedArgs["surname"];
クエリ文字列が改ざんされていないことを確認するために、Decryptメソッドによって発生したFormatExceptionを処理し、引数(この場合は「firstName」と「surname」)が存在することを確認するためにテストできます。
URLの書き換えは別の問題であり、URLをより美しくしたい場合に使用できます。クエリ文字列をだれもいじらないようにすることとは、実際にはあまり関係がありません。
複雑にする理由は、行のデータバインドイベントを使用してURIを設定し、クエリ文字列パラメーターを変換してServer.UrlEncodeを使用することで、準備が整います。
RowDataBoundEvent
protected void YourGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
try
{
if (e.Row.RowType != DataControlRowType.DataRow) return;
if (e.Row.DataItem == null) return;
var hlobj= e.Row.FindControl("HYPERLINKID") as HyperLink;
if ( null == hlViewTest) return;
hlobj.NavigateUrl = String.Format("--------.aspx?whatever={0}",
Server.UrlEncode(Encrypt(whatever)));
}
catch (Exception ex)
{
//
}
}
暗号化方式:.........。
private static string Encrypt(String val)
{
try
{
var bytes = Encoding.UTF8.GetBytes(val.ToString(CultureInfo.InvariantCulture));
var encBytes = ProtectedData.Protect(bytes, new byte[0], DataProtectionScope.LocalMachine);
return Convert.ToBase64String(encBytes);
}
catch (Exception ex)
{
return String.Empty;
}
}
復号化方法:------------
private static string Decrypt(string val)
{
try
{
var bytes = Convert.FromBase64String(val);
var encBytes = ProtectedData.Unprotect(bytes, new byte[0], DataProtectionScope.LocalMachine);
return System.Text.Encoding.UTF8.GetString(encBytes);
}
catch (Exception ex)
{
return String.Empty;
}
}
他のページでは、次のように使用します.........
var decryptedString=Decrypt(Request["YOUR PASSING ID"] || Request.QueryString["YOUR PASSING ID"]));
1つのアプローチは、渡すIDごとにGUIDを作成し、バックエンドのどこかにあるディクショナリで追跡を続けることです。したがって、クエリ文字列でGuidを渡し、辞書を使用して通常のIDに「デコード」します。
ただし、これは「隠すことによるセキュリティ」であるため、受信ページで認証チェックを実行する必要があります(クエリ文字列をいじらないようにするためです。もちろん、GUIDの権利を推測する可能性は、落雷に見舞われるよりもおそらく小さいでしょう。 、それでも確認する必要があります)。