防止用户在表单中输入 URL

Posted

技术标签:

【中文标题】防止用户在表单中输入 URL【英文标题】:Prevent user from entering URL in form 【发布时间】:2020-03-11 13:54:44 【问题描述】:

我有一个 ASP.Net Core 3.0 Web 应用程序,其中有一个包含多个输入字段的表单。输入字段绑定到模型,并且已经进行了一些验证。但是,在其中一个字段中,我想限制用户输入 URL 地址甚至电子邮件地址(但目前 URL 更重要)。

我的想法如下:在服务器端提交表单后,检查该字段中的文本,如果该文本包含一些 URL,则将其删除或使其无效(例如添加一些空格)。我的目标是因为用户输入稍后将显示在网站中,以限制任何 URL 处于活动状态或根本不显示,因此如果另一个用户正在检查该输入,则不会被诱骗点击某些恶意网站链接。

我的问题是:我们在 .Net Core 3(或以前的版本)上是否已经有一种机制可以自动检查用户输入中的 URL 并删除它们、使它们无效或给出验证错误?我打算自己编写整个逻辑,但如果已经完成(在 .Net Core 或其他一些开源库中),那会更好,并且会为我节省一些精力。

我还想知道是否有一些自定义验证器甚至是基本的 .Net 验证器正在执行此操作。我可以只在服务器端进行验证,但如果我们有任何机会对此进行客户端验证,那就更好了。

到目前为止,我没有任何具体的代码要显示。我对一般情况感兴趣,所以如果它对你有帮助,你可以想象一个正常的 CRUD 形式(来自那些由 VS 生成的形式)。

感谢任何帮助。

最好的问候, 艾哈迈德

== 编辑 == 可能我不够清楚。我有兴趣查看用户输入的文本是否包含一个或多个 URL。如果该文本中有任何 URL 可以将其删除,则以某种方式使其无效或给出验证错误。所以如果用户输入这个文本:

“在这里你可以找到一些疯狂的交易 - http://crazydeals.com/notsocrazydeals 并且你可以买到一些高品质的玩具”

要么转向这个:

“在这里你可以找到一些疯狂的交易 - 你可以买到一些高品质的玩具”

或者这个

"在这里你可以找到一些疯狂的交易 - h t t p : // c r a z y d e al s 。 c o m / n o t s o c r a z y d e a l s,你可以买一些高质量的玩具”

【问题讨论】:

不确定我是否足够清楚,但我有兴趣检查文本中是否包含 URL(一个或多个),而不是字符串是否为 URL 。带来不便敬请谅解。我在问题中添加了更多细节 regexr.com/4otrr ? 我看到将其变成不可点击的解决方案是一个不错的解决方案。然后你实际上什么都不做:输入 URL 的用户在呈现时不会神奇地把这个 URL 变成一个锚点。您绝对需要确保在此字段中没有输入任何 html,但要避免跨站点脚本,这将比 URL 更成问题... .net 验证应该注意在表单输入字段中输入 html 标记,值得测试,但这是一个默认验证器,需要明确禁用以允许在表单中输入 html。见:docs.microsoft.com/en-us/aspnet/whitepapers/request-validation @Derrick:是的,你是对的。默认验证器对我来说工作正常。我没有输入 html contets 的问题(至少到目前为止)。另外,我正在对输入进行编码。 【参考方案1】:

您可以创建自己的验证器并进行如下验证:

Uri uriResult;
bool result = Uri.TryCreate(uriName, UriKind.Absolute, out uriResult) 
&& (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);

参考:

How to check whether a string is a valid HTTP URL?

【讨论】:

不确定我是否足够清楚,但我有兴趣检查文本中是否包含 URL(一个或多个),而不是字符串是否为 URL 。带来不便敬请谅解。我在问题中添加了更多细节。 好的。上面的代码告诉您如何识别 URL。您可以使用相同的代码来检查字符串的多个区域。可以检查字符串中的单词“http”。如果发现被空格分割(因为 URL 没有空格),应用上面的逻辑来识别它是否是一个有效的 URL。然后继续在字符串中。【参考方案2】:

正则表达式是解决此问题的最佳方法,可能使用“https?:.*(?=\s)” 此代码将从字符串中删除所有 url:

Regex regx = new Regex("https?:.*(?=\s)", RegexOptions.IgnoreCase);

MatchCollection matches = regx.Matches(txt);

foreach (Match match in matches) 
    txt = txt.Replace(match.Value, "");

您还可以使用RegularExpressionAttribute 使基于模式的模型输入无效。这样的属性在客户端和服务器端都会失效。

public class TestModel

    [RegularExpression(@"^((?!(https?:.*(?=\s))).)*$", ErrorMessage = "URL's are not allowed.")]
    public string Text  get; set; 

这是一个正则表达式属性的测试:

[TestMethod]
public void TestNotUrl()

    var modelFail = new TestModel  Text = "Here you can find some crazy deals - http://crazydeals.com/notsocrazydeals and you can buy some high quality toys" ;
    var modelPass = new TestModel  Text = "Here you can find some crazy deals - crazydeals.com and you can buy some high quality toys" ;

    var result = new List<ValidationResult>();
    var context = new ValidationContext(modelFail)  MemberName = "Text" ;
    var expectNotValid = System.ComponentModel.DataAnnotations.Validator.TryValidateProperty(modelFail.Text, context, result);
    var expectValid = System.ComponentModel.DataAnnotations.Validator.TryValidateProperty(modelPass.Text, context, result);

    Assert.IsFalse(expectNotValid, "Expected modelFail.Text not to validate, as it contains a URL.");
    Assert.IsTrue(expectValid, "Expected modelPass.Text to validate, as it does not contain a URL.");

【讨论】:

我想我会采用这种方法并让您提到的功能检查链接,然后删除它们或使它们无效。我有点希望也许有什么东西可以自动完成,但我认为你的想法是我需要做的。 RegularExpressionAttribute 想法似乎是我需要的东西,但它似乎对我不起作用。我只是想知道该属性是否会验证整个文本是 URL,还是会在文本中查找 URL。我猜是第一个选项,但我可能错了 它在文本中查找任何出现的 URL。我将在我的答案中添加一个测试方法。 我用正则表达式方法做到了。这对我来说很有用。感谢支持 这将仅删除 web URI。还必须添加文件、FTP、mailto、LDAP 和其他方案——基本上,任何以冒号结尾的前缀。根据实际定义标准的RFC3986,它实际上有点复杂。

以上是关于防止用户在表单中输入 URL的主要内容,如果未能解决你的问题,请参考以下文章

防止表单提交字段输入键keydown? [复制]

防止表单输入类型=“数字”中的负输入?

访问 VBA 防止在关闭时输入表单记录

防止表单提交基于在框中输入相同的数字

如何防止web攻击

CakePHP:防止在 URL 中获取表单字段