Improve logging pattern schema validation (#200317)

## Summary

This makes pattern schema validation stricter by avoiding unrestricted
matching, enforces realistic timezone constraints, and sets an upper
bound to the date format string.

| Characteristic | Before | After |
----|----|----|
| Optional Groups | Capturing groups for optional sections. |
Non-capturing groups for optional sections.|
|Timezone Validation | Allows any characters except }. | Restricts to
A-Za-z/_+-.|
|Clarity | More complex and verbose. | Cleaner, more restrictive, and
simpler.|
|Performance | Captures unnecessary groups. | Limits captures to needed
named groups.|

---------

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Christiane (Tina) Heiligers 2024-11-18 07:47:29 -07:00 committed by GitHub
parent d910e5e8a3
commit c7bcc5c408
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 17 additions and 2 deletions

View file

@ -12,7 +12,7 @@ import { last } from 'lodash';
import { LogRecord } from '@kbn/logging';
import { Conversion } from './types';
const dateRegExp = /%date({(?<format>[^}]+)})?({(?<timezone>[^}]+)})?/g;
const dateRegExp = /%date(?:\{(?<format>[^}]+)\})?(?:\{(?<timezone>[A-Za-z/_+-]+)\})?/g;
const formats = {
ISO8601: 'ISO8601',
@ -29,7 +29,6 @@ function formatDate(
): string {
const momentDate = moment(date);
momentDate.tz(timezone ?? moment.tz.guess());
switch (dateFormat) {
case formats.ISO8601:
return momentDate.toISOString();

View file

@ -326,6 +326,21 @@ describe('schema', () => {
`"Date format expected one of ISO8601, ISO8601_TZ, ABSOLUTE, UNIX, UNIX_MILLIS, but given: HH"`
);
});
it('fails on %date with schema too long', () => {
const generateLongFormat = () => {
const longFormat = [];
for (let i = 1; i < 1001; i++) {
longFormat.push(`${i}`);
}
return longFormat.join('');
};
expect(() =>
patternSchema.validate(`%date${generateLongFormat()}`)
).toThrowErrorMatchingInlineSnapshot(
`"value has length [2898] but it must have a maximum length of [1000]."`
);
});
});
});
});

View file

@ -24,6 +24,7 @@ import {
const DEFAULT_PATTERN = `[%date][%level][%logger] %message`;
export const patternSchema = schema.string({
maxLength: 1000,
validate: (string) => {
DateConversion.validate!(string);
},