mirror of
https://github.com/bitwarden/browser
synced 2025-12-14 23:33:31 +00:00
[PS-1123] Improve hostname and domain retrieval (#3168)
* Add test cases from previous PR https://github.com/bitwarden/jslib/pull/547 * Install tldts as replacement for tldjs * Use tldts for hostname and domain retrieval/validation * Remove usage of old tldjs.noop-implementation * Add handling of about protocol * Remove usage of tldEndingRegex and use tldts check instead * Uninstall @types/tldjs and tldjs * Updated package-lock.json * Fix accessibility cookie check * Rename loginUriView.spec to login-uri-view.spec * Add test for getDomain failing file links * getHostName - Return null when given, data, about or file links
This commit is contained in:
committed by
GitHub
parent
94e9744d06
commit
8c59eef257
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable no-useless-escape */
|
||||
import * as tldjs from "tldjs";
|
||||
import { getHostname, parse } from "tldts";
|
||||
|
||||
import { AbstractEncryptService } from "../abstractions/abstractEncrypt.service";
|
||||
import { CryptoService } from "../abstractions/crypto.service";
|
||||
@@ -24,11 +24,10 @@ export class Utils {
|
||||
static isMobileBrowser = false;
|
||||
static isAppleMobileBrowser = false;
|
||||
static global: typeof global = null;
|
||||
static tldEndingRegex =
|
||||
/.*\.(com|net|org|edu|uk|gov|ca|de|jp|fr|au|ru|ch|io|es|us|co|xyz|info|ly|mil)$/;
|
||||
// Transpiled version of /\p{Emoji_Presentation}/gu using https://mothereff.in/regexpu. Used for compatability in older browsers.
|
||||
static regexpEmojiPresentation =
|
||||
/(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])/g;
|
||||
static readonly validHosts: string[] = ["localhost"];
|
||||
|
||||
static init() {
|
||||
if (Utils.inited) {
|
||||
@@ -214,12 +213,39 @@ export class Utils {
|
||||
}
|
||||
|
||||
static getHostname(uriString: string): string {
|
||||
const url = Utils.getUrl(uriString);
|
||||
if (Utils.isNullOrWhitespace(uriString)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
uriString = uriString.trim();
|
||||
|
||||
if (uriString.startsWith("data:")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (uriString.startsWith("about:")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (uriString.startsWith("file:")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Does uriString contain invalid characters
|
||||
// TODO Needs to possibly be extended, although '!' is a reserved character
|
||||
if (uriString.indexOf("!") > 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return url != null && url.hostname !== "" ? url.hostname : null;
|
||||
const hostname = getHostname(uriString, { validHosts: this.validHosts });
|
||||
if (hostname != null) {
|
||||
return hostname;
|
||||
}
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static getHost(uriString: string): string {
|
||||
@@ -232,60 +258,35 @@ export class Utils {
|
||||
}
|
||||
|
||||
static getDomain(uriString: string): string {
|
||||
if (uriString == null) {
|
||||
if (Utils.isNullOrWhitespace(uriString)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
uriString = uriString.trim();
|
||||
if (uriString === "") {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (uriString.startsWith("data:")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let httpUrl = uriString.startsWith("http://") || uriString.startsWith("https://");
|
||||
if (
|
||||
!httpUrl &&
|
||||
uriString.indexOf("://") < 0 &&
|
||||
Utils.tldEndingRegex.test(uriString) &&
|
||||
uriString.indexOf("@") < 0
|
||||
) {
|
||||
uriString = "http://" + uriString;
|
||||
httpUrl = true;
|
||||
}
|
||||
|
||||
if (httpUrl) {
|
||||
try {
|
||||
const url = Utils.getUrlObject(uriString);
|
||||
const validHostname = tldjs?.isValid != null ? tldjs.isValid(url.hostname) : true;
|
||||
if (!validHostname) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (url.hostname === "localhost" || Utils.validIpAddress(url.hostname)) {
|
||||
return url.hostname;
|
||||
}
|
||||
|
||||
const urlDomain =
|
||||
tldjs != null && tldjs.getDomain != null ? tldjs.getDomain(url.hostname) : null;
|
||||
return urlDomain != null ? urlDomain : url.hostname;
|
||||
} catch (e) {
|
||||
// Invalid domain, try another approach below.
|
||||
}
|
||||
if (uriString.startsWith("about:")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const domain = tldjs != null && tldjs.getDomain != null ? tldjs.getDomain(uriString) : null;
|
||||
const parseResult = parse(uriString, { validHosts: this.validHosts });
|
||||
if (parseResult != null && parseResult.hostname != null) {
|
||||
if (parseResult.hostname === "localhost" || parseResult.isIp) {
|
||||
return parseResult.hostname;
|
||||
}
|
||||
|
||||
if (domain != null) {
|
||||
return domain;
|
||||
if (parseResult.domain != null) {
|
||||
return parseResult.domain;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -358,14 +359,11 @@ export class Utils {
|
||||
}
|
||||
|
||||
static getUrl(uriString: string): URL {
|
||||
if (uriString == null) {
|
||||
if (this.isNullOrWhitespace(uriString)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
uriString = uriString.trim();
|
||||
if (uriString === "") {
|
||||
return null;
|
||||
}
|
||||
|
||||
let url = Utils.getUrlObject(uriString);
|
||||
if (url == null) {
|
||||
@@ -425,12 +423,6 @@ export class Utils {
|
||||
return this.global.bitwardenContainerService;
|
||||
}
|
||||
|
||||
private static validIpAddress(ipString: string): boolean {
|
||||
const ipRegex =
|
||||
/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
|
||||
return ipRegex.test(ipString);
|
||||
}
|
||||
|
||||
private static isMobile(win: Window) {
|
||||
let mobile = false;
|
||||
((a) => {
|
||||
|
||||
Reference in New Issue
Block a user