如何为纯API型Sails.js应用防护SQL注入与参数异常?
Hey there! Let's dive into securing your Sails.js API—whether it's a full-stack app or an API-only service—against SQL injection and invalid parameter issues (like type mismatches or malformed data). Here's a practical, actionable breakdown:
SQL injection is one of the most common attack vectors, but Sails.js gives you tools to mitigate it if you use them correctly:
Stick to Waterline (Sails' built-in ORM) for all queries
Waterline automatically escapes query parameters, so as long as you use its standard methods likefind(),create(),update(), you're protected. For example:// Safe: Waterline handles escaping const user = await User.find({ id: req.param('userId') });Never build raw SQL strings by concatenating user input—this is the #1 cause of injection vulnerabilities.
Use parameterized queries if you need raw SQL
If you must useModel.query()for complex queries, always pass parameters as an array instead of embedding them in the string:// Safe: Parameterized query const user = await User.query('SELECT * FROM users WHERE email = $1', [req.param('email')]); // UNSAFE: Never do this! const badQuery = await User.query(`SELECT * FROM users WHERE email = '${req.param('email')}'`);Lock down your model schemas
Enableschema: truein your models to ensure only defined attributes can be modified. Combine this withwhitelistorblacklistto control which parameters are allowed in requests. For example, in a controller:// Only allow email and password to be updated const allowedParams = req.params.all(['email', 'password']); const updatedUser = await User.updateOne({ id: req.param('userId') }).set(allowedParams);
For API-only setups, you need extra guardrails to catch bad input before it reaches your database:
Leverage Waterline's built-in validation
Define strict rules for your model attributes to enforce data types, formats, and required fields. Example model configuration:// api/models/User.js module.exports = { attributes: { email: { type: 'string', required: true, isEmail: true, // Enforces valid email format unique: true }, age: { type: 'number', min: 18, max: 120 } }, schema: true };When a request sends invalid data, Waterline will throw a validation error that you can handle cleanly.
Add controller-level pre-validation
For edge cases that model validation doesn't cover, add checks in your controllers to catch type mismatches or malformed data early:// api/controllers/UserController.js async findOne(req, res) { const userId = parseInt(req.param('id')); if (isNaN(userId)) { return res.badRequest({ error: 'User ID must be a numeric value' }); } const user = await User.findOne({ id: userId }); return res.ok(user); }Customize error responses
Avoid leaking sensitive database details to attackers by overriding Sails' default error responses. Inconfig/responses.js, update thebadRequestresponse to return clear, safe messages:// config/responses.js module.exports.responses = { badRequest: function(data) { return this.res.status(400).json({ error: 'Invalid request parameters', details: data?.message || 'Please check your input and try again' }); } };Enforce minimal database permissions
Create a dedicated database user for your Sails app with only the permissions it needs (e.g.,SELECT,INSERT,UPDATE,DELETE—noDROP,ALTER, orCREATE). Even if an injection does slip through, this limits the damage an attacker can do.
- Keep Sails.js, Waterline, and all dependencies updated—security patches are regularly released.
- Log invalid requests and failed validation attempts to monitor for suspicious activity.
- Use rate limiting to prevent brute-force attacks on your API endpoints.
内容的提问来源于stack exchange,提问作者FranzHuber23

