Created
March 22, 2022 23:38
-
-
Save maxime-rainville/5b52a076a80b39e4fc02bd85a2f46fe3 to your computer and use it in GitHub Desktop.
GraphQL Spam script for Silverstirpe CMS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const https = require('https'); | |
const schema='tiny'; | |
const forceClear = false; | |
// This is meant to immitate an actual browser | |
// So you need to stick your PHP session ID and your user agent string in here | |
const sessionid = ''; | |
const useragent = 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:98.0) Gecko/20100101 Firefox/98.0' | |
const postData = JSON.stringify({ | |
"operationName": null, | |
"variables": {}, | |
"query": ` | |
{ | |
readPorroRems { | |
nodes { | |
id | |
distinctioId { | |
id | |
} | |
distinctioIds { | |
id | |
} | |
distinctioIdManys { | |
id | |
} | |
} | |
} | |
}` | |
}); | |
const options = { | |
hostname: 'cmstestm-uat.sites.silverstripe.com', | |
port: 443, | |
path: `/${schema}/graphql`, | |
method: 'POST', | |
headers: { | |
'content-type': 'application/json', | |
'User-Agent': useragent, | |
'Cookie': `PHPSESSID=${sessionid}` | |
} | |
}; | |
/** | |
* Does the initial call to /dev/graphql/clear ... this will redirect you ta confirm screen | |
*/ | |
function clearInit() { | |
return new Promise((resolve, reject) => { | |
const req = https.request({...options, path: '/dev/graphql/clear', method: 'GET'}, (res) => { | |
const body = [] | |
res.on('data', (chunk) => body.push(chunk)) | |
res.on('end', () => { | |
resolve(clearConfirm()); | |
}) | |
}) | |
req.on('error', (e) => { | |
console.error(e); | |
reject(e) | |
}); | |
req.end(); | |
}) | |
} | |
/** | |
* Gets the confirm request form and extract the token from the hidden form field | |
*/ | |
function clearConfirm() { | |
return new Promise((resolve, reject) => { | |
const req = https.request({...options, path: '/dev/confirm/dev-urls', method: 'GET'}, (res) => { | |
const body = [] | |
res.on('data', (chunk) => body.push(chunk)) | |
res.on('end', () => { | |
const resString = Buffer.concat(body).toString(); | |
const matches = resString.match(/<input type="hidden" name=".*?" value=".*?"/ig); | |
const params = matches.reduce( | |
(value, match) => { | |
const res = match.match(/name="(.*?)" value="(.*?)"/i); | |
return {...value, [res[1]]: res[2]}; | |
}, | |
{'action_doConfirm': 'Run the action'} | |
); | |
resolve(clearConfirmPost(params)); | |
}) | |
}) | |
req.on('error', (e) => { | |
console.error(e); | |
reject(e) | |
}); | |
req.end(); | |
}) | |
} | |
/** | |
* Submits the tokens to the confirm form | |
*/ | |
function clearConfirmPost(params) { | |
const postData = Object | |
.entries(params) | |
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`) | |
.join('&'); | |
return new Promise((resolve, reject) => { | |
const req = https.request({...options, path: `/dev/confirm/dev-urls/Form/?stage=Stage`, headers: {...options.headers, 'Content-Type': 'application/x-www-form-urlencoded', referer: 'https://cmstestm-uat.sites.silverstripe.com/dev/confirm/dev-urls'}}, (res) => { | |
res.on('data', (b) => {}); | |
res.on('end', () => { | |
resolve(clearFinal()); | |
}) | |
}) | |
req.on('error', (e) => { | |
console.error(e); | |
reject(e) | |
}); | |
req.write(postData); | |
req.end(); | |
}) | |
} | |
/** | |
* Doest he actual clearing | |
*/ | |
function clearFinal() { | |
return new Promise((resolve, reject) => { | |
const req = https.request({...options, path: '/dev/graphql/clear', method: 'GET'}, (res) => { | |
res.on('data', (b) => {console.log(b.toString())}); | |
res.on('end', () => { | |
resolve(); | |
}) | |
}) | |
req.on('error', (e) => { | |
console.error(e); | |
reject(e) | |
}); | |
req.end(); | |
}) | |
} | |
/** | |
* Does a GraphQL request | |
*/ | |
function doGraphQL() { | |
return new Promise((resolve, reject) => { | |
let start = Date.now(); | |
const req = https.request(options, (res) => { | |
const end = Date.now(); | |
res.on('data', (d) => { | |
process.stdout.write(d); | |
}); | |
res.on('end', () => { | |
resolve(end-start); | |
}) | |
}) | |
req.on('error', (e) => { | |
console.error(e); | |
reject(e) | |
}); | |
req.write(postData); | |
req.end(); | |
}) | |
} | |
/** | |
* Sleeps for the provided number of milliseconds | |
*/ | |
function sleep(ms) { | |
return new Promise((resolve) => { | |
setTimeout(resolve, ms); | |
}); | |
} | |
/** | |
* Entry point | |
*/ | |
async function start() { | |
let results = []; | |
for (let i = 0; i < 10; i++) { | |
if (forceClear){ | |
await clearInit(); | |
await sleep(1000); | |
} | |
const res = await doGraphQL(); | |
results.push(res); | |
await sleep(1000); | |
} | |
console.log(''); | |
for (result of results) { | |
console.log(result); | |
} | |
} | |
start(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment