Api Key Exposure in Restify
How Api Key Exposure Manifests in Restify
Api key exposure in Restify applications typically occurs through several Restify-specific code patterns and architectural decisions. Understanding these patterns is crucial for both detection and remediation.
The most common manifestation is through hardcoded API keys in route handlers. Restify developers often embed keys directly in middleware or route definitions:
const server = restify.createServer();
// Vulnerable: hardcoded API key
const API_KEY = 'sk-1234567890';
server.use((req, res, next) => {
const authKey = req.header('x-api-key');
if (authKey !== API_KEY) {
return next(new restify.UnauthorizedError('Invalid API key'));
}
next();
});
Another Restify-specific pattern involves improper use of the server.authorizationParser() middleware. Developers might configure it incorrectly, exposing keys in logs or error responses:
const server = restify.createServer();
server.use(restify.authorizationParser());
server.get('/api/data', (req, res, next) => {
// Vulnerable: authorization info might be logged
console.log(req.authorization);
res.send(200, { data: 'sensitive' });
next();
});
Restify's server.pre() middleware can also create exposure points when developers attempt to validate keys before proper authentication:
server.pre((req, res, next) => {
const apiKey = req.header('x-api-key');
// Vulnerable: key exposed in pre-processing
if (!apiKey) {
return next(new restify.BadRequestError('API key required'));
}
next();
});
Environment variable mishandling is particularly problematic in Restify applications. Keys stored in environment variables but logged during development create exposure risks:
const server = restify.createServer();
// Vulnerable: key logged in error messages
const API_KEY = process.env.API_KEY;
server.on('uncaughtException', (req, res, route, err) => {
console.error(`API key: ${API_KEY}`, err);
res.send(500, { error: 'Internal Server Error' });
});
Restify's built-in server.use(restify.plugins.bodyParser()) can inadvertently expose keys if API keys are sent in request bodies and logged by custom middleware:
server.use(restify.plugins.bodyParser());
server.use((req, res, next) => {
// Vulnerable: logging entire request body
console.log('Received request:', req.body);
next();
});
Version-specific vulnerabilities in Restify have also led to key exposure. For example, Restify versions before 8.5.0 had issues with header parsing that could expose sensitive information in error traces.
Restify-Specific Detection
Detecting API key exposure in Restify applications requires understanding both the framework's architecture and common vulnerability patterns. middleBrick's black-box scanning approach is particularly effective for Restify APIs.
middleBrick scans Restify endpoints by sending requests to all documented routes and analyzing responses for key exposure patterns. The scanner specifically looks for:
- API keys in response headers, body, or error messages
- Misconfigured authorization headers that reveal key formats
- Debug endpoints that expose authentication details
- Version-specific vulnerabilities in Restify's middleware chain
For Restify applications, middleBrick's OpenAPI spec analysis is particularly valuable. The scanner cross-references your Restify API's documented endpoints with runtime behavior:
{
"restify_api_exposure": {
"severity": "high",
"endpoint": "/api/v1/users",
"vulnerability": "API key in response body",
"remediation": "Remove API key from response, use proper authentication middleware",
"evidence": "Response contains 'x-api-key' header in JSON body"
}
}
middleBrick's CLI tool can be integrated directly into your Restify development workflow:
npm install -g middlebrick
middlebrick scan https://api.yourservice.com --spec openapi.json --output json
The GitHub Action integration is especially useful for Restify applications in CI/CD pipelines:
- name: API Security Scan
uses: middlebrick/middlebrick-action@v1
with:
api_url: ${{ secrets.API_URL }}
spec_file: openapi.json
fail_threshold: 80
middleBrick's LLM security scanning is unique for Restify applications that use AI features. The scanner tests for system prompt leakage and prompt injection vulnerabilities that could expose API keys through AI interactions:
{
"llm_security": {
"test": "system_prompt_extraction",
"result": "failed",
"vulnerability": "API key found in system prompt",
"severity": "critical"
}
}
Restify-Specific Remediation
Remediating API key exposure in Restify requires both architectural changes and proper use of Restify's security features. Here are Restify-specific solutions:
1. Use environment variables with proper validation:
const server = restify.createServer();
// Secure: validate environment variable presence
const API_KEY = process.env.API_KEY;
if (!API_KEY) {
throw new Error('API_KEY environment variable not set');
}
// Use restify's built-in authorization
const authMiddleware = (req, res, next) => {
const authKey = req.header('x-api-key');
if (authKey !== API_KEY) {
return next(new restify.UnauthorizedError('Invalid API key'));
}
next();
};
server.use(authMiddleware);
2. Configure proper logging to prevent key exposure:
const server = restify.createServer({
log: winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.json(),
winston.format.sanitize(({ sanitize: true })) // Prevents logging sensitive data
),
transports: [new winston.transports.Console()]
})
});
// Custom middleware to redact sensitive headers
const sanitizeHeaders = (req, res, next) => {
const sanitized = { ...req.headers };
delete sanitized['x-api-key'];
delete sanitized['authorization'];
req.sanitizedHeaders = sanitized;
next();
};
server.use(sanitizeHeaders);
3. Use Restify's built-in security plugins:
const server = restify.createServer();
server.use(restify.plugins.conditionalRequest());
// Rate limiting to prevent brute force attacks
server.use(restify.plugins.throttle({
burst: 100,
rate: 50,
ip: true,
overrides: {
'192.168.1.1': {
rate: 0, // No rate limit for trusted IPs
burst: 0
}
}
}));
// Security headers
server.use(restify.plugins.securityHeaders());
4. Implement proper error handling to prevent key leakage:
server.on('uncaughtException', (req, res, route, err) => {
// Secure: don't log sensitive information
console.error(`Uncaught exception: ${err.message}`);
// Don't expose stack traces in production
if (process.env.NODE_ENV === 'production') {
res.send(500, { error: 'Internal Server Error' });
} else {
res.send(500, { error: err.message, stack: err.stack });
}
});
5. Use middleBrick's continuous monitoring for Restify APIs:
# Pro plan: continuous monitoring
middlebrick monitor https://api.yourservice.com \
--spec openapi.json \
--schedule "0 */6 * * *" \
--alert slack://webhook-url \
--threshold 85
6. Integrate with CI/CD using GitHub Action:
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run middleBrick Scan
uses: middlebrick/middlebrick-action@v1
with:
api_url: ${{ secrets.API_URL }}
spec_file: openapi.json
fail_threshold: 90
scan_type: "restify-specific"