JavaScript 如何验证 URL

更新日期: 2023-02-27阅读: 986标签: url


前言

当开发者需要为不同目的以不同形式处理URL时,比如说浏览器历史导航,锚点目标,查询参数等等,我们经常会借助于JavaScript。然而,它的频繁使用促使攻击者利用其漏洞。这种被利用的风险是我们必须在我们的JavaScript应用程序中实现URL验证的原因。

URL验证检查URL是否遵循正确的URL语法,也就是每个URL必须具备的结构。URL验证可以使我们的应用程序免遭基于URL的漏洞,比如恶意脚本注入和服务器端请求伪造(SSRF)。当我们在获取远程资源时没有应用安全编码惯例来验证用户提供的URL时,恶意行为者可以采用SSRF攻击。

URL验证

URL验证的存在是为了加强安全,防止可能存在的漏洞,并消除运行代码时产生的任何错误的机会。但是我们应该在什么时候使用URL验证,在这个过程中我们要验证什么呢?我们应该在所有必须识别和验证诸如网页、图片、gif和视频等资源的软件中实施URL验证。

一个典型的URL包括多个片段,比如协议、域名、主机名、资源名、URL源、端口等等。这些用来告诉浏览器如何追踪指定的资源。我们可以以不同的方式来验证URL:

  • 使用正则字面量和构造函数
  • URL构造函数
  • isValidURL方法
  • Input元素
  • Anchor标签方法

一个典型的URL验证方案接收来自用户的输入,然后对其进行解析,以识别其各个组成部分。验证方案可以确保所有的URL组件符合互联网标准。例如,如果需要,它可以检查URL是否使用安全协议。

主机名验证首先是将主机名分成独立的标签,以确保它们符合顶级域名规范。一个典型的主机名由至少两个用点分隔的标签组成。例如,www.snyk.com 有 "www"、"snyk"和 "com"的标签。每个标签只能由一个字母数字字符或一个连字符组成,无论大小写。然后,验证方案可以确保主机名与URL的允许列表相匹配,以确保只允许指定的URL,并且允许的URL不会被错误地取消资格。

默认情况下,URL中使用的大多数资源的路径都是允许的。然而,端口只能在1到65536的范围内。任何超出这个范围的东西都应该抛出一个错误。我们还可以检查数字IP地址,以判断它是一个IPV4地址还是IPV6地址。

最后,我们也可以检查URL的用户名和密码。这个功能有助于遵守公司政策和凭证保护。

现在,你已经有了这些基础知识,让我们来看看使用javascript的URL验证吧。

如何执行URL验证

在JavaScript中,执行URL验证最简单的方式是使用new URL构造函数。除此之外,它还得到了Node.js运行时和大多数浏览器的支持。

基本语法如下:

new URL (url)
new URL (url , base)

如果提供相对URL,JavaScript只需要base元素。如果不提供相对URL,默认为undefined。另外,如果提供一个具有绝对URL的base元素,JavaScript会忽略base元素。

为了验证URL,可以使用以下代码:

function checkUrl (string) {
  let givenURL ;
  try {
      givenURL = new URL (string);
  } catch (error) {
      console.log ("error is", error);
     return false; 
  }
  return true;
}

该函数用于检查URL的有效性。当URL有效时返回true,否则返回false。

  • 如果你传递www.urlcheck.com给该函数会返回false。因为该参数并不是一个有效的URL。正确版本应该是https://urlcheck.com。
  • 另一个例子是mailto:John.Doe@example.com。这是一个有效的URL,但如果移除了冒号,JavaScript就不再认为它是一个URL了。
  • 第三个例子是ftp://。这不是一个有效URL,因为没有包含主机名。如果你添加两个点(..),就会变成有效URL。因为点会被认为是一个主机名,也就是说ftp://..变成了一个有效的URL。

重要的是要记住,非常规的、但完全有效的URL是存在的!它们可能对从事这些工作的开发人员来说是意外的,但在其他方面是完全合适的。例如,以下两个URL都会返回真值:

  • new URL("youtube://a.b.c.d");
  • new URL("a://1.2.3.4@1.2.3.4");

这些例子提醒我们,开发者应该依靠URL验证原则,而不是专注于惯例。

如果你想确保有效的URL包含一些特定的URL方案,你可以使用以下函数:

function checkHttpUrl(string) {
  let givenURL;
  try {
      givenURL = new URL(string);
  } catch (error) {
      console.log("error is",error)
    return false;  
  }
  return givenURL.protocol === "http:" || givenURL.protocol === "https:";
}

该函数验证URL,然后检查URL是否使用HTTP或者HTTPS。在这里,ftp://..会被认为是无效的,因为它不包含HTTP或者HTTPS,而http://..依旧有效。

使用URL构造函数的一些其他方式包括:

let m = '<https://snyk.io>';
let a = new URL("/", m);

上述示例使用了base元素。记录下这个值,我们就可以得到https://snyk.io/。

要返回一个URL对象而不指定base参数的话,语法是:

let b = new URL(m);

为了给主机添加一个路径名,我们的代码结构如下:

let d = new URL('/en-US/docs', b);

存储在变量d上的URL是https://snyk.io/en-US/docs。

URL模块的另一个功能是,它实现了WHATWG URL api,它遵守WHATWG的URL标准,供浏览器使用:

let adr = new URL("<https://snyk.io/en-US/docs>");
let host = adr.host;
let path = adr.pathname;

在上面的例子中,我们创建了一个名为adr的URL对象。接着,代码获取URL的主机和路径名,分别是snyk.io和/en-US/docs。最后,我们可以将URL和允许列表或者黑名单进行对比,确保只有特定URL是被允许的。

如何使用正则验证

另一种验证URL的方法是使用正则表达式(regex)。我们可以使用Regex来检查URL是否有效。

使用regex进行URL验证的JavaScript语法是:

function isValidURL(string) 
  {
      var res = 
      string.match(/(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-
      ]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]
      \.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|w
      ww\.[a-zA-Z0-9]+\.[^\s]{2,})/gi);
          return (res !== null);
  };

来测试一些URL:

var tc1 = "<http://helloworld.com>"
console.log(isValidURL(tc1));

regex定义的URL语法检查URL是否以http://或https://或子域开始,以及是否包含域名。控制台上的语句结果是true,因为它遵循了由regex定义的URL语法。相反,下面的语句将返回一个false,因为它没有以任何允许的方案或子域开始,也不包含域名:

var tc4 = "helloWorld";
console.log (isValidURL(tc4));

上面的正则表达式相对简单,但仍然难以驾驭。这也是一个容易出错的方法,因为一个正则表达式不能充分处理验证URL的规则。它最多只能做到匹配有效的URL。此外,当一个正则表达式要么包含复杂的验证逻辑,要么收到冗长的输入字符串时,执行验证检查就变得很耗时。

为了满足定义的正则表达式验证检查,浏览器必须在输入字符串中进行数以百万计的回溯。如此多的回溯检查可能会导致"灾难性的回溯",这种现象是复杂的正则表达式会冻结浏览器或使CPU核心进程爆满。

安全使用JavaScript

正如SSRF被添加到新的OWASP Top 10中所证明的那样,URL验证对于JavaScript应用程序的安全性已经变得越来越关键。幸运的是,我们可以通过在服务器端验证URL来帮助缓解此类攻击。此外,根据验证和处理URL的首选方式来使用new URL函数会非常有益。

在看到new URL函数的一些使用案例后,我们学习了如何用正则表达式验证一个URL--并看到了为什么这种方法很麻烦而且容易出错。

URL的安全风险与其说是关于其有效性,不如说是关于危险的URL方案。因此,我们需要确保让服务器端的应用程序进行验证。攻击者可以绕过客户端的验证机制,所以仅仅依靠它并不是解决办法。

原文:https://snyk.io/blog/secure-javascript-url-validation/

链接: https://fly63.com/article/detial/12388

静态网站如何获取Get参数,通过js获取url的参数数据的实现方式

不使用动态语言php,java等,直接通过js获取链接中传递的get数据的方法总结。javascript可以获取当前页面的url 只要对获取下来的url进行简单地解析即可。

短网址(short URL)系统的原理及其实现

做一个短链接生成器,可以将一个长链接缩短成一个短链接。就是把普通网址,转换成比较短的网址。好处不言而喻。短、字符少、美观、便于发布、传播。

从浏览器地址栏输入url到显示页面的步骤(以HTTP为例)

在浏览器地址栏输入URL,浏览器查看缓存,如果请求资源在缓存中并且新鲜,跳转到转码步骤,如果资源未缓存,发起新请求,如果已缓存,检验是否足够新鲜,足够新鲜直接提供给客户端,否则与服务器进行验证...

html 获取url地址_js获取当前页面的url网址信息汇总

在WEB开发中,时常会用到javascript来获取当前页面的url网址信息,在这里是我的一些获取url信息的小总结。window.location.href(设置或获取整个 URL 为字符串),window.location.protocol(设置或获取 URL 的协议部分)

html中绝对路径和相对路径的区别?比较相对路径和绝对路径的优缺点

相对路径就是相对于当前文件的路径;可以防止被抄袭,如果网页位置改变,里面的链接还是指向正确的URL。在编码编写时不方便使用绝对路径,因为链接应该指向真正的域名,而不是开发站点。

qs.js_更好的处理url参数

一次接触qs这个库,是在使用axios时,用于给post方法编码,在使用过程中,接触到了一些不同的用法,写在这里分享一下:qs.parse、qs.stringify、排序、指定数组编码格式、处理json格式的参数

短网址(short URL)的实现_如何生成短链接URL?

什么是短链接 ?就是把普通网址,转换成比较短的网址。好处不言而喻:短、字符少、美观、便于发布、传播。所以如何来优雅的生成足够短的字符串唯一ID呢?

window.URL对象的使用方式

window对象的URL对象是专门用来将blob或者file读取成一个url的。这个url可以用在html的任何可以使用url的地方,比如img的src ; audio/video的src和source标签等。

PHP利用get_headers()函数判断远程的url地址是否有效

利用url访问远程的文件、图片、视频时有时需要请求前判断url地址是否有效。利用PHP自带的函数get_headers(),利用http返回值是否存在200状态,来判断url地址是否有效。

URL和URI的区别

URL的格式由下列三部分组成:协议(或称为服务方式);存有该资源的主机IP地址(有时也包括端口号);主机资源的具体地址,如目录和文件名等。URI,统一资源标识符:主机名。存放资源的自身的名称,由路径表示

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!