Skip to content

Instantly share code, notes, and snippets.

not-an-aardvark / vandalism.yml
Last active May 2, 2022
Proof-of-concept GitHub Actions workflow exploit (CVE-2021-22862)
View vandalism.yml
# This is a proof-of-concept for a security bug in GitHub Actions which has since been fixed.
# See for more information.
# The proof-of-concept was only ever used in a test environment to validate the existence of the
# vulnerability, and is shown here for educational purposes.
# The proof-of-concept would have the effect of creating a `` file, containing vandalism,
# on the default branch of a victim repository.
# To use the proof-of-concept, the steps would have been:
# 1. Fork the victim repository
View exploit.js
"use strict";
const crypto = require("crypto");
const fetch = require("node-fetch");
const BLOCK_SIZE = 16;
const PADDING_ORACLE_PAYLOAD = '","user":"admin"}';
const padToBlockSize = text => {
const unpadded = Buffer.from(text, "binary");

Overview of options and tradeoffs for throwing an error on duplicate plugin names

The main blocker for eslint/eslint#3458 (allowing shareable configs to manage their own plugin dependencies) has been a concern that two shareable configs could depend on two different versions of a plugin. Currently, ESLint's mechanism for referring to a rule from a config (with pluginName/ruleName) implicitly assumes plugin names are globally unique. This has led to proposals like eslint/rfcs#5 that attempt to remove the assumption that plugin names are globally unique, by giving config authors a way to disambiguate plugins with the same name.

The case where two plugins have the same name seems like it would be somewhat rare. As an alternative to a disambiguation mechanism, a few people have suggested simply raising an error when a name conflict happens (i.e. declaring that we don't support that case), which would avoid the complexi


Keybase proof

I hereby claim:

  • I am not-an-aardvark on github.
  • I am not_an_aardvark ( on keybase.
  • I have a public key ASAIfVUSAjh_DpFTn6ysz8qjWkCSkJyC5E_2a3Tz2bK-HAo

To claim this, I am signing this object:

not-an-aardvark / eslint-fuzzer.js
Last active Apr 2, 2017
Fuzzer to detect ESLint crashes and autofixing errors
View eslint-fuzzer.js
"use strict";
// Requirements
const assert = require("assert");
const lodash = require("lodash");
const eslump = require("eslump");
const SourceCodeFixer = require("eslint/lib/util/source-code-fixer");
not-an-aardvark / .eslintrc.js
Last active Sep 30, 2017
How to dogfood your own rules when writing an ESLint plugin. DEPRECATED in favor of
View .eslintrc.js
'use strict';
const fs = require('fs');
const path = require('path');
const PACKAGE_NAME = require('./package').name;
const SYMLINK_LOCATION = path.join(__dirname, 'node_modules', PACKAGE_NAME);
// Symlink node_modules/{package name} to this directory so that ESLint resolves this plugin name correctly.
if (!fs.existsSync(SYMLINK_LOCATION)) {
fs.symlinkSync(__dirname, SYMLINK_LOCATION);

This is a crash course in JavaScript. It is intended for people who already have a bit of programming experience in other languages.

This will hopefully give a basic idea of the most-commonly-used language features, but it is not indended to be a comprehensive guide.

This guide was last updated in August 2016.

Basic syntax

To declare a variable called foo:

View throttle.js
/* Returns a wrapped version of `func` which calls `func` at most once every `delay` milliseconds.
** The wrapped function returns a Promise which resolves with the result of calling `func` after the delay has finished.
module.exports = (func, delay) => {
var lastTimestamp = -Infinity;
return function (...args) {
var now =;
lastTimestamp = Math.max(now, lastTimestamp + delay);
return new Promise(resolve => setTimeout(resolve, lastTimestamp - now)).then(() => func.apply(this, args));
not-an-aardvark / async-without-babel.js
Last active Mar 24, 2017
async functions without a transpiler
View async-without-babel.js
var Promise = require('bluebird');
var examplePromise1 = Promise.delay(5000);
var examplePromise2 = Promise.delay(2000).return('myValue');
// the following two are equivalent:
// 1. Async function (ES7, only available with a transpiler)
var func = async function (arg1, arg2, arg3) {
await examplePromise1;
View losslessThrottle.js
var _ = require('lodash');
function losslessThrottle(func, wait) {
var scheduledCalls = [];
return function() {
// Add a timestamp to `scheduledCalls` signifying when the current invocation will take place.
// The last element of `scheduledCalls` will be the timestamp of the latest scheduled invocation, so the current
// invocation should occur `wait` milliseconds after that.
var scheduledTimestamp = _.max([_.last(scheduledCalls) + wait,]);