Anonymize error message (datarhei/restreamer#688)

This commit is contained in:
Ingo Oppermann 2024-02-23 17:44:10 +01:00
parent cfb70e5325
commit 82796c3801
No known key found for this signature in database
GPG Key ID: 2AB32426E9DD229E
3 changed files with 83 additions and 30 deletions

51
src/utils/anonymizer.js Normal file
View File

@ -0,0 +1,51 @@
import urlparser from 'url-parse';
const anonymize_url = (url) => {
let u = urlparser(url, true);
if (u.hostname !== 'localhost') {
return `${u.protocol}//[anonymized]`;
}
if (u.auth.length !== 0) {
u.username = '***';
u.password = '***';
}
if (u.protocol === 'rtmp:') {
if ('token' in u.query) {
u.query.token = '***';
}
} else if (u.protocol === 'srt') {
if ('streamid' in u.query) {
u.query.streamid = '***';
}
if ('passphrase' in u.query) {
u.query.passphrase = '***';
}
}
return u.toString();
};
const anonymize = (text) => {
const regex = /(?:([a-z0-9\\]+):)?\/[A-Za-z0-9-._~!$&'()*+,;=:@?/{}%\\]*/gm;
return text.replaceAll(regex, (match, scheme) => {
console.log('text', text, 'match', match, 'scheme', scheme);
if (scheme) {
match = match.replace(scheme, scheme.replaceAll('\\', ''));
return anonymize_url(match);
}
const pathElm = match.split('/').filter((p) => p.length !== 0);
if (pathElm.length < 2) {
return match;
}
return `/[anonymized]/${pathElm.pop()}`;
});
};
export { anonymize, anonymize_url };

View File

@ -11,6 +11,7 @@ import * as M from './metadata';
import * as Storage from './storage';
import * as Version from '../version';
import API from './api';
import { anonymize } from './anonymizer';
class Restreamer {
constructor(address) {
@ -3030,51 +3031,35 @@ class Restreamer {
return null;
}
const regex = /(?:([a-z]+):)?\/[^\s]*/gm;
const replace = (s) => {
return s.replaceAll(regex, (match, scheme) => {
if (scheme) {
return `${scheme}://[anonymized]`;
}
const pathElm = match.split('/').filter((p) => p.length !== 0);
if (pathElm.length < 2) {
return match;
}
return `/[anonymized]/${pathElm.pop()}`;
});
};
if (p.config) {
p.config.options = p.config.options.map(replace);
p.config.options = p.config.options.map(anonymize);
for (let i in p.config.input) {
p.config.input[i].address = replace(p.config.input[i].address);
p.config.input[i].options = p.config.input[i].options.map(replace);
p.config.input[i].address = anonymize(p.config.input[i].address);
p.config.input[i].options = p.config.input[i].options.map(anonymize);
}
for (let i in p.config.output) {
p.config.output[i].address = replace(p.config.output[i].address);
p.config.output[i].options = p.config.output[i].options.map(replace);
p.config.output[i].address = anonymize(p.config.output[i].address);
p.config.output[i].options = p.config.output[i].options.map(anonymize);
}
}
if (p.state) {
for (let i in p.state.progress.inputs) {
p.state.progress.inputs[i].address = replace(p.state.progress.inputs[i].address);
p.state.progress.inputs[i].address = anonymize(p.state.progress.inputs[i].address);
}
for (let i in p.state.progress.outputs) {
p.state.progress.outputs[i].address = replace(p.state.progress.outputs[i].address);
p.state.progress.outputs[i].address = anonymize(p.state.progress.outputs[i].address);
}
if (!p.state.command) {
p.state.command = [];
}
p.state.command = p.state.command.map(replace);
p.state.last_logline = replace(p.state.last_logline);
p.state.command = p.state.command.map(anonymize);
p.state.last_logline = anonymize(p.state.last_logline);
}
if (p.report) {
@ -3082,12 +3067,12 @@ class Restreamer {
p.report.prelude = [];
}
p.report.prelude = p.report.prelude.map(replace);
p.report.log = p.report.log.map((l) => [l[0], replace(l[1])]);
p.report.prelude = p.report.prelude.map(anonymize);
p.report.log = p.report.log.map((l) => [l[0], anonymize(l[1])]);
for (let i in p.report.history) {
p.report.history[i].prelude = p.report.history[i].prelude.map(replace);
p.report.history[i].log = p.report.history[i].log.map((l) => [l[0], replace(l[1])]);
p.report.history[i].prelude = p.report.history[i].prelude.map(anonymize);
p.report.history[i].log = p.report.history[i].log.map((l) => [l[0], anonymize(l[1])]);
}
}
@ -3348,6 +3333,20 @@ class Restreamer {
config.storage.memory.auth.username = '[anonymized]';
config.storage.memory.auth.password = '[anonymized]';
config.storage.s3 = config.storage.s3.map((e) => {
return {
...e,
auth: {
...e.auth,
username: '[anonymized]',
password: '[anonymized]',
},
endpoint: '[anonymized]',
access_key_id: '[anonymized]',
secret_access_key: '[anonymized]',
};
});
if (config.storage.cors.origins.length !== 1 || config.storage.cors.origins[0] !== '*') {
config.storage.cors.origins = config.storage.cors.origins.map((e) => '[anonymized]');
}
@ -3355,6 +3354,8 @@ class Restreamer {
config.rtmp.app = '[anonymized]';
config.rtmp.token = '[anonymized]';
config.ffmpeg.binary = anonymize(config.ffmpeg.binary);
config.service.token = '[anonymized]';
config.sessions.ip_ignorelist = config.sessions.ip_ignorelist.map((e) => '[anonymized]');

View File

@ -11,6 +11,7 @@ import Typography from '@mui/material/Typography';
import WarningIcon from '@mui/icons-material/Warning';
import * as M from '../../utils/metadata';
import { anonymize } from '../../utils/anonymizer';
import useInterval from '../../hooks/useInterval';
import ActionButton from '../../misc/ActionButton';
import CopyButton from '../../misc/CopyButton';
@ -350,7 +351,7 @@ export default function Main(props) {
</Grid>
<Grid item>
<Typography>
<Trans>Error: {$state.progress.error || 'unknown'}</Trans>
<Trans>Error: {anonymize($state.progress.error) || 'unknown'}</Trans>
</Typography>
</Grid>
<Grid item>