@@ -1142,6 +1142,59 @@ Query.prototype.select = function select() {
11421142 throw new TypeError ( 'Invalid select() argument. Must be string or object.' ) ;
11431143} ;
11441144
1145+ /**
1146+ * Sets this query's `sanitizeProjection` option. If set, `sanitizeProjection` does
1147+ * two things:
1148+ *
1149+ * 1. Enforces that projection values are numbers, not strings.
1150+ * 2. Prevents using `+` syntax to override properties that are deselected by default.
1151+ *
1152+ * With `sanitizeProjection()`, you can pass potentially untrusted user data to `.select()`.
1153+ *
1154+ * #### Example
1155+ *
1156+ * const userSchema = new Schema({
1157+ * name: String,
1158+ * password: { type: String, select: false }
1159+ * });
1160+ * const UserModel = mongoose.model('User', userSchema);
1161+ * const { _id } = await UserModel.create({ name: 'John', password: 'secret' })
1162+ *
1163+ * // The MongoDB server has special handling for string values that start with '$'
1164+ * // in projections, which can lead to unexpected leaking of sensitive data.
1165+ * let doc = await UserModel.findOne().select({ name: '$password' });
1166+ * doc.name; // 'secret'
1167+ * doc.password; // undefined
1168+ *
1169+ * // With `sanitizeProjection`, Mongoose forces all projection values to be numbers
1170+ * doc = await UserModel.findOne().sanitizeProjection(true).select({ name: '$password' });
1171+ * doc.name; // 'John'
1172+ * doc.password; // undefined
1173+ *
1174+ * // By default, Mongoose supports projecting in `password` using `+password`
1175+ * doc = await UserModel.findOne().select('+password');
1176+ * doc.password; // 'secret'
1177+ *
1178+ * // With `sanitizeProjection`, Mongoose prevents projecting in `password` and other
1179+ * // fields that have `select: false` in the schema.
1180+ * doc = await UserModel.findOne().sanitizeProjection(true).select('+password');
1181+ * doc.password; // undefined
1182+ *
1183+ * @method sanitizeProjection
1184+ * @memberOf Query
1185+ * @instance
1186+ * @param {Boolean } value
1187+ * @return {Query } this
1188+ * @see sanitizeProjection https://thecodebarbarian.com/whats-new-in-mongoose-5-13-sanitizeprojection.html
1189+ * @api public
1190+ */
1191+
1192+ Query . prototype . sanitizeProjection = function sanitizeProjection ( value ) {
1193+ this . _mongooseOptions . sanitizeProjection = value ;
1194+
1195+ return this ;
1196+ } ;
1197+
11451198/**
11461199 * Determines the MongoDB nodes from which to read.
11471200 *
0 commit comments