Fixed code injection from twitter import

This commit is contained in:
KevinWh0 2024-02-01 15:58:50 +01:00
parent 2811f4cca5
commit 2a8e93e4be
1 changed files with 25 additions and 17 deletions

View File

@ -130,6 +130,17 @@ export class ImportNotesProcessorService {
return typeof obj[Symbol.iterator] === 'function'; return typeof obj[Symbol.iterator] === 'function';
} }
private parseTwitterFile(str : string) : null | [{ tweet: any }] {
const removed = str.replace(new RegExp('window\\.YTD\\.tweets\\.part0 = ', 'g'), '');
try {
return JSON.parse(removed);
} catch (error) {
//The format is not what we expected. Either this file was tampered with or twitters exports changed
return null;
}
}
@bindThis @bindThis
public async process(job: Bull.Job<DbNoteImportJobData>): Promise<void> { public async process(job: Bull.Job<DbNoteImportJobData>): Promise<void> {
this.logger.info(`Starting note import of ${job.data.user.id} ...`); this.logger.info(`Starting note import of ${job.data.user.id} ...`);
@ -175,23 +186,20 @@ export class ImportNotesProcessorService {
try { try {
this.logger.succ(`Unzipping to ${outputPath}`); this.logger.succ(`Unzipping to ${outputPath}`);
ZipReader.withDestinationPath(outputPath).viaBuffer(await fs.promises.readFile(destPath)); ZipReader.withDestinationPath(outputPath).viaBuffer(await fs.promises.readFile(destPath));
const fakeWindow: any = {
window: { const unprocessedTweetJson = this.parseTwitterFile(fs.readFileSync(outputPath + '/data/tweets.js', 'utf-8'));
YTD: {
tweets: { //Make sure that it isnt null (because if something went wrong in parseTwitterFile it returns null)
part0: {}, if (unprocessedTweetJson) {
}, const tweets = Object.keys(unprocessedTweetJson).reduce((m, key, i, obj) => {
}, return m.concat(unprocessedTweetJson[i].tweet);
}, }, []);
};
const script = new vm.Script(fs.readFileSync(outputPath + '/data/tweets.js', 'utf-8')); const processedTweets = await this.recreateChain(['id_str'], ['in_reply_to_status_id_str'], tweets, false);
const context = vm.createContext(fakeWindow); this.queueService.createImportTweetsToDbJob(job.data.user, processedTweets, null);
script.runInContext(context); } else {
const tweets = Object.keys(fakeWindow.window.YTD.tweets.part0).reduce((m, key, i, obj) => { this.logger.warn('Failed to import twitter notes due to malformed file');
return m.concat(fakeWindow.window.YTD.tweets.part0[key].tweet); }
}, []);
const processedTweets = await this.recreateChain(['id_str'], ['in_reply_to_status_id_str'], tweets, false);
this.queueService.createImportTweetsToDbJob(job.data.user, processedTweets, null);
} finally { } finally {
cleanup(); cleanup();
} }