String `id` field + bulkCreate does not escape the String primary key—SQL injection vulnerability?
See original GitHub issueIssue Description
Due to #11714, I have decided to just name my String primaryKey id
. However, when using a String primary key with bulkCreate
, it does not add the quotation marks to the String that gets inserted, which blows up.
The relevant piece of my config.json:
{
"development": {
"username": null,
"password": null,
"database": "experiment",
"host": "127.0.0.1",
"dialect": "postgres"
}
}
After initializing the project, I ran npx sequelize-cli models:generate --name Foo --attributes foo:string,bar:string,quux:integer and edited the migrations/…-create-foo.js file as such:
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('Foos', {
id: {
allowNull: false,
autoIncrement: false,
primaryKey: true,
type: Sequelize.STRING
},
bar: {
type: Sequelize.STRING
},
quux: {
type: Sequelize.INTEGER
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('Foos');
}
};
Small test script:
const db = require('./models/index.js');
const Foo = db.Foo;
Foo.bulkCreate([{ id: "Foo", bar: "Bar", quux: 42 }]).then(() => console.log("It worked!"));
What do you expect to happen?
It worked!
What is actually happening?
The generated SQL inserted Foo
directly into the query and does not add the quotation marks with it.
Executing (default): INSERT INTO "Foos" ("id","bar","quux","createdAt","updatedAt") VALUES (Foo,'Bar',42,'2019-12-02 02:29:43.780 +00:00','2019-12-02 02:29:43.780 +00:00') RETURNING *;
Unhandled rejection SequelizeDatabaseError: column "foo" does not exist
at Query.formatError (/Users/Mitch/sequelize/sequelize-bug/node_modules/sequelize/lib/dialects/postgres/query.js:366:16)
at query.catch.err (/Users/Mitch/sequelize/sequelize-bug/node_modules/sequelize/lib/dialects/postgres/query.js:72:18)
at tryCatcher (/Users/Mitch/sequelize/sequelize-bug/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/Users/Mitch/sequelize/sequelize-bug/node_modules/bluebird/js/release/promise.js:547:31)
at Promise._settlePromise (/Users/Mitch/sequelize/sequelize-bug/node_modules/bluebird/js/release/promise.js:604:18)
at Promise._settlePromise0 (/Users/Mitch/sequelize/sequelize-bug/node_modules/bluebird/js/release/promise.js:649:10)
at Promise._settlePromises (/Users/Mitch/sequelize/sequelize-bug/node_modules/bluebird/js/release/promise.js:725:18)
at _drainQueueStep (/Users/Mitch/sequelize/sequelize-bug/node_modules/bluebird/js/release/async.js:93:12)
at _drainQueue (/Users/Mitch/sequelize/sequelize-bug/node_modules/bluebird/js/release/async.js:86:9)
at Async._drainQueues (/Users/Mitch/sequelize/sequelize-bug/node_modules/bluebird/js/release/async.js:102:5)
at Immediate.Async.drainQueues [as _onImmediate] (/Users/Mitch/sequelize/sequelize-bug/node_modules/bluebird/js/release/async.js:15:14)
at runCallback (timers.js:705:18)
at tryOnImmediate (timers.js:676:5)
at processImmediate (timers.js:658:5)
Additional context
This seems like a weird corner-case, as I’ve only seen this behavior with bulkCreate
paired with a string id
field (that in this case at least is the primary key). I’m not sure if there are other weird situations where something like this might happen. This also definitely feels like it’s rife for a SQL injection attack.
Follow-up: contrived example, but this SQL injection will work.
Foo.bulkCreate([
{
id: "'Foo', '1', 2, '2019-12-02 04:05:46.971 +00:00', '2019-12-02 04:05:46.971 +00:00'); \
select count(*) from \"Foos\"; \
drop table \"Foos\"; \
insert into \"Foos\" (\"id\", \"bar\", \"quux\", \"createdAt\", \"updatedAt\") values ('hello'",
bar: "Bar",
quux: 42
}
]).then(() => console.log("It worked!"));
Environment
- Sequelize version: 5.21.2
- Node.js version: 10.16.3
- Operating System: macOS Mojave 10.14.5
Issue Template Checklist
How does this problem relate to dialects?
- I don’t know, I was using Postgres, with connector library version pg@7.21.1 and database version PostgreSQL 11.3
Would you be willing to resolve this issue by submitting a Pull Request?
- Yes, I have the time but I don’t know how to start, I would need guidance. --> (bulkCreate isn’t the easiest thing to parse 😃 )
Issue Analytics
- State:
- Created 4 years ago
- Comments:8 (2 by maintainers)
I will close this in favor of #11830 now since your original problem was solved.
Hi @alirizwan, thanks for helping @gamburgm solve this issue 😃
As for your last comment, @gamburgm, I agree that the current ‘developer experience’ on this is quite messy. I have opened #11830 with a different idea on how to improve this. Please share your thoughts 😃