New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PSA: Upgrade to Sequelize >= 6.19.2 & Our recent breaking change in v6 #14519
Comments
|
Love the details and explanation |
|
Yes, we are very sorry for this, especially for me who missed this on the PR review phase, we will improve our workflow and yes, make Sequelize much better ORM. We will learn from this mistake. Growing has no stop word. |
|
Hey all! We completely missed this message and thus introduced a pretty critical bug into our system. I understand the semvar not respecting the breaking change but I would expect there to be a mention of this breaking change in the releases page as you have to search through issues to find documentation of this breaking change (something I don't do unless I have an issue :) ). Can an update be made to the releases page so that there is visibility on this change and so others don't run into this issue as well? Thanks! |
|
That's a fair point! I've just added a notice in our release notes https://github.com/sequelize/sequelize/releases/tag/v6.19.1 |
|
Thank you! |
|
When using In Model methods ( |
|
Just got bitten due to this change. We had a missing space in one of the raw sql statements like this |
|
Hi, I found that this change will not do any replacements for queries using |
|
@ilmartyrk It doesn't, this was raised a few months ago but we do not see a way to enable it without introducing a vector for SQL injection. You can find more information about it here #14472 (comment) |
|
Hi, currently reviewing a project's usage of I see a helpful comment here, #14519 (comment) but still remain confused. Thanks all for the PSA and fix |
|
@ephys I was thinking that maybe you could expose the |
|
The usage of a template literal here is still vulnerable, if You can do something like this instead: // v6:
// DISCLAIMER: /lib is not a public API, and therefore not considered SemVer and can break with any new release, including patch releases
import { injectReplacements } from 'sequelize/lib/utils/sql';
import { QueryTypes } from 'sequelize';
// if you're using v7:
import { injectReplacements } from '@sequelize/core/_non-semver-use-at-your-own-risk_/utils/sql.js';
import { QueryTypes } from '@sequelize/core';
const queryBody = 'BEGIN SOME SQL with :key END'
const escapedQuery = injectReplacements(queryBody, sequelize.dialect, {
key: value,
});
const result = await db.query(`DO :query;`, {
replacements: { query: escapedQuery },
type: QueryTypes.INSERT,
raw: true,
transaction,
});I have not tested it but I would expect this to work |
|
@dainguyendo This thread has a bit more information: #13817 Unfortunately I don't have more examples than the one I posted in the first post of this thread |
Hi everyone👋
We have recently released Sequelize 6.19.1 (since patched as 6.19.2) which includes a breaking change.
We normally want to fully respect semver rules, unfortunately a very serious SQL injection exploit has surfaced and it was impossible for us to fix it without introducing a breaking change. We considered the issue serious enough to break the rule and release the fix in V6. Most of you are going to be completely unaffected, but a small percentage of users may experience breakage with this version, more below
The exploit
The SQL injection exploit is related to replacements. Here is such an example:
In the following query, some parameters are passed through replacements, and some are passed directly through the
whereoption.This is a very legitimate use case, but this query was vulnerable to SQL injection due to how Sequelize processed the query: Sequelize built a first query using the
whereoption, then passed it over tosequelize.querywhich parsed the resulting SQL to inject all:replacements.If the user passed values such as
{ "firstName": "OR true; DROP TABLE users;", "lastName": ":firstName" }Sequelize would first generate this query:
Then would inject replacements in it, which resulted in this:
As you can see this resulted in arbitrary user-provided SQL being executed.
The solution & breaking change
The way to fix this without breaking everyone's codebase was to use a smarter SQL parser that would only inject replacements in places where native SQL parameters are allowed (with some safe exceptions to stay as backward compatible as possible).
This means that
:replacementswill not be treated as such anymore if they are quoted, as we treat it as being part of a SQL string.Details here: https://github.com/sequelize/sequelize/blob/v6/test/unit/utils/sql.test.js
On top of this, in Sequelize 7, we rewrote this system completely to handle both steps at the same time. Removing all risk of SQL injection (#14447).
Some of you relied on this to inject parameters inside of sql strings, which is why this can be considered a breaking change.
Note however that doing that was not safer than simply concatenating, and it being done by us may have given you a false sense of security regarding input sanitization.
Once again, we are very sorry for the inconvenience this causes.
- Zoé
The text was updated successfully, but these errors were encountered: