chore: introduce jsmasker to mask sensitive debug logging data.

This commit is contained in:
Bill Church 2024-08-20 19:42:06 +00:00
parent 01e312d701
commit 46338e4f2c
No known key found for this signature in database
5 changed files with 15 additions and 45 deletions

View file

@ -6,7 +6,8 @@ const express = require("express")
const router = express.Router() const router = express.Router()
const handleConnection = require("./connectionHandler") const handleConnection = require("./connectionHandler")
const basicAuth = require("basic-auth") const basicAuth = require("basic-auth")
const { sanitizeObject, validateSshTerm } = require("./utils") const { validateSshTerm } = require("./utils")
const maskObject = require('jsmasker');
const validator = require("validator") const validator = require("validator")
function auth(req, res, next) { function auth(req, res, next) {
@ -63,7 +64,7 @@ router.get("/host/:host", auth, function (req, res) {
req.session.usedBasicAuth = true req.session.usedBasicAuth = true
// Sanitize and log the sshCredentials object // Sanitize and log the sshCredentials object
const sanitizedCredentials = sanitizeObject( const sanitizedCredentials = maskObject(
JSON.parse(JSON.stringify(req.session.sshCredentials)) JSON.parse(JSON.stringify(req.session.sshCredentials))
) )
debug("/ssh/host/ Credentials: ", sanitizedCredentials) debug("/ssh/host/ Credentials: ", sanitizedCredentials)

View file

@ -2,11 +2,12 @@
// app/socket.js // app/socket.js
"use strict" "use strict"
var createDebug = require("debug") const createDebug = require("debug")
var debug = createDebug("webssh2:socket") const debug = createDebug("webssh2:socket")
var SSHConnection = require("./ssh") const SSHConnection = require("./ssh")
var { sanitizeObject, validateSshTerm } = require("./utils") const { validateSshTerm } = require("./utils")
var validator = require("validator") const maskObject = require('jsmasker');
const validator = require("validator")
module.exports = function (io, config) { module.exports = function (io, config) {
io.on("connection", function (socket) { io.on("connection", function (socket) {
@ -30,7 +31,7 @@ module.exports = function (io, config) {
* @param {Object} config - The configuration object. * @param {Object} config - The configuration object.
*/ */
function handleAuthenticate(creds) { function handleAuthenticate(creds) {
debug("handleAuthenticate: " + socket.id + ", %O", sanitizeObject(creds)) debug("handleAuthenticate: " + socket.id + ", %O", maskObject(creds))
if (isValidCredentials(creds)) { if (isValidCredentials(creds)) {
sessionState.term = validateSshTerm(creds.term) sessionState.term = validateSshTerm(creds.term)
@ -65,7 +66,7 @@ module.exports = function (io, config) {
", INITIALIZING SSH CONNECTION: Host: " + ", INITIALIZING SSH CONNECTION: Host: " +
creds.host + creds.host +
", creds: %O", ", creds: %O",
sanitizeObject(creds) maskObject(creds)
) )
ssh ssh
@ -392,7 +393,7 @@ module.exports = function (io, config) {
", Host: " + ", Host: " +
creds.host + creds.host +
": HTTP Basic Credentials Exist, creds: %O", ": HTTP Basic Credentials Exist, creds: %O",
sanitizeObject(creds) maskObject(creds)
) )
handleAuthenticate(creds) handleAuthenticate(creds)
} else if (!sessionState.authenticated) { } else if (!sessionState.authenticated) {

View file

@ -5,7 +5,7 @@
const createDebug = require("debug") const createDebug = require("debug")
const debug = createDebug("webssh2:ssh") const debug = createDebug("webssh2:ssh")
const SSH = require("ssh2").Client const SSH = require("ssh2").Client
const { sanitizeObject } = require("./utils") const maskObject = require('jsmasker');
function SSHConnection(config) { function SSHConnection(config) {
this.config = config this.config = config
@ -16,7 +16,7 @@ function SSHConnection(config) {
SSHConnection.prototype.connect = function(creds) { SSHConnection.prototype.connect = function(creds) {
var self = this var self = this
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
debug("connect: %O", sanitizeObject(creds)) debug("connect: %O", maskObject(creds))
if (self.conn) { if (self.conn) {
self.conn.end() self.conn.end()

View file

@ -4,38 +4,6 @@ const validator = require("validator")
const createDebug = require("debug") const createDebug = require("debug")
const debug = createDebug("webssh2:utils") const debug = createDebug("webssh2:utils")
/**
* Sanitizes an object by replacing sensitive properties with asterisks.
* @param {Object} obj - The object to sanitize.
* @param {Array} [properties=['password', 'key', 'secret', 'token']] - The list of properties to sanitize.
* @returns {Object} - The sanitized object.
*/
function sanitizeObject(
obj,
properties = ["password", "key", "secret", "token"]
) {
if (obj && typeof obj === "object") {
const copy = Array.isArray(obj) ? [] : Object.assign({}, obj)
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
// eslint-disable-line no-prototype-builtins
if (properties.includes(key) && typeof obj[key] === "string") {
copy[key] = "*".repeat(obj[key].length)
} else if (typeof obj[key] === "object") {
copy[key] = sanitizeObject(obj[key], properties)
} else {
copy[key] = obj[key]
}
}
}
return copy
}
return obj
}
/** /**
* Validates the SSH terminal name using validator functions. * Validates the SSH terminal name using validator functions.
* Allows alphanumeric characters, hyphens, and periods. * Allows alphanumeric characters, hyphens, and periods.
@ -54,5 +22,4 @@ function validateSshTerm(term) {
) )
} }
exports.sanitizeObject = sanitizeObject
exports.validateSshTerm = validateSshTerm exports.validateSshTerm = validateSshTerm

View file

@ -39,6 +39,7 @@
"express": "^4.14.1", "express": "^4.14.1",
"express-session": "^1.18.0", "express-session": "^1.18.0",
"express-socket.io-session": "^1.3.5", "express-socket.io-session": "^1.3.5",
"jsmasker": "^1.1.2",
"read-config-ng": "~3.0.7", "read-config-ng": "~3.0.7",
"socket.io": "~2.2.0", "socket.io": "~2.2.0",
"ssh2": "~0.8.9", "ssh2": "~0.8.9",