Skip to content

Commit

Permalink
Masks IP Addresses in json responses (HAWNG-824)
Browse files Browse the repository at this point in the history
* gateway-api.ts
 * Adds response interceptor to proxy to capture the body and mask any ip
   addresses in the body string

* jolokia-agent.ts
 * Before sending back the response, ip addresses are masked in the body

* utils.ts
 * Regex matched and replacement function

* Only response that cannot be masked is the responses from the websockets
  as these are never intercepted by the express server.
  • Loading branch information
phantomjinx committed Oct 23, 2024
1 parent a53192c commit 4ca046e
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 3 deletions.
17 changes: 16 additions & 1 deletion docker/gateway/src/gateway-api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* jshint node: true */
import express from 'express'
import { createProxyMiddleware } from 'http-proxy-middleware'
import { createProxyMiddleware, responseInterceptor } from 'http-proxy-middleware'
import helmet from 'helmet'
import methodOverride from 'method-override'
import cors from 'cors'
Expand All @@ -11,6 +11,7 @@ import { logger, expressLogger } from './logger'
import { proxyMasterGuard } from './master-guard'
import { proxyJolokiaAgent } from './jolokia-agent'
import { GatewayOptions } from './globals'
import { maskIPAddresses } from './utils'

const environment = process.env.NODE_ENV || 'development'
const port = process.env.HAWTIO_ONLINE_GATEWAY_APP_PORT || 3000
Expand Down Expand Up @@ -114,6 +115,10 @@ gatewayServer.use(
changeOrigin: false,
ws: true,
secure: false,
/**
* IMPORTANT: avoid res.end being called automatically
**/
selfHandleResponse: true,

pathFilter: (path, _) => {
const result = proxyMasterGuard('/master' + path)
Expand All @@ -123,6 +128,16 @@ gatewayServer.use(
pathRewrite: (path, _) => {
return path.replace('/master', '')
},

/**
* Intercept response
**/
on: {
proxyRes: responseInterceptor(async (responseBuffer, proxyRes, req, res) => {
const jsonStr = responseBuffer.toString('utf8')
return maskIPAddresses(jsonStr)
}),
},
}),
)

Expand Down
6 changes: 4 additions & 2 deletions docker/gateway/src/jolokia-agent/jolokia-agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as fs from 'fs'
import { JolokiaRequest as MBeanRequest } from 'jolokia.js'
import { logger } from '../logger'
import { GatewayOptions } from '../globals'
import { isObject, isError } from '../utils'
import { isObject, isError, maskIPAddresses } from '../utils'
import {
AgentInfo,
InterceptedResponse,
Expand Down Expand Up @@ -62,7 +62,9 @@ function response(agentInfo: AgentInfo, res: SimpleResponse) {
*/
agentInfo.response.setHeader('content-type', 'application/json')

agentInfo.response.status(res.status).send(res.body)
const maskedResponse = maskIPAddresses(res.body)

agentInfo.response.status(res.status).send(maskedResponse)
}

function reject(status: number, body: Record<string, string>): Promise<SimpleResponse> {
Expand Down
12 changes: 12 additions & 0 deletions docker/gateway/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,15 @@ export function toStringArray(value: unknown): string[] {
export function isError(obj: unknown): obj is Error {
return obj instanceof Error
}

// IP Address Regex Matcher
const ipPattern =
/\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/gm

export function maskIPAddresses(obj: string | object): string {
let jsonStr
if (isObject(obj)) jsonStr = JSON.stringify(obj)
else jsonStr = obj

return jsonStr.replaceAll(ipPattern, '<masked>')
}

0 comments on commit 4ca046e

Please sign in to comment.