Skip to content

Instantly share code, notes, and snippets.

Avatar
:octocat:

Eli Grey eligrey

:octocat:
View GitHub Profile
@eligrey
eligrey / interventions.ts
Last active January 21, 2022 20:58
lock well-known built-in JS iterable prototypes
View interventions.ts
const freezeProp = <T = any>(
object: T,
property: string | symbol | number,
value = (object as any)[property],
): T =>
Object.defineProperty(object, property, {
value,
configurable: false,
writable: false,
enumerable: false,
@eligrey
eligrey / uri-validator.ts
Created September 25, 2021 19:50
URL validation utilities
View uri-validator.ts
/**
* Validate potentially relative URL
*
* @param input - URL to validate
* @returns true if URL is valid and doesn't need additional encoding
*/
const isValidURL = (input: string): boolean => {
try {
const { href, pathname, host, origin } = new globalThis.URL(
input,
@eligrey
eligrey / example.ts
Last active April 12, 2022 05:10
Simple language matcher
View example.ts
import { matchLanguages, getNearestSupportedLanguage } from './match-languages';
const supportedLanguages = ['en-GB', 'fr'];
console.log('navigator.languages: ', navigator.languages);
const matches = matchLanguages(navigator.languages, supportedLanguages);
console.log('preferred language matches:', matches);
const nearest = getNearestSupportedLanguage(matches, supportedLanguages);
console.log('nearest matching supported language:', nearest);
@eligrey
eligrey / host-validator.ts
Last active June 11, 2022 10:07
URL host validation utility
View host-validator.ts
/**
* Validate URL host
*
* This supports domain names, IDN domain names, IPv4, and IPv6 addresses.
*
* Intentional spec incompatibilities:
* - Blank hosts ('') and blank FQDN hosts ('.') are considered invalid.
*
* @param host - Host to validate
* @returns true if host is valid and doesn't need additional encoding
@eligrey
eligrey / challenge.js
Last active February 15, 2021 00:53
Secure user-initiated click isTrusted attestation challenge — https://go.eligrey.com/t/event-isTrusted-challenge
View challenge.js
// @ts-nocheck
//
// User-initiated click isTrusted attestation challenge:
//
// Secure this 'click' event listener from synthetic clicks
// while working in a prototype pollution superfund site.
//
// addEventListener() has been been backdoored.
//
@eligrey
eligrey / node.isConnected-polyfill.js
Last active December 26, 2022 01:09
Node.isConnected polyfill for EdgeHTML
View node.isConnected-polyfill.js
/*
* Node.isConnected polyfill for EdgeHTML
* 2021-04-12
*
* By Eli Grey, https://eligrey.com
* Public domain.
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
*/
if (!('isConnected' in Node.prototype)) {
@eligrey
eligrey / bypass-csp.js
Last active November 26, 2019 00:45
Universal CSP bypass exfiltration tool
View bypass-csp.js
// update: this was over-engineered
// just navigate to an HTTP 204 redirect to exfiltrate data
@eligrey
eligrey / filename from path regexes.js
Created August 16, 2019 03:19
filename from path regexes
View filename from path regexes.js
const pathFileNameMatcher = /\/?(?<fileName>[^/]+(?<fileExtension>\.[^/.]*)?)\/*$/;
const pathFilePrefixMatcher = /\/?(?<filePrefix>[^/]+)(?<fileExtension>\.[^/.]*)?\/*$/;
'test/foo/|foo|.test.enc/'.match(pathFilePrefixMatcher).groups.filePrefix == '|foo|.test'
const matches = new URL('https://your-url-here/example.txt').pathname.match(pathFileNameMatcher);
const fileName =
(matches && matches.groups && matches.groups.fileName) || 'file';
@eligrey
eligrey / spreadify.once.js
Last active August 8, 2022 05:41
spreadify: add a universal iterator to any array-like object
View spreadify.once.js
/** Alternative spreadify implementation with `...spreadify.once` */
const spreadify = {
/** Always spread */
*[Symbol.iterator](): any {
delete this[Symbol.iterator];
yield* this.once[Symbol.iterator].call(this);
this[Symbol.iterator] = this.once[Symbol.iterator];
},
once: {
/** Spread once */
@eligrey
eligrey / hash.ts
Last active July 12, 2022 10:39
Simple cryptographic hashing function for ArrayBuffers in browsers
View hash.ts
/**
* Get the cryptographic hash of an ArrayBuffer
*
* @param ab - ArrayBuffer to digest
* @param algorithm - Cryptographic hash digest algorithm
* @returns Hexadecimal hash digest string
*/
export const hash = async (
algorithm: string,
ab: ArrayBuffer | Promise<ArrayBuffer>,