Skip to content

Commit

Permalink
chore: add extra scripts for brute force leak detection
Browse files Browse the repository at this point in the history
  • Loading branch information
JCMais committed Oct 23, 2021
1 parent 2be7b30 commit f83cb33
Show file tree
Hide file tree
Showing 5 changed files with 229 additions and 67 deletions.
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
},
"scripts": {
"ae": "api-extractor run --local --verbose",
"brute-force-leak-test:run": "node --inspect --expose_gc -r ts-node/register ./tools/brute-force-leak-test.ts",
"brute-force-leak-test:run:debug:gdb": "gdb --args node --inspect --expose_gc -r ts-node/register ./tools/brute-force-leak-test.ts",
"brute-force-leak-test:server": "http-server ./tools/brute-force-server-static-folder -p 8080 -s",
"build:dist": "tsc",
"clean": "yarn clean:build && yarn clean:dist",
"clean:build": "rimraf build",
Expand All @@ -47,6 +50,7 @@
"prettier:all": "yarn prettier lib/**/*.ts tools/**/*.js scripts/**/*.js test/**/*.ts examples/**/*.js",
"test": "mocha --require ts-node/register test/**/*.spec.ts --reporter spec --timeout 60000",
"test:coverage": "nyc yarn test",
"test:debug:gdb": "gdb --args node ./node_modules/.bin/mocha -r ts-node/register test/curl/hsts.spec.ts",
"test:electron": "electron-mocha --require ts-node/register test/**/*.spec.ts --reporter spec --timeout 60000",
"test:watch": "yarn test --watch --watch-files lib/*.ts lib/**/*.ts test/**/*.spec.ts",
"preversion": "yarn lint && yarn clean:dist && yarn build:dist"
Expand Down
67 changes: 0 additions & 67 deletions tools/brute-force-leak-test.js

This file was deleted.

207 changes: 207 additions & 0 deletions tools/brute-force-leak-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
/* eslint-disable no-inner-declarations */
/**
* Copyright (c) Jonathan Cardoso Machado. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { Curl, CurlHsts, Easy } from '../lib'
import readline from 'readline'

const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
})

const MAX_REQUESTS_AT_ONCE = 50
const AMOUNT_ITERATIONS_PER_RUN = 1e4

let instances: Easy[] | Curl[] = []
let iteration = 0

function createAndCloseCurlHandlesTest() {
let i = 0
const shouldClose = iteration++ % 2
const postData = [
{
name: 'file',
file: 'test.img',
type: 'image/png',
},
]

return () => {
if (shouldClose) {
console.log('Closing handles.')
} else {
console.log('Opening handles.')
}

while (i++ < AMOUNT_ITERATIONS_PER_RUN) {
if (shouldClose) {
const instance = instances.splice(i, 1)
if (instance) {
instances[i].close()
}
} else {
const handle = new Easy()
handle.setOpt('HTTPPOST', postData)
handle.setOpt(Curl.option.XFERINFOFUNCTION, () => 0)
instances[i] = handle
}
}

if (global.gc && shouldClose) {
console.log('Calling garbage collector.')
global.gc()
}
}
}

function createAndPerformAndCloseCurlHandlesMultiTest() {
let i = AMOUNT_ITERATIONS_PER_RUN
let toClose: Curl[] = []
let toPerform: Curl[] = []
let currentlyPerforming: Curl[] = []
const postData = [
{
name: 'field',
contents: 'value',
},
]

const getHstsCache = () => [
{
host: 'owasp.org',
expire: null, // infinite
},
{
host: 'github.com',
expire: '20350101 00:00:00', // infinite
},
{
host: 'donotcall.gov',
includeSubdomain: true,
},
]

return function run() {
return new Promise<void>((resolve) => {
while (i--) {
console.log('creating handler')

const handle = new Curl()
handle.setOpt('HTTPPOST', postData)
handle.setOpt('URL', 'http://127.0.0.1:8080/index.html')
handle.setOpt('HSTS_CTRL', CurlHsts.Enable)
handle.setOpt('HSTSREADFUNCTION', () => getHstsCache())
instances[i] = handle
toPerform.push(handle)

function doCleanupIfLastOne() {
const totalFinished = toClose.length
const total = instances.length

if (totalFinished === total) {
for (const handle of toClose) {
try {
handle.close()
} catch (error) {
console.error('error while closing handle', error)
}
}

toClose = []
toPerform = []
currentlyPerforming = []
instances = []

console.log('toClose.length', toClose.length)
console.log('instances.length', instances.length)
console.log('toPerform.length', toPerform.length)
console.log(
'currentlyPerforming.length',
currentlyPerforming.length,
)
console.log('Calling garbage collector.')
global.gc()

resolve()
}
}

handle.on('end', (status, data, headers, handle) => {
toClose.push(handle)
console.log('end', status)
currentlyPerforming.splice(currentlyPerforming.indexOf(handle), 1)
doPerformIfNeeded()
doCleanupIfLastOne()
})

handle.on('error', (error, code, handle) => {
toClose.push(handle)
console.log('error', error?.message || code)
currentlyPerforming.splice(currentlyPerforming.indexOf(handle), 1)
doPerformIfNeeded()
doCleanupIfLastOne()
})
}

function doPerformIfNeeded() {
const instancesToPerform = toPerform.splice(
0,
MAX_REQUESTS_AT_ONCE - currentlyPerforming.length,
)

for (const instance of instancesToPerform) {
instance.perform()
}
}

doPerformIfNeeded()
})
}
}

function clearInstances() {
return async () => {
const instance = instances.shift()
while (instance) {
try {
instance.close()
iteration = 0
} catch (error) {
/* noop */
}
}
}
}

function loop() {
rl.question(
[
`Type number to proceed, where number is:`,
`[1]: createAndCloseCurlHandlesTest`,
`[2]:createAndPerformAndCloseCurlHandlesTest`,
`[3]:clearInstances`,
``,
].join('\n'),
async function (answer) {
switch (answer) {
case '1':
await createAndCloseCurlHandlesTest()()
break
case '2':
await createAndPerformAndCloseCurlHandlesMultiTest()()
break
case '3':
default:
await clearInstances()()
}

process.nextTick(loop)
},
)
}

loop()
7 changes: 7 additions & 0 deletions tools/brute-force-server-static-folder/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## Sample HTML file

Serve this directory using a tool like `http-server` to have something to hit during the brute force leak test.

```
http-server ./tools/brute-force-server-static-folder -p 8080
```
11 changes: 11 additions & 0 deletions tools/brute-force-server-static-folder/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Sample HTML page</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
</head>
<body>
</body>
</html>

0 comments on commit f83cb33

Please sign in to comment.