Api Key Exposure in Feathersjs with Mssql
Api Key Exposure in Feathersjs with Mssql — how this specific combination creates or exposes the vulnerability
FeathersJS is a framework for rapidly building JavaScript APIs. When FeathersJS services are configured to connect to Microsoft SQL Server (Mssql) without strict controls, API keys and other secrets can be exposed through insecure service configuration, dynamic query construction, or improper authentication handling. The combination of FeathersJS hooks and Mssql drivers introduces specific risks if runtime values containing sensitive data are logged, reflected in error messages, or passed through unvalidated parameters.
Consider a FeathersJS service that builds dynamic Mssql queries by interpolating user input into SQL strings. If an API key is stored in an environment variable but accidentally included in logs or error responses, an authenticated or unauthentinated attacker could extract it via crafted requests that trigger verbose errors or debug endpoints. For example, a misconfigured hook might append trace information to query results, inadvertently exposing tokens that were intended only for backend service-to-service communication.
Another exposure path is through OpenAPI/Swagger introspection when endpoints expose parameters that should remain internal. If a FeathersJS app exposes an endpoint that accepts an Authorization header or an X-API-Key header and echoes it in responses or logs, scanning with a tool that includes Data Exposure checks can identify such leakage. This is particularly relevant when Mssql connection strings or keys are embedded in request metadata or query options that are returned in API responses.
LLM/AI Security checks are valuable here because they can detect system prompt leakage patterns that might occur if error messages or debug data contain structured hints resembling internal instructions or key names. For Mssql-backed FeathersJS services, ensuring that sensitive values are never reflected in responses, logs, or stack traces is essential. Using parameterized queries and strict input validation prevents injection and reduces the likelihood that keys or tokens are mishandled through malformed requests.
middleBrick scans this attack surface without authentication, testing endpoints that may inadvertently expose keys through verbose errors or insecure configurations. The scan includes checks against Data Exposure and Input Validation, mapping findings to frameworks such as OWASP API Top 10 and PCI-DSS. If your API involves FeathersJS with Mssql, running a scan helps identify whether API keys or other secrets are reflected in outputs or logs, allowing you to remediate before sensitive data is exposed in production environments.
Mssql-Specific Remediation in Feathersjs — concrete code fixes
Remediation focuses on preventing sensitive data from being logged, echoed, or constructed via string interpolation. Use parameterized queries with the tedious or mssql libraries to ensure user input never becomes part of the SQL string. Configure FeathersJS hooks to sanitize and validate inputs, and ensure that environment variables containing keys are accessed securely without being attached to logs or error objects.
Below are concrete, working examples for a FeathersJS service that connects to Mssql safely.
const feathers = require('@feathersjs/feathers');
const express = require('@feathersjs/express');
const { Sequelize } = require('sequelize-typescript');
const { mssql } = require('feathers-hooks-common');
const app = express(feathers());
// Secure configuration: keep connection details out of code
const sequelize = new Sequelize({
dialect: 'mssql',
host: process.env.MSSQL_HOST,
port: parseInt(process.env.MSSQL_PORT || '1433', 10),
database: process.env.MSSQL_DATABASE,
username: process.env.MSSQL_USER,
password: process.env.MSSQL_PASSWORD,
logging: false // disable verbose query logging in production
});
app.configure(express.rest());
app.configure(express.socketio());
// Example service with safe Mssql handling
app.use('/records', {
async find(params) {
const { search } = params.query;
// Use parameterized query to avoid injection and prevent key exposure
const results = await sequelize.query(
'SELECT id, name, category FROM records WHERE category = @category',
{ replacements: { category: search || 'general' }, type: sequelize.QueryTypes.SELECT }
);
return results;
},
async get(id, params) {
const result = await sequelize.query(
'SELECT id, name, metadata FROM records WHERE id = @id',
{ replacements: { id }, type: sequelize.QueryTypes.SELECT }
);
if (!result.length) {
throw new Error('Not found');
}
return result[0];
}
});
// Hook to sanitize and avoid logging sensitive data
app.hooks({
before: {
all: [],
find: [context => {
// Ensure no API key is appended to the context or response
if (context.params.query && context.params.query.api_key) {
delete context.params.query.api_key;
}
return context;
}],
get: [context => {
if (context.params.query && context.params.query.api_key) {
delete context.params.query.api_key;
}
return context;
}]
},
after: {
all: [context => {
// Prevent keys from leaking in responses
if (context.result && context.result.apiKey) {
delete context.result.apiKey;
}
return context;
}],
error: [context => {
// Avoid exposing stack traces or internal values
if (context.error && context.error.message) {
context.error.message = 'An error occurred';
}
return context;
}]
}
});
module.exports = app;
In this example, the Sequelize instance is configured with logging: false to prevent SQL and sensitive values from appearing in console output. Parameterized queries using replacements ensure that user input never concatenates directly into SQL strings, reducing injection risks that could lead to key exposure. Hooks explicitly remove any api_key from query parameters and strip sensitive fields from responses and errors, aligning with Data Exposure checks that middleBrick performs.
For production, ensure environment variables are managed outside the codebase and that connection strings do not contain embedded keys. middleBrick’s CLI can be used to validate these configurations by scanning your endpoints and confirming that no API keys appear in logs, error messages, or response bodies. The CLI outputs structured findings with severity and remediation guidance, helping you prioritize fixes for Mssql-related exposures in FeathersJS services.
middleBrick’s GitHub Action can enforce a minimum security score in CI/CD, failing builds if risk levels exceed your threshold. This ensures that regressions which might reintroduce key exposure are caught before deployment. Combining runtime-safe query practices with automated scanning provides a robust approach to protecting API keys when FeathersJS interacts with Mssql.