Core 03 - OS Module
Table of Contents
- Basic Idea
- System Information
- User and System Directories
- Platform Identification
- User Info and Network Interfaces
- Uptime and Load
- Endianness and Priority
- Security Sensitive APIs
- Summary
- Prerequisites
Basic Idea
You need to know what machine your code is running on
CPU cores for worker pool sizing , memory for cache limits , network interfaces for binding
os module gives you all the system-level intel without writing platform-specific shell commands
System Information
const os = require('os')
// CPU - for sizing thread pools
const cpus = os.cpus()
console.log('CPU count:', cpus.length)
console.log('Model:', cpus[0].model) // e.g., AMD Ryzen 9 7950X
console.log('Speed:', cpus[0].speed, 'MHz')
// Memory
console.log('Total RAM:', os.totalmem() / 1024 / 1024 / 1024, 'GB')
console.log('Free RAM:', os.freemem() / 1024 / 1024 / 1024, 'GB')
console.log('Used:', (os.totalmem() - os.freemem()) / 1024 / 1024 / 1024, 'GB')
cpus() returns an array with info for each logical core - including hyperthreads
Don’t confuse logical cores with physical cores
If you’re spawning workers , os.cpus().length is your upper bound
User and System Directories
// home directory - usually /home/user on Linux
console.log('Home:', os.homedir())
// /home/mahmoud
// temp directory - for ephemeral files
console.log('Temp:', os.tmpdir())
// /tmp
// hostname - useful for logging and distributed tracing
console.log('Hostname:', os.hostname())
// kali-2025
homedir() reads the HOME environment variable
On Windows it reads USERPROFILE - which might not exist in all contexts like Windows services
tmpdir() follows the OS convention - /tmp on Linux , %TEMP% on Windows
Platform Identification
console.log('Platform:', os.platform()) // linux, darwin, win32
console.log('Arch:', os.arch()) // x64, arm64, ia32
console.log('Release:', os.release()) // 6.8.0-45-generic
// practical - conditional logic per platform
switch (os.platform()) {
case 'linux':
// use /dev/null or /proc
break
case 'win32':
// use NUL or %SystemRoot%
break
case 'darwin':
// macOS stuff
break
}
os.platform() returns one of: 'aix', 'darwin', 'freebsd', 'linux', 'openbsd', 'sunos', 'win32'
Don’t confuse with process.arch which returns 'x64' , 'arm64' , etc
User Info and Network Interfaces
// user info - username , uid , gid , shell , homedir
const user = os.userInfo()
console.log('Username:', user.username)
console.log('UID:', user.uid)
console.log('Shell:', user.shell) // /bin/bash
// network interfaces
const nets = os.networkInterfaces()
for (const [name, addrs] of Object.entries(nets)) {
console.log(`Interface ${name}:`)
for (const addr of addrs) {
if (addr.family === 'IPv4') {
console.log(` ${addr.address}/${addr.netmask}`)
}
}
}
networkInterfaces() returns internal network topology - every adapter and every address
Good for finding which IP your service should bind to
Careful with userInfo() - it leaks system usernames which are often reused across services
Uptime and Load
// system uptime in seconds
console.log('Uptime:', os.uptime(), 'seconds')
console.log('Uptime:', Math.floor(os.uptime() / 3600), 'hours')
// load averages - 1, 5, 15 minutes
const [one, five, fifteen] = os.loadavg()
console.log(`Load: ${one.toFixed(2)} / ${five.toFixed(2)} / ${fifteen.toFixed(2)}`)
loadavg() returns the traditional Unix load averages
On Linux these include all processes - not just CPU bound ones
A load of 16 on a 8-core machine means the system is slammed
On Windows this returns [0, 0, 0] because Windows doesn’t have load averages - good luck
Endianness and Priority
// byte order - BE or LE
console.log('Endianness:', os.endianness())
// LE on virtually everything you'll touch
// process priority - only on POSIX systems
os.setPriority(0, -10) // lower nice value = higher priority
console.log('Current priority:', os.getPriority(0))
Most developers will never touch endianness until they interface with binary protocols or hardware
setPriority(0, ...) modifies the current process
Negative values require root or appropriate capabilities
Security Sensitive APIs
// os.userInfo() exposes system usernames
const { username } = os.userInfo()
// If your app crashes and dumps this into logs + error messages
// that's a username leak - combine with path traversal for exploitation
// os.networkInterfaces() shows internal IP topology
const ifaces = JSON.stringify(os.networkInterfaces(), null, 2)
// Don't expose this in API responses unless you want to help attackers map your internal network
userInfo() and networkInterfaces() are common information disclosure vectors
Never expose raw OS module output in error messages , debug endpoints , or logs
A /debug route that returns os.networkInterfaces() is basically a free recon pass for attackers
Summary
cpus().lengthfor worker pool sizingplatform()andarch()for conditional code pathsfreemem()andloadavg()for health checks- Never expose
userInfo()ornetworkInterfaces()in API responses
Prerequisites
next -> core_04_events
Posted · Updated