I need to use query strings in a URL, but need to ensure that they haven't been tampered with. I found a solution which almost works, but the encoded strings get mangled by a service my app needs to use. Can anyone think of a different solution?
EDIT: The solution I mention doesn't work for me because the Base64 encoded query string it produces contains "+". The servic开发者_运维问答e I pass this query string to doesn't properly handle "+", and I can't even URL encode it to "%2B". I can substitute "_" for it, I suppose. However, I was wondering if there was a different solution entirely.
EDIT 2: To be more clear, the solution I reference works, but I was wondering about alternative solutions.
you can encrypt your querystring value and then pass it and where you want to use, simply decrypt it. Also check these articles... how-to-encrypt-query-string-parameters-in-asp-net
http://www.codeproject.com/KB/web-security/QueryStringEncryptionNET.aspx
Basically a duplicate of: Security with QueryString values in Asp.net MVC
Bottom line - never trust input from the user especially over the web, always assume a user can and will tamper with the inputs.
You can compute and pass a hash of your parameters along with your querystring. On your landing page, compute the hash again and compare it with the query string hash, if both are not same it means the URL is tampered.
You can make functions inside a utility class like
const string secretKey = "%%YoUrSeCrEtKeY##";
public static string CreateTamperProofUrl(string pageUrl)
{
try
{
return HttpUtility.UrlEncode(CreateDigest(pageUrl.Trim()));
}
catch (Exception)
{
throw;
}
}
private static string CreateDigest(string pageUrl)
{
string urlToEncode = secretKey + pageUrl + secretKey;
var hasher = new MD5CryptoServiceProvider();
var encoder = new UTF8Encoding();
byte[] hashedDataBytes = hasher.ComputeHash(encoder.GetBytes(urlToEncode));
string signatureData = Convert.ToBase64String(hashedDataBytes);
return signatureData;
}
public static bool IsValidDigest(string pageUrl, string receivedDigest)
{
if (receivedDigest == null)
{
return false;
}
string expectedDigest = CreateDigest(pageUrl);
if (string.Compare(receivedDigest, expectedDigest) != 0)
{
return false;
}
else
return true;
}
On your landing page just check like this
if (!Page.IsPostBack)
{
if (Request.QueryString["Digest"] != null)
{
// compare the digest
string id = Request.QueryString["fid"];
string digest = Request.QueryString["Digest"];
if (Utility.IsValidDigest(id, digest))
{
lblStatus.ForeColor = System.Drawing.Color.DarkGreen;
lblStatus.Text = "Valid digest received";
}
else
{
lblStatus.ForeColor = System.Drawing.Color.Red;
lblStatus.Text = "Url is tampered!";
}
}
}
精彩评论