mirror of
https://github.com/log4js-node/log4js-node.git
synced 2025-12-08 19:26:01 +00:00
feat: new crlfFilter appender to prevent log forging
This commit is contained in:
parent
8fd25d55e1
commit
e337bcdb8f
@ -23,6 +23,7 @@ The following appenders are included with log4js. Some require extra dependencie
|
||||
|
||||
- [categoryFilter](categoryFilter.md)
|
||||
- [console](console.md)
|
||||
- [crlfFilter](crlfFilter.md)
|
||||
- [dateFile](dateFile.md)
|
||||
- [file](file.md)
|
||||
- [fileSync](fileSync.md)
|
||||
|
||||
36
docs/crlfFilter.md
Normal file
36
docs/crlfFilter.md
Normal file
@ -0,0 +1,36 @@
|
||||
# CRLF Filter
|
||||
|
||||
This is not strictly an appender - it wraps around another appender and to prevent log forging by replacing starting the line with a `>` prefix after line-breaks.
|
||||
|
||||
## Configuration
|
||||
|
||||
- `type` - `"crlfFilter"`
|
||||
- `appender` - `string | Array<String>` - the name of the appender to filter. (exists for backward compatibility)
|
||||
- `appenders` - `string | Array<String>` - the names of the appenders to filter.
|
||||
|
||||
## Example
|
||||
|
||||
```javascript
|
||||
log4js.configure({
|
||||
appenders: {
|
||||
everything: { type: "file", filename: "all-the-logs.log" },
|
||||
crlfFilter: {
|
||||
type: "crlfFilter",
|
||||
appenders: ["everything"],
|
||||
},
|
||||
},
|
||||
categories: {
|
||||
default: { appenders: ["crlfFilter"], level: "debug" },
|
||||
},
|
||||
});
|
||||
|
||||
const logger = log4js.getLogger();
|
||||
logger.info(
|
||||
"Some debug messages\n[2023-01-17T11:58:38.150] [INFO] default - Log forging"
|
||||
);
|
||||
```
|
||||
|
||||
```
|
||||
[2023-01-17T11:58:38.150] [INFO] default - Some debug messages
|
||||
> [2023-01-17T11:58:38.150] [INFO] default - Log forging
|
||||
```
|
||||
47
lib/appenders/crlfFilter.js
Normal file
47
lib/appenders/crlfFilter.js
Normal file
@ -0,0 +1,47 @@
|
||||
const debug = require('debug')('log4js:crlfFilter');
|
||||
|
||||
function crlfFilter(appenders) {
|
||||
return (logEvent) => {
|
||||
const filteredData = logEvent.data.map((i) => {
|
||||
if (typeof i.replace === 'function') return i.replace(/\n/g, '\n> '); // add a > prefix
|
||||
return i;
|
||||
});
|
||||
logEvent.data = filteredData;
|
||||
appenders.forEach((appender) => {
|
||||
appender(logEvent);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function configure(config, layouts, findAppender) {
|
||||
const addToSet = function (input, set = new Set()) {
|
||||
const addAppender = function (appenderName) {
|
||||
debug(`actual appender is ${appenderName}`);
|
||||
const appender = findAppender(appenderName);
|
||||
if (!appender) {
|
||||
debug(`actual appender "${config.appender}" not found`);
|
||||
throw new Error(`crlfFilter appender "${config.appender}" not defined`);
|
||||
} else {
|
||||
set.add(appender);
|
||||
}
|
||||
};
|
||||
|
||||
if (input && !Array.isArray(input)) input = [input];
|
||||
if (input) input.forEach((appenderName) => addAppender(appenderName));
|
||||
|
||||
return set;
|
||||
};
|
||||
|
||||
const appenders = new Set();
|
||||
addToSet(config.appender, appenders);
|
||||
addToSet(config.appenders, appenders);
|
||||
|
||||
if (appenders.size === 0) {
|
||||
debug(`no appender found in config ${config}`);
|
||||
throw new Error('crlfFilter appender must have an "appender" defined');
|
||||
}
|
||||
|
||||
return crlfFilter(appenders);
|
||||
}
|
||||
|
||||
module.exports.configure = configure;
|
||||
Loading…
x
Reference in New Issue
Block a user