Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Detects slow synchronous execution and reports where it started.
Requires Node 8+
$ npm install blocked-at
blocked((time, stack) => {
console.log(`Blocked for ${time}ms, operation started here:`, stack)
})
The blocked()
function reports every value over the configured threshold (defaults to 20ms). Usage is similar to blocked
but the detection mechanism is different, to allow pointing to the slow function.
It uses Async Hooks to measure the time and generate the stack trace. Stack trace will point to the beginning of an asynchronously called function that contained the long operation.
Run tests (npm test
) to see examples.
There's a performance cost to enabling Async Hooks. It's recommended to detect blocking exists with something without the performance overhead and use blocked-at in testing environment to pinpoint where the slowdown happens. Rule of thumb is you should not be running this in production unless desperate.
const blocked = require('blocked-at')
const { stop } = blocked(fn, options)
option | default | description |
---|---|---|
trimFalsePositives | falsy | eliminate a class of false positives (experimental) |
threshold | 20 | minimum miliseconds of blockage to report. supported for parity with blocked |
resourcesCap | undefined | maximum amount of stack traces with resource details kept in memory. Resources are not saved by default. see the next section for details |
debug | falsy | print debug data to console |
Returns: An object with stop
method. stop()
will disable the async hooks set up by this library and callback will no longer be called.
The stack trace is pointing to a start of a function called asynchronously, so in most cases the first stack frame pointing to your code is where you need to start analyzing all synchronous operations to find the slow one.
In some cases your code is not directly called and tracking it down will still be difficult. See how the http test case produces a stack pointing to Server.connectionListener
as the slow function, because everything inside of it is synchronously called. You can always wrap your handlers' code in setImmediate
if you become desperate. Or use resources.
If you can't narrow down a blocking call to a particular function, you can try to use resourcesCap
option and inspect an associated resource:
blocked((time, stack, {type, resource}) => {
console.log(`Blocked for ${time}ms, operation started here:`, stack)
if (type === 'HTTPPARSER' && resource) {
// resource structure in this example assumes Node 10.x
console.log(`URL related to blocking operation: ${resource.resource.incoming.url}`)
}
}, {resourcesCap: 100})
Note that resource structure is a subject to change and may vary between Node versions.
Warning: Exposing resource details has a significant memory overhead, to the point of crashing the entire application due to exceeding heap limit. This is why resourcesCap
is a number -
it specifies the maximum amount of resources with details kept in memory. If this number is exceeded at runtime, you'll still get the information about blocked event loop, but resource will be undefined
.
Adjust it according to your needs. You can start arbitrarily with a 100
and decrease it if it's consuming too much memory or increase it if you don't see the details when you need them.
MIT
FAQs
Detects node eventloop block and reports where it started
We found that blocked-at 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
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.