mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[logging] Encode control chars (#169773)
This commit is contained in:
parent
fafec28398
commit
9c58bd5ec8
2 changed files with 35 additions and 10 deletions
|
@ -24,16 +24,16 @@ describe('MessageConversion', () => {
|
|||
).toEqual('Hi!\nHow are you?');
|
||||
});
|
||||
|
||||
test('it should remove ANSI chars lines from the message', () => {
|
||||
test('it should encode/escape ANSI chars lines from the message', () => {
|
||||
expect(
|
||||
MessageConversion.convert(
|
||||
{ ...baseRecord, message: 'Blinking...\u001b[5;7;6mThis is Fine\u001b[27m' },
|
||||
false
|
||||
)
|
||||
).toEqual('Blinking...This is Fine');
|
||||
).toEqual('Blinking...\\u001b[5;7;6mThis is Fine\\u001b[27m');
|
||||
});
|
||||
|
||||
test('it should remove any unicode injection from the message', () => {
|
||||
test('it should encode/escape any unicode injection from the message', () => {
|
||||
expect(
|
||||
MessageConversion.convert(
|
||||
{
|
||||
|
@ -43,6 +43,23 @@ describe('MessageConversion', () => {
|
|||
},
|
||||
false
|
||||
)
|
||||
).toEqual('ESC-INJECTION-LFUNICODE:SUCCESSFUL\n\nInjecting 10.000 lols 😂');
|
||||
).toEqual(
|
||||
'\\u001b[31mESC-INJECTION-LFUNICODE:\\u001b[32mSUCCESSFUL\\u001b[0m\\u0007\n\nInjecting 10.000 lols 😂\\u001b[10000;b\\u0007'
|
||||
);
|
||||
});
|
||||
|
||||
test('it should encode/escape any unicode injection from the message (including nullbyte)', () => {
|
||||
expect(
|
||||
MessageConversion.convert(
|
||||
{
|
||||
...baseRecord,
|
||||
message:
|
||||
'\u001b\u0000[31mESC-INJECTION-LFUNICODE:\u001b[32mSUCCESSFUL\u001b[0m\u0007\n\nInjecting 10.000 lols 😂\u001b[10000;b\u0007',
|
||||
},
|
||||
false
|
||||
)
|
||||
).toEqual(
|
||||
'\\u001b\\u0000[31mESC-INJECTION-LFUNICODE:\\u001b[32mSUCCESSFUL\\u001b[0m\\u0007\n\nInjecting 10.000 lols 😂\\u001b[10000;b\\u0007'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,20 +6,28 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import ansiRegex from 'ansi-regex';
|
||||
import { LogRecord } from '@kbn/logging';
|
||||
import { Conversion } from './types';
|
||||
|
||||
// Defining it globally because it's more performant than creating for each log entry
|
||||
// We can reuse the same global RegExp here because `.replace()` automatically resets the `.lastIndex` of the RegExp.
|
||||
const ANSI_ESCAPE_CODES_REGEXP = ansiRegex();
|
||||
// From https://www.ascii-code.com/characters/control-characters,
|
||||
// but explicitly allowing the range \u0008-\u000F (line breaks, tabs, etc.)
|
||||
const CONTROL_CHAR_REGEXP = new RegExp('[\\u0000-\\u0007\\u0010-\\u001F]', 'g');
|
||||
|
||||
export const MessageConversion: Conversion = {
|
||||
pattern: /%message/g,
|
||||
convert(record: LogRecord) {
|
||||
// Error stack is much more useful than just the message.
|
||||
const str = record.error?.stack || record.message;
|
||||
// We need to validate it's a string because, despite types, there are use case where it's not a string :/
|
||||
return typeof str === 'string' ? str.replace(ANSI_ESCAPE_CODES_REGEXP, '') : str;
|
||||
|
||||
return typeof str === 'string' // We need to validate it's a string because, despite types, there are use case where it's not a string :/
|
||||
? str.replace(
|
||||
CONTROL_CHAR_REGEXP,
|
||||
// Escaping control chars via JSON.stringify to maintain consistency with `meta` and the JSON layout.
|
||||
// This way, post analysis of the logs is easier as we can search the same patterns.
|
||||
// Our benchmark didn't show a big difference in performance between custom-escaping vs. JSON.stringify one.
|
||||
// The slice is removing the double-quotes.
|
||||
(substr) => JSON.stringify(substr).slice(1, -1)
|
||||
)
|
||||
: str;
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue