sails: Find, Destroy or Update methods ignore undefined type attributes
Waterline version: 0.13.0-rc11 Node version: 4.5 NPM version: 2.15.9 Operating system: MacOs
Hi guys, I found an issue that I’m not sure if it’s a bug or something that you have considered. If you do something like this:
User.update({id: undefined}, {name: 'joe'}).exec()
This is gonna update ALL the users in the database, because the mongo query is gonna be something like this {}. The same thing happens with find/destroy methods.
So imagine that in your code you don’t realize data X value is undefined and you lauch a destroy against it, you’ll end up dropping all the collection with no clue about what just happened.
Thanks for your time.
About this issue
- Original URL
- State: open
- Created 7 years ago
- Comments: 53 (34 by maintainers)
Commits related to this issue
- Don't ignore undefined keys in where clauses Fixes https://github.com/balderdashy/sails/issues/4639 — committed to alxndrsn/waterline by deleted user 5 years ago
- Throw Error on undefined value in WHERE clause Fixes https://github.com/balderdashy/sails/issues/4639 — committed to alxndrsn/waterline by deleted user 5 years ago
- Don't ignore undefined keys in where clauses Fixes https://github.com/balderdashy/sails/issues/4639 — committed to alxndrsn/waterline by deleted user 5 years ago
- Don't ignore undefined keys in where clauses Fixes https://github.com/balderdashy/sails/issues/4639 — committed to alxndrsn/waterline by deleted user 5 years ago
- Don't ignore undefined keys in where clauses Fixes https://github.com/balderdashy/sails/issues/4639 — committed to alxndrsn/waterline by deleted user 5 years ago
For anyone still following this, I’ve forked
sails-hook-ormat https://www.npmjs.com/package/sails-hook-safe-orm / https://github.com/alxndrsn/sails-hook-orm so that anyundefinedvalues passed toupdate()orupdateOne()WHEREclauses should be rejected with anError.I intend to keep that lib and the underlying fork of
waterlineup-to-date as required. If you want specific vesions released then let me know.@mikermcneil I’d be interested in hearing your thoughts on the approach in that fork (visible at https://github.com/balderdashy/waterline/compare/master...alxndrsn:master); if these are of interest then I’d be happy to fix them up for a PR into the official
waterlinerepo.I was curious to see what the best practices around this issue are in other Node ORM’s. I made a simple test of 6 ORM packages, including Waterline, and included the results below.
Waterline:
Loopback:
Same behavior as Waterline, intentionally changes {id: undefined} to {}.
Configuration option “normalizeUndefinedInQuery” available to modify this behavior. https://github.com/strongloop/loopback/issues/637#issuecomment-146574151
Sequelize:
Bookshelf (Knex Query Builder):
TypeORM:
Node-ORM2 (No longer actively maintained):
@luislobo Throwing errors when undefined values are detected is certainly the safest way to go. If we were out of beta I’d be more hesitant since it’d be a significant breaking change, but in this case, I’m on board.
So it sounds like the current proposal is:
removeUndefined, which iftruestrips undefined values from criteria objects (as in the current behavior). Defaults tofalse.removeUndefinedisfalseand an undefined value is detected in a criteria object, anErroris thrown.Examples:
I agree with @Josebaseba, it would be great to be able to opt out of the “auto Remove Undefined From Where Clauses” feature. Although I see it’s convenience, it’s consequences can be, as demonstrated, complicated. Writing a little bit more code to handle specific criteria cases is not that bad for us. For example, we do have a “if this kind of user use this criteria and if not, use this other”, and we are fine with that.
@luislobo - They will all be located in balderdashy/sails - yes. 👍
Hi @Josebaseba, @luislobo, @sreed101 and @davidreghay, We are currently consolidating all Sails issues into one repo to help keep a better eye on things. We defiantly dont want to loss this well loved/documented issue! Cheers all!
I like having
updateOneanddeleteOnemethods.But I think the problem lies with acting on documents/records that don’t match with your “expected” criteria.
The same issues causing a condition to match a different set of documents/records could happen to one single document/record
Imagine having one record. SSN: ‘123456’, and the calling service/application tries to update SSN:‘847327’. For some bug/issue, the API receives
personSSN == undefined, it should not update the SSN correspoding to 123456, because it doesn’t match, but in this particular case it will. I know it’s an edge case, but that can happen, right?Thanks @luislobo I’m hoping against hope for it to be accepted 😆
SailsBot, don’t close it yet 😃 #1545 seems to fix it!
Hey @davidreghay it looks good to me. Thanks!
Hi @Josebaseba, @luislobo, @Xandrak, @mikermcneil, @sgress454
I’ve opened https://github.com/balderdashy/waterline/pull/1545 which is an attempt at implementing the solution as outlined by @mikermcneil
Please have a look and let me know what you think!
I like @Josebaseba suggestion, but, in addition to that, I would add an exception whenever a “value” in a where clause is undefined, in the case
removeUndefined: false. If you are “wanting” undefined NOT to be removed, you are worried about getting undefined values from your inputs, so you should be warned/stopped in those cases. Of course… one should validate it’s inputs… but sometimes having a large codebase that currently behaves in a different way, it’s easier to search for allupdateanddeletestatements and add ametaoption, for the sake of the upgrade to Sails v1.We just updated an entire database collection on accident IN prod due to this.