Injection Flaws in Sails (Javascript)
Injection Flaws in Sails with Javascript
Injection flaws in Sails using JavaScript typically arise when untrusted input is concatenated into queries, model criteria, or lifecycle callbacks without proper validation or parameterization. Sails is built on Waterline ORM, which abstracts database interactions through models. If developers construct query conditions by directly interpolating user-controlled strings, numbers, or objects into Waterline criteria, they can inadvertently create injection surfaces that allow an attacker to manipulate query logic, bypass intended filters, or extract sensitive data.
For example, consider a search endpoint that builds a Waterline find criteria from request query parameters. If the code does not sanitize or validate input, an attacker could inject additional conditions by embedding operators like $or or $where into stringified JSON or URL parameters. This can lead to authentication bypass or unauthorized data access. The risk is especially pronounced when the application uses custom model methods that dynamically assemble criteria using JavaScript string concatenation or eval-like patterns, which can enable arbitrary code execution under certain configurations.
Another common scenario involves sending raw SQL or NoSQL fragments from client input into lifecycle callbacks such as beforeCreate or beforeUpdate. Because Sails allows integration with multiple databases, the underlying adapter may interpret injected operators or expressions differently. An attacker might supply a payload such as { "username": "admin", "password[regex]": ".*" } to manipulate regex-based matching or exploit type coercion in the adapter layer. Even when using services like sockets or actions, failing to validate and sanitize arguments enables injection-style attacks that compromise data confidentiality and integrity.
To detect these patterns, middleBrick performs black-box scanning against unauthenticated endpoints, analyzing input handling and response behavior for signs of injection. It checks whether user input is properly validated, parameterized, or escaped before being used in model queries or internal logic. This includes inspecting action blueprints, policies, and model lifecycle callbacks for unsafe usage of JavaScript expressions that could be influenced by an attacker.
Using OpenAPI or Swagger specifications, if provided, middleBrick correlates defined request schemas with runtime behavior. It resolves $ref references across complex schemas and cross-references them with observed inputs. This helps identify mismatches where documentation implies strict typing or structure, but the implementation accepts loosely typed JavaScript objects that are vulnerable to injection. The scanner maps findings to frameworks such as OWASP API Top 10, highlighting injection-related risks under the Injection category.
Javascript-Specific Remediation in Sails
Remediation focuses on strict input validation, avoiding dynamic query construction, and using framework-safe patterns. Always validate and sanitize incoming data using a dedicated library before incorporating it into Waterline criteria. Prefer parameterized queries or built-in Waterline methods that do not concatenate user input into raw query strings.
For instance, instead of building criteria via string interpolation, use explicit key-value pairs and allow-list validation. If a search action must support multiple filters, parse and validate each field individually against a known schema.
// Unsafe: directly using req.allInputs() in criteria
const criteria = req.allInputs();
const results = await User.find(criteria);
// Safer: explicit allow-list validation
const allowedFields = ['email', 'status', 'role'];
const safeCriteria = {};
for (const field of allowedFields) {
if (req.param(field) !== undefined) {
safeCriteria[field] = req.param(field);
}
}
const results = await User.find(safeCriteria);
When dealing with complex queries, prefer Waterline’s built-in methods such as where with bound parameters or use query builders that do not rely on string evaluation. Avoid using functions like eval or Function to construct query logic from user input.
// Unsafe: using eval to build query logic
const filter = req.param('filter');
const results = await User.find(eval(`(${filter})`));
// Safer: using Waterline's explicit where clauses
const results = await User.find()
.where({ email: req.param('email') })
.or([
{ status: 'active' },
{ role: 'admin' }
]);
Incorporate input sanitization for strings and numbers, and enforce strict type checks in policies and custom model methods. For text fields, trim and escape content as appropriate. For numeric fields, validate ranges and ensure integer parsing to prevent type confusion attacks. These practices reduce the likelihood that injected operators or malformed payloads affect database behavior.
Additionally, review lifecycle callbacks for unsafe usage of JavaScript expressions. If dynamic logic is necessary, isolate it behind controlled interfaces and avoid passing raw user input into where clauses or query hooks without normalization. middleBrick’s CLI can be used locally to scan code patterns, while the GitHub Action helps enforce these rules in CI/CD pipelines by failing builds when insecure query patterns are detected.
For teams using the Dashboard or MCP Server, it is possible to track changes over time and integrate scanning into AI-assisted development workflows. This supports early detection of injection-prone patterns during development, complementing runtime scans performed by the Pro continuous monitoring or Enterprise tier features.