透過 IsLocalUrl 來過濾 Path ,是否可以避掉 Open Redirect issue呢?
在前一篇之中「Open Redirect」,針對這問題就是使用白名單來Filter!
protected void Button1_Click(object sender, EventArgs e)
{
string funcUrl = "WebForm2.aspx?";
string funQueryString = "para=" + HttpUtility.UrlEncode(txtParam.Text);
string validateUrl = funcUrl + funQueryString;
Response.Redirect(validateUrl);
}
有參考「Preventing Open Redirection Attacks」使用 IsLocalUrl 去限定,然而 Tool 似乎還是不接受!
private bool IsLocalUrl(string url)
{
if (string.IsNullOrEmpty(url))
{
return false;
}
else
{
return ((url[0] == '/' && (url.Length == 1 ||
(url[1] != '/' && url[1] != '\\'))) || // "/" or "/foo" but not "//" or "/\"
(url.Length > 1 &&
url[0] == '~' && url[1] == '/')); // "~/" or "~/foo"
}
}
protected void Button1_Click(object sender, EventArgs e)
{
string funcUrl = "WebForm2.aspx?";
string funQueryString = "para=" + HttpUtility.UrlEncode(txtParam.Text);
string validateUrl = funcUrl + funQueryString;
if (IsLocalUrl(validateUrl))
Response.Redirect(validateUrl);
}
所以另一個方式是除了判斷 IsLocalUrl 外,再將不確定的QueryString部份重新組合,如下,
protected void Button4_Click(object sender, EventArgs e)
{
string funcUrl = "WebForm2.aspx?";
string funQueryString = "para=" + txtParam.Text;
string validateUrl = GenValidateUrl(funcUrl + funQueryString);
if (!string.IsNullOrWhiteSpace(validateUrl))
{
Response.Redirect(validateUrl);
}
}
private string GenValidateUrl(string rawUrl)
{
string result = string.Empty;
if (IsLocalUrl(rawUrl))
{
UriBuilder builder = new UriBuilder(rawUrl);
//這裡請依個人的需求而調整哦!!!
string funcUrl = builder.Host + builder.Path;
NameValueCollection qsCollection = HttpUtility.ParseQueryString(builder.Query);
result = funcUrl + JoinNvcToQs(qsCollection);
}
return result;
}
private static string JoinNvcToQs(NameValueCollection qs)
{
return string.Join("&", Array.ConvertAll(qs.AllKeys,
key => string.Format("{0}={1}", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(qs[key]))));
}
Hi,
亂馬客Blog已移到了 「亂馬客 : Re:從零開始的軟體開發生活」
請大家繼續支持 ^_^