HIGH insufficient loggingfeathersjsmongodb

Insufficient Logging in Feathersjs with Mongodb

Insufficient Logging in Feathersjs with Mongodb — how this specific combination creates or exposes the vulnerability

FeathersJS is a framework for real-time APIs that typically sits as a service layer in front of databases such as MongoDB. Insufficient logging in this stack means events like authentication attempts, data mutations, and authorization failures are not recorded with sufficient context for later investigation. When FeathersJS calls MongoDB via an adapter (e.g., feathers-mongodb) or a custom hook, the absence of structured logs removes visibility into which user or service invoked an operation, what document was targeted, and whether the request matched expected patterns.

In a typical FeathersJS + MongoDB setup, hooks provide a central place to add logging, but if developers omit audit entries or do not log key fields (user ID, resource ID, outcome), attackers can probe endpoints without leaving evidence. This becomes especially risky when combined with permissive MongoDB configurations that allow a broad set of operations; without logs, abuse such as privilege escalation via BOLA/IDOR or unsafe data exports may go unnoticed. Attackers can also leverage weak logging to perform reconnaissance: by observing differences in response timing or error messages, they infer whether specific operations were processed or rejected, which can feed into further exploitation chains such as injection or SSRF.

Compliance frameworks such as OWASP API Top 10 A03:2023 (Injection) and A09:2023 (Security Logging) highlight the importance of audit trails for detecting and forensically analyzing attacks. In PCI-DSS and SOC2 contexts, insufficient logging can prevent effective incident response and breach detection. With FeathersJS, because service logic often resides in JavaScript/TypeScript hooks rather than in the database itself, responsibility for robust logging falls on the application developer. If hooks do not explicitly record input validation results, authorization decisions, and MongoDB operation responses (including error codes), teams lose the ability to correlate suspicious API requests with downstream database actions.

Consider an endpoint that updates a user profile via a PATCH request handled by a FeathersJS service. If the hook does not log the authenticated subject’s identity, the profile identifier, and the pre/post images of the document, an attacker who modifies another user’s ID in the payload (BOLA) cannot be reliably traced. Similarly, if MongoDB driver-level errors are swallowed or masked to avoid information leakage without being recorded internally, defenders lose insight into malformed queries that may indicate injection attempts. The combination of FeathersJS’s event-driven hooks and MongoDB’s flexible document model amplifies the impact of missing logs because there are more surfaces where context can be lost if instrumentation is incomplete.

Effective logging in this context must capture: the request path and method, the authenticated principal (or lack thereof), query parameters and payload metadata, the MongoDB collection and filter used, the operation type (find, insert, update, delete), the outcome (success/failure with error code), and any validation or authorization checks performed. This data should be emitted in a structured, time-synchronized format that can be ingested by external monitoring systems. Without it, even if the API returns correct HTTP statuses, the lack of forensic detail undermines detection, triage, and post-incident analysis.

Mongodb-Specific Remediation in Feathersjs — concrete code fixes

Remediation centers on instrumenting FeathersJS hooks to emit detailed, tamper-resistant logs for every interaction with MongoDB. Use a dedicated logger that supports structured JSON output and ensure that logs are forwarded to a centralized system where they can be retained and analyzed. Below are specific code examples for a FeathersJS service using the official MongoDB adapter.

1. Adding audit logging to a service hook

In your service hook (e.g., src/hooks/audit.js), capture key identifiers and outcomes before and after the MongoDB operation. This example logs authentication-sensitive actions and documents the filter and result summary.

const { v4: uuidv4 } = require('uuid');

module.exports = function auditLogger(options = {}) {
  return async context => {
    const start = Date.now();
    const { user } = context.params || {};
    const userId = user && user._id ? user._id.toString() : 'anonymous';
    const serviceName = context.service ? context.service.path : 'unknown';
    const method = context.method; // 'find', 'create', 'update', 'patch', 'remove'
    const id = context.id ? context.id.toString() : (context.data && context.data._id ? context.data._id.toString() : null);

    // Minimal pre-log before operation
    const preLog = {
      id: uuidv4(),
      timestamp: new Date().toISOString(),
      level: 'info',
      event: 'api_request_start',
      service: serviceName,
      method,
      userId,
      resourceId: id,
      path: context.path,
      query: typeof context.params.query === 'object' ? context.params.query : {}
    };
    context.app.get('logger').info(preLog);

    try {
      const result = await context.app.service(serviceName)._mongodb[method](context.params);
      const duration = Date.now() - start;
      const postLog = {
        id: uuidv4(),
        timestamp: new Date().toISOString(),
        level: 'info',
        event: 'api_request_complete',
        service: serviceName,
        method,
        userId,
        resourceId: id,
        durationMs: duration,
        outcome: 'success'
      };
      context.app.get('logger').info(postLog);
      return result;
    } catch (error) {
      const duration = Date.now() - start;
      const errorLog = {
        id: uuidv4(),
        timestamp: new Date().toISOString(),
        level: 'error',
        event: 'api_request_error',
        service: serviceName,
        method,
        userId,
        resourceId: id,
        durationMs: duration,
        outcome: 'failure',
        errorCode: error.code || 'UNKNOWN',
        errorMessage: error.message,
        stack: options.includeStackTraces ? error.stack : undefined
      };
      context.app.get('logger').error(errorLog);
      throw error;
    }
  };
};

2. MongoDB-specific details in logs

Ensure that logs include the namespace (database and collection) and, where safe and useful, a sanitized representation of the filter and update payload. Avoid logging full documents containing PII. For native MongoDB driver errors, capture error codes to distinguish duplication (11000) from network issues or authentication failures.

// Example logger integration using a Winston transport that outputs JSON
const winston = require('winston');
const logger = winston.createLogger({
  level: 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.json()
  ),
  transports: [
    new winston.transports.Console(),
    // Add file or external transport as needed
  ]
});

// Assign to Feathers so hooks can access it
app.set('logger', logger);

3. Centralized log management and alerting

Forward logs to a SIEM or log analytics platform and define rules for suspicious patterns such as repeated authentication failures for the same user, unexpected service access by an unauthenticated context, or high rates of update operations on sensitive collections. MiddleBrick’s dashboard can ingest these logs to track security scores and findings, helping you correlate runtime behavior with configuration issues.

Frequently Asked Questions

How can I verify that my logging is capturing MongoDB operation outcomes without exposing sensitive data?
Implement structured logging that records operation type, filter keys (e.g., _id), outcome, and error codes while redacting or omitting full documents. Use a logger that supports JSON output and forward logs to a secure analysis platform for review.
Is it enough to rely on MongoDB’s built-in logging, or do I need application-level logs in FeathersJS?
MongoDB server logs provide database-side visibility but lack application context such as authenticated identity and business-level intent. Application-level logs in FeathersJS hooks are necessary to trace requests end-to-end and to correlate API behavior with user actions.