Injection Flaws in Sails with Basic Auth
Injection Flaws in Sails with Basic Auth — how this specific combination creates or exposes the vulnerability
Injection flaws in Sails applications that rely on HTTP Basic Auth arise when user-controlled input is passed to database queries or command execution without proper validation or parameterization. Basic Auth itself transmits credentials in an encoded (not encrypted) header; if the application uses the decoded username or password to construct dynamic queries, the attacker can inject malicious payloads. For example, an attacker may provide a username like ' OR 1=1 -- and, if the app uses that value to build a SQL or NoSQL condition, the authentication check can be bypassed.
When combined with unauthenticated scanning, middleBrick tests endpoints that expose an authentication surface via Basic Auth. If the endpoint reflects user input in responses or error messages, injection indicators (such as database error strings or timing differences) may be observed. Sails apps often use Waterline ORM; dynamic finders like User.find({ where: { email: req.body.email } }) are generally safe, but constructing raw queries or using string interpolation increases risk. The LLM/AI Security checks in middleBrick additionally probe for prompt injection or data exfiltration patterns if the API interacts with language models, which can compound the impact of injection flaws.
Specific checks relevant to this scenario include Input Validation, which tests for missing allowlists and improper sanitization, and Authentication checks to verify whether Basic Auth is required for sensitive paths. Data Exposure checks may reveal that error messages disclose stack traces or database details, aiding further injection attempts. Because Sails can integrate with various databases and external services, SSRF and Unsafe Consumption checks help identify whether injected content triggers unintended internal requests or code execution.
Basic Auth-Specific Remediation in Sails — concrete code fixes
Remediation focuses on avoiding string concatenation or interpolation when using credentials or user input, enforcing strict input validation, and ensuring Basic Auth is used only over HTTPS. The following examples show secure patterns for a Sails controller and model usage.
1. Use parameterized queries and Waterline safely
Do not build queries by embedding headers or body values directly. Instead, rely on Waterline’s built-in parameterization:
// api/controllers/UserController.js
module.exports = {
login: async function (req, res) {
const { email, password } = req.allParams();
// Safe: Waterline parameterized query
const user = await User.findOne({ email: email });
if (!user || user.password !== password) {
return res.unauthorized('Invalid credentials');
}
return res.ok({ id: user.id, email: user.email });
}
};
2. Validate and sanitize Basic Auth credentials before use
Treat decoded Basic Auth credentials as untrusted input. Validate format and length, and avoid using them in raw queries:
// api/actions/secure-login.js
module.exports = {
friendlyName: 'Secure Login with Basic Auth',
description: 'Authenticate using Authorization header with strict validation.',
inputs: {
basicAuth: {
type: 'ref',
required: true
}
},
fn: async function (inputs, exits) {
const credentials = Buffer.from(inputs.basicAuth.split(' ')[1], 'base64').toString('utf8');
const [username, password] = credentials.split(':');
// Strict validation: alphanumeric + limited length
if (!/^[a-zA-Z0-9_-]{3,32}$/.test(username) || !/^[\w@!#$%&’*+/=?`{|}~-]{8,64}$/.test(password)) {
return res.badRequest('Invalid credentials format');
}
const user = await User.findOne({ username: username });
if (!user || user.password !== password) {
return res.unauthorized();
}
return res.ok({ token: 'session-token' });
}
};
3. Enforce HTTPS and avoid logging sensitive data
Ensure that Basic Auth is only accepted over TLS and that sensitive values are not written to logs or error responses:
// config/security.js
module.exports.security = {
requireHttps: true,
secureCookies: true
};
// In a custom response handler, avoid leaking credentials:
if (req.headers.authorization) {
sails.log.info('Authentication attempt received');
// Do NOT log req.headers.authorization
}
4. Combine with Content-Security-Policy and strict CORS
Add response headers to reduce the impact of any potential injection:
// config/http.js
module.exports.http = {
middleware: {
secureHeaders: function (req, res, next) {
res.set('Content-Security-Policy', "default-src 'self';");
res.set('X-Content-Type-Options', 'nosniff');
return next();
}
}
};