在我的网站(服务器端为c#)中,我让用户提交如下链接:
<a href="$">link text</a>
他们输入的任何内容仅保留在“ href”属性内。我想通过“ href” URL阻止XSS。
现在,我检查c#对象URI是否为有效网址。
我的问题是:
例如,如何防止有效网址的XSS网络钓鱼攻击为: “ http://xss.rocks/xss.css”
答案 0 :(得分:0)
作为URI进行验证是一个好的开始。之后,确认scheme
是白名单选项,例如http
/ https
。之后,请确保在输出之前对其进行编码(请参阅OWASP链接)。基本上,您可以对任何html属性编码进行完全相同的操作,除了您还需要注意恶意方案。
要注意的事情:javascript:alert(1);
(验证方案),https://example.com?xss=" onclick=alert(1);//
(转义输出)。
请参阅:
对于问题的第二部分,一旦用户单击链接并转到新站点,该站点就不再是XSS。允许用户添加任何URL仍然很危险,即使它不是XSS漏洞也是如此。它们仍然可以链接到恶意站点,非法内容等。对于这些站点,您也许可以针对site reputation API like Google provides进行验证,但即使这样也不是防弹的。
答案 1 :(得分:0)
要回答您的问题-验证为System.Uri是不够的。我的解决方法:
&
)-拒绝网址此时,URL仍然可能类似于javascript:alert(1)
-浏览器将接受:
,而WebUtility.HtmlDecode
由于缺少分号而失败,因此:
这是代码。
private static readonly string[] acceptedSchemes = { Uri.UriSchemeHttp, Uri.UriSchemeHttps, Uri.UriSchemeMailto, Uri.UriSchemeFile };
private static readonly char[] forbiddenHrefChars = { '"', '\'', '`', (char)10, (char)13 };
private static readonly char[] forbiddenBeforeQueryString = { ':', '&', '\\' }; // the colon may look surprising, but if we deal with a colon we expect something which parses as URI
/// <summary>
/// Returns true if the specified string is considered XSS safe href attribute value.
/// </summary>
public static bool IsSafeHref(string input)
{
if (input.Any(c => forbiddenHrefChars.Contains(c)))
return false;
// do not accept any entities
string href = WebUtility.HtmlDecode(input);
if (href != input)
return false;
// check if the scheme is valid, if specified
bool isUri = Uri.TryCreate(input, UriKind.Absolute, out Uri uri);
if (uri != null)
return acceptedSchemes.Contains(uri.Scheme ?? "");
int qsIdx = href.IndexOf('?');
string partBeforeQueryString = qsIdx < 0 ? href : href.Substring(0, qsIdx);
if (forbiddenBeforeQueryString.Any(c => partBeforeQueryString.Contains(c)))
return false;
return true;
}
我认为,不应以任何方式切换URL的上下文以执行javascript。如果您找到打破它的方法,请告诉我。