Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/azu/url-cheatsheet
URL manipulation cheatsheet for JavaScript
https://github.com/azu/url-cheatsheet
cheatsheet javascript url urlsearchparams
Last synced: 5 days ago
JSON representation
URL manipulation cheatsheet for JavaScript
- Host: GitHub
- URL: https://github.com/azu/url-cheatsheet
- Owner: azu
- License: mit
- Created: 2022-12-13T15:25:27.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2023-08-21T14:38:04.000Z (about 1 year ago)
- Last Synced: 2024-11-07T16:51:10.139Z (13 days ago)
- Topics: cheatsheet, javascript, url, urlsearchparams
- Language: JavaScript
- Homepage:
- Size: 105 KB
- Stars: 194
- Watchers: 2
- Forks: 4
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# url-cheatsheet
URL manipulation cheatsheet for JavaScript.
## DO NOT: concat url and user input without escape
Please DO NOT concat url and user input without escape
```js
// DO NOT
const name = "";
const url = `https://example.com/user/${name}`;
console.log(url); // => "https://example.com/user/"
```This code may have directory traversal vulnerability.
You should escape the `name` by `encodeURIComponent`.```js
// DO
const name = "";
const url = `https://example.com/user/${encodeURIComponent(name)}`;
console.log(url); // => "https://example.com/user/%3Cuser%20input%3E"
```Addtionaly, You should reject [`.`](https://url.spec.whatwg.org/#single-dot-path-segment) and [`..`](https://url.spec.whatwg.org/#double-dot-path-segment) as a name.
Because `encodeURIComponent("..")` is `..`, it may have directory traversal vulnerability.```js
// DO
const name = "";
if (name === ".." || name === ".") {
throw new Error("Invalid name");
}
const url = `https://example.com/user/${encodeURIComponent(name)}`;
console.log(url); // => "https://example.com/user/%3Cuser%20input%3E"
```-
- [Path Traversal | OWASP Foundation](https://owasp.org/www-community/attacks/Path_Traversal)
- [Path Traversal and SSRF - Security, Tech, And Ramblings](https://smarpo.com/posts/path-traversal-and-ssrf/)## DO NOT: concat parameter and user input without escape
Please DO NOT concat parameter and user input without escape
```js
// DO NOT
const query = "";
const url = `https://example.com?q=${query}`;
console.log(url); // => "https://example.com?q="
```This example does not consider that `query` includes `&` or `?` that is required to escape.
You should escape the `query` by `encodeURIComponent`.```js
// DO
const query = "";
const url = `https://example.com?q=${encodeURIComponent(query)}`;
console.log(url); // => "https://example.com?q=%3Cuser%20input%3E"
```Or, You can use [URLSearchParams()](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/URLSearchParams) that escape each parameters automatically.
- Related: [Client-side HTTP parameter pollution (reflected) - PortSwigger](https://portswigger.net/kb/issues/00501400_client-side-http-parameter-pollution-reflected)
## Base URL + Path
Use [`new URL(pathname, base)`](https://developer.mozilla.org/docs/Web/API/URL/URL).
- keywords: url-join, join path
```js
const base = "https://example.com";
const pathname = "/path/to/page";
const result = new URL(pathname, base);
console.log(result.toString()); // => "https://example.com/path/to/page"
```If the pathname include user input, you should escape it by `encodeURIComponent`.
```js
const base = "https://example.com/";
const name = "";
const result = new URL(`/user/${encodeURIComponent(name)}`, base);
console.log(result.toString()); // => "https://example.com/user/%3Cuser%20input%3E"
```Addtionaly, You should reject [`.`](https://url.spec.whatwg.org/#single-dot-path-segment) and [`..`](https://url.spec.whatwg.org/#double-dot-path-segment) as a name.
Because `encodeURIComponent("..")` is `..`, it may have directory traversal vulnerability.```js
// DO
const base = "https://example.com/";
const name = "";
if (name === ".." || name === ".") {
throw new Error("Invalid name");
}
const result = new URL(`/user/${encodeURIComponent(name)}`, base);
console.log(result.toString()); // => "https://example.com/user/%3Cuser%20input%3E"
```-
- [Path Traversal | OWASP Foundation](https://owasp.org/www-community/attacks/Path_Traversal)
- [Path Traversal and SSRF - Security, Tech, And Ramblings](https://smarpo.com/posts/path-traversal-and-ssrf/)## Get parameter from URL
Use [`URL`](https://developer.mozilla.org/docs/Web/API/URL/URL) and [URLSearchParams#get](https://developer.mozilla.org/docs/Web/API/URLSearchParams/get)
```js
const inputURL = "https://example.com/?q=query&page=1";
const url = new URL(inputURL);
const q = url.searchParams.get("q");
console.log(q); // => "query"
```## Get multiple parameters as array from URL
Use [`URL`](https://developer.mozilla.org/docs/Web/API/URL/URL) and [URLSearchParams#getAll](https://developer.mozilla.org/docs/Web/API/URLSearchParams/getAll)
```js
const inputURL = "https://example.com/?q=query&lang=en_US&lang=ja_JP";
const url = new URL(inputURL);
const langs = url.searchParams.getAll("lang");
console.log(langs); // ["en_US", "ja_JP"]
```## Add parameters to URL
Use [URLSearchParams](https://developer.mozilla.org/docs/Web/API/URLSearchParams)
```js
const q = "query";
const page = 1;
const base = "https://example.com";
const url = new URL(base);
const params = new URLSearchParams({
q,
page,
});
console.log(url + "?" + params); // => "https://example.com/?q=query&page=1"
```or
```js
const q = "query";
const page = 1;
const base = "https://example.com";
const url = new URL(base);
url.search = new URLSearchParams({
q,
page,
});
console.log(url.toString()); // => "https://example.com/?q=query&page=1"
```:memo: `URLSearchParams` escape each parameter automtically.
```js
const q = "";
const page = 1;
const base = "https://example.com";
const url = new URL(base);
url.search = new URLSearchParams({
q,
page,
});
console.log(url.toString()); // => "https://example.com/?q=%3Cuser+input%3E&page=1"
```## Update parameter of URL
Use [`URL`](https://developer.mozilla.org/docs/Web/API/URL/URL)'s [`searchParams`](https://developer.mozilla.org/docs/Web/API/URL/searchParams) property.
```js
const inputURL = "https://example.com/?q=query&page=1";
const url = new URL(inputURL);
url.searchParams.set("q", "update");
console.log(url.toString()); // => "https://example.com/?q=update&page=1"
```## Remove parameter from URL
Use [`URL`](https://developer.mozilla.org/docs/Web/API/URL/URL) and [URLSearchParams](https://developer.mozilla.org/docs/Web/API/URLSearchParams)
```js
const inputURL = "https://example.com/?q=query&page=1";
const url = new URL(inputURL);
url.searchParams.delete("q");
console.log(url.toString()); // => "https://example.com/?page=1"
```## Filter parameters
Allow only `a` and `d` parameters.
- keywords: pick, white list, allow list
```js
const base = "https://example.com/?a=1&b=2&c=3&d=4";
const url = new URL(base);
const allowedParameterNames = ["a", "d"];
url.search = new URLSearchParams(
Array.from(url.searchParams).filter(([key, value]) => {
return allowedParameterNames.includes(key);
})
);
console.log(url.toString()); // => "https://example.com/?a=1&d=4"
```## Check URL is Absolute-URL
[`new URL(urlString)`](https://developer.mozilla.org/docs/Web/API/URL/URL) throw an error when parsing relative url string.
As a result, you can use `URL` for checking URL is absolute-URL that starts with a schema like `https:`- Related: [Secure JavaScript URL validation | Snyk](https://snyk.io/blog/secure-javascript-url-validation/)
```js
const isValidURL = (urlString) => {
try {
new URL(urlString); // if `urlString` is invalid, throw an erorr
return true;
} catch {
return false;
}
};
console.log(isValidURL("https://example.com")); // => true
console.log(isValidURL("https/example.com")); // => false
```## Check URL is HTTP
Check [`URL`](https://developer.mozilla.org/docs/Web/API/URL/URL)'s [`protocol`](https://developer.mozilla.org/docs/Web/API/URL/protocol) property.
```js
const isHttpURL = (urlString) => {
try {
const url = new URL(urlString); // if `urlString` is invalid, throw an erorr
return url.protocol === "http:" || url.protocol === "https:";
} catch {
return false;
}
};
console.log(isHttpURL("http://example.com")); // => true
console.log(isHttpURL("https://example.com")); // => true
console.log(isHttpURL("ftp://example.com")); // => false
console.log(isHttpURL("https/example.com")); // => false
```