
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
Structured, easy-to-parse log messages mostly for CloudWatch
Antlog is a follow-on project to the TinLog package, which was itself a follow-on to SN-LOG. I wrote it to be used with AWS CloudWatch, though it works perfectly fine outside that environment. In the middle of a recent project I found I was downloading and processing CloudWatch logs to verify what steps had been completed by various lambdas and containerized apps. At first we depended on file names, line numbers and custom parsers to extract interesting information out of the logs. You don't want to do that.
I use SN-LOG and TinLog in previous projects. They were intended to "feel" like the old VMS MESSAGE Facility. VMS MESSAGE gave developers the ability to create message templates which were converted into an object file which was then linked into an application. Developers could then use the MSG$_ procedures to reference a specific message from the template along with pertinent data. It then produced log messages in a regular format that was easy to parse.
Fast-forward 40 years and this is still a decent idea, but there's no reason not to use JSON as it is well-supported in virtually every programming language you are likely to use. So... as a developer, what you do is to create a message template like this:
var larb_messages = {
facility: "larb",
messages: {
info: {
begin: {
message: "Application beginning",
required: [ "name" ]
},
options: {
message: "Command line options",
required: [ "options" ]
},
environment: {
message: "Environment variables",
required: [ "variables" ]
},
end: {
message: "Application exiting",
required: [ "exit" ]
}
},
debug: {
comp1: {
message: "Completed Phase 1"
},
tokenauth: {
message: "Authenticated with JWT token"
},
passauth: {
message: "Authenticated with username / password bearer token"
}
},
error: {
ddbread: {
message: "An error reading from a DynamoDB table occurred",
required: [ "table" ]
}
},
fatal: {
general: {
message: "A fatal error has occurred"
},
cli: {
message: "A fatal error parsing command line options has occurred"
},
fopen: {
message: "An error opening a file has occurred",
required: [ "name", "error" ]
}
}
}
It is then read and parsed with the antlog function:
const antlog = require( "antlog" );
[ _log, _msg ] = antlog( larb_messages );
_log( _msg.I_BEGIN, {name: "REST Access"} );
_log( _msg.I_OPTIONS, {options: process.ARGV} );
Which would print log messages that look like:
{"_f":"LARB","_s":"I","_a":"BEGIN","_d":1654711842031,"_i":"access.js","_l":5,"_m":"Application beginning","name":"REST Access"}
{"_f":"LARB","_s":"I","_a":"OPTIONS","_d":1654711842073,"_i":"access.js","_l":6,"_m":"Command line options","options":["/usr/bin/node","/opt/larb/access.js","--config","/mnt/r1/access_opts.json"]}
Each log entry will have the following "private" JSON members:
| _f | facility |
| _s | severity (I = Info, D = Debug, E = Error, F = Fatal) |
| _a | abbreviation |
| _d | date / time (msec since 1970) |
| _i | filename |
| _l | line |
| _m | message text |
If you include a JSON object as the second parameter to the _log() call, it will copy members of that object to the logged message.
And if you printed these with console.log() in a lambda, you would get CloudWatch records that look like:
2022-06-08T18:10:42.031Z\t76227c3a-e758-11ec-9045-17b456a80bd2\tINFO\t{"_f":"LARB","_s":"I","_a":"BEGIN","_d":1654711842031,"_c":"access.js","_l":5,"_m":"Application beginning","name":"REST Access"}
2022-06-08T18:10:42.073Z\t76227c3a-e758-11ec-9045-17b456a80bd2\tINFO\t{"_f":"LARB","_s":"I","_a":"OPTIONS","_d":1654711842073,"_c":"access.js","_l":6,"_m":"Command line options","options":["/usr/bin/node","/opt/larb/access.js","--config","/mnt/r1/access_opts.json"]}
And sure, that may not look all that great to you, but like I said, it's great if you're trying to parse CloudWatch logfilese because you can now use code like this to parse it:
function _log_line_to_components( line ) {
let components = line.split('\t');
try {
// Parse the text of the log message so we return
// an object, not the JSON serialization of the object.
components[ 3 ] = JSON.parse( components[ 3 ] );
} catch( err ) {
// If we catch an exception, assume it's a problem
// parsing the JSON.
components[ 3 ] = {}
}
// This returns an array with the Date string, AWS
// invocation ID, log level and logged object
return components;
}
The log descriptor passed to the antlog() call is a JSON object with the following members:
FAQs
Log JSON objects, mainly for a CloudWatch environment
We found that antlog demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.