HIGH out of bounds readhapijavascript

Out Of Bounds Read in Hapi (Javascript)

Out Of Bounds Read in Hapi with Javascript

In the Hapi framework, which runs on Node.js, an Out Of Bounds Read vulnerability typically arises when code attempts to access an array or object property using an index or key that does not exist, but the runtime does not immediately throw an error due to unsafe property access patterns.

When combined with JavaScript's flexible property access and prototype chain, this can lead to unintended data exposure. For example, if a route handler uses bracket notation with a user-supplied value to access an internal configuration object, and that value is not validated, the application may inadvertently expose internal keys or trigger prototype pollution.

Consider a Hapi route that processes JSON input and accesses a configuration field based on a request parameter:

server.route({
  method: 'POST',
  path: '/config',
  handler: (request, h) => {
    const { configKey } = request.payload;
    // Insecure: directly accessing config[configKey] without validation
    const value = server.settings[configKey];
    return { configValue: value };
  }
});

If an attacker sends a payload like { "configKey": "undefined"/**/apiKey */}", and the server evaluates it in a context where prototype pollution is possible, or if the key is used dynamically in a way that bypasses checks, the application may resolve to unintended properties, potentially leaking sensitive configuration values such as API keys or database credentials.

This pattern is especially dangerous when the code relies on implicit property resolution without strict validation. In JavaScript, accessing a non-existent property in a plain object returns undefined, but if the property name is constructed from user input and used in a context that triggers prototype lookups (e.g., Object.prototype[userKey]), it can lead to information disclosure or indirect privilege escalation.

Additionally, Hapi plugins that process headers, query parameters, or multipart data may pass unsanitized strings into property access logic. If a plugin uses dynamic property access to retrieve metadata (e.g., for logging or routing), and that metadata includes sensitive internal states, an out-of-bounds read could expose data that should remain private.

While not always a direct memory read like in native languages, the semantic effect in JavaScript — accessing a non-existent or unintended property and using its value in a way that leaks internal structure — constitutes an out-of-bounds read from a security perspective, especially when it leads to data exposure or logic bypass.

The risk is heightened in Hapi when plugins or server configurations expose internal objects through dynamic key resolution, and when input validation is inconsistent across middleware layers.

Javascript-Specific Remediation in Hapi

To prevent out-of-bounds reads in Hapi using JavaScript, strict validation of dynamic property access is required. Always validate or sanitize keys used to access internal objects, and avoid direct dynamic property resolution on untrusted input.

Use a whitelist of allowed configuration keys and validate user input before using it as a property name:

const ALLOWED_CONFIG_KEYS = new Set(['databaseUrl', 'apiKey', 'logLevel']);

server.route({
  method: 'POST',
  path: '/config',
  handler: (request, h) => {
    const { configKey } = request.payload;
    
    // Validate against allowed keys
    if (!ALLOWED_CONFIG_KEYS.has(configKey)) {
      return h.response({ error: 'Invalid config key' }).code(400);
    }
    
    const value = server.settings[configKey];
    if (value === undefined) {
      return h.response({ error: 'Key not found' }).code(404);
    }
    
    return { configValue: value };
  }
});

Additionally, avoid using bracket notation with user input on objects that may have prototype chains. Use plain objects without prototype extension, and prefer structured access patterns.

For deeper inspection, use Object.keys(), Object.getOwnPropertyNames(), or a mapping object to safely resolve properties. Never allow user input to control property access on sensitive objects like process.env, server.plugins, or internal state.

When building plugins or middleware, isolate dynamic access to clearly defined scopes and avoid passing raw request data into object access logic. Use defensive checks such as:

const safeAccess = (obj, key) => {
  return Object.prototype.hasOwnProperty.call(obj, key) ? obj[key] : undefined;
};

// Usage
const value = safeAccess(server.settings, configKey);
if (value === undefined) { /* handle missing safely */ }

These practices eliminate the risk of unintended property access and prevent data exposure through malformed input.