详解JavaScript是如何验证URL的

作者:寒星时间:2026-10-26 11:04:51浏览:405

本文深入解析JavaScript中URL验证的多种实现方式,重点介绍URL构造函数与正则表达式的应用。通过具体代码示例,阐述如何校验协议、主机名及端口,并探讨客户端验证的局限性,强调服务端验证在防范SSRF等安全风险中的必要性。

前言

在开发过程中,我们常需利用JavaScript处理各类URL,涵盖浏览器历史导航、锚点定位及查询参数解析等场景。然而,随着JavaScript应用的普及,攻击者利用其潜在漏洞的风险也随之增加。因此,在JavaScript应用中实施严格的URL验证机制,已成为保障应用安全的关键环节。

URL验证的核心在于检查URL是否符合标准的语法结构。这一机制能有效防御基于URL的漏洞,例如恶意脚本注入和服务端请求伪造(SSRF)。若在获取远程资源时未遵循安全编码规范对用户提供的URL进行验证,攻击者便可能利用SSRF攻击漏洞。

URL验证

实施URL验证旨在强化系统安全性,预防潜在漏洞,并消除代码执行过程中可能出现的错误。关键在于确定验证的时机与对象:凡涉及识别和验证网页、图片、GIF及视频等资源的软件,均应部署URL验证机制。

标准URL由协议、域名、主机名、资源名、URL源及端口等多个片段构成,这些元素共同指导浏览器定位指定资源。我们可以采用多种策略对URL进行验证:

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

典型的URL验证流程接收用户输入并解析其各组成部分,确保所有组件符合互联网标准。例如,验证方案可检查URL是否采用了安全协议。

主机名验证首先将主机名拆分为独立标签,以确认其符合顶级域名规范。典型主机名至少包含两个由点分隔的标签,如 www.snyk.com 包含 "www"、"snyk" 和 "com"。每个标签仅限字母数字字符或连字符,大小写不限。随后,验证方案需确保主机名与预定义的允许列表匹配,从而仅放行指定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后,进一步检查其是否使用HTTP或HTTPS。在此场景下,ftp://..被视为无效,因其不包含HTTP或HTTPS,而http://..依然有效。

使用URL构造函数的其他方法包括:

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

上述示例使用了base元素。记录该值,即可得到https://snyk.io/。

若要在不指定base参数的情况下返回URL对象,语法为:

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,该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/

作者:Mannan Tirmizi

到此这篇关于详解JavaScript是如何验证URL的的文章就介绍到这了,更多相关JavaScript验证URL内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

作者最新文章