Skip to content
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

additionalAuthenticatedFields didn't work #113

Open
doverradio opened this issue May 2, 2022 · 1 comment
Open

additionalAuthenticatedFields didn't work #113

doverradio opened this issue May 2, 2022 · 1 comment

Comments

@doverradio
Copy link

Hello,

I am trying to save some mostly plain text user documents into a new collection encrypted using mongoose-encryption.

When I tried, the expected fields of _id, _v, _ct, and _ac appeared.

However, the new encrypted documents also showed the prior email field and the email address unencrypted.

Upon review, the README shows this can be solved by using additionalAuthenticatedFields, doing something like this:

userEncSchema.plugin(encrypt, { encryptionKey: encKey, signingKey: sigKey, additionalAuthenticatedFields: ['email'] });

Unfortunately, despite passing in ['email'] as the value, dropping the encrypted collection, and then again creating encrypted user documents, the email field and email addresses still appear.

I'm not clear why it's still revealing the email, so I'm hoping this can be solved in this issue.

My Schema:

const mongoose = require("mongoose");
const crypto = require("crypto");
const { v1: uuidv1 } = require('uuid');
const { ObjectId } = mongoose.Schema;
var encrypt = require('mongoose-encryption');
var encKey = process.env.SOME_32BYTE_BASE64_STRING;
var sigKey = process.env.SOME_64BYTE_BASE64_STRING;


const userEncSchema = new mongoose.Schema(
    {
        firstName: {
            type: String,
            trim: true,
            required: true,
            maxlength: 100
        },
        lastName: {
            type: String,
            trim: true,
            required: true,
            maxlength: 100
        },
        name: {
            type: String,
            trim: true,
            required: true,
            maxlength: 200
        },
        email: {
            type: String,
            trim: true,
            required: true,
            unique: true
        },
        hashed_password: {
            type: String,
            required: true
        },
        about: {
            type: String,
            trim: true
        },
        salt: String,
        role: {
            type: Number,
            default: 0
        },
        history: {
            type: Array,
            default: []
        },
        token: {
            type: Array,
            default: []
        },
        address1: {
            type: String,
            default: ""
        },
        address2: {
            type: String,
            default: ""
        },
        city: {
            type: String,
            default: ""
        },
        state: {
            type: String,
            default: ""
        },
        status: {
            type: String,
            default: "Active",
            enum: [
                "Active",
                "Not Active"
            ]
        },
        zip: {
            type: String,
            default: ""
        },
        country: {
            type: String,
            default: ""
        },
        phone: {
            type: String,
            default: ""
        },
        token_last_refresh: {
            type: Date,
            default: ""
        },
    },
    { timestamps: true }
);

// virtual field
userEncSchema
    .virtual("password")
    .set(function(password) {
        this._password = password;
        this.salt = uuidv1();
        this.hashed_password = this.encryptPassword(password);
    })
    .get(function() {
        return this._password;
    });

userEncSchema.methods = {
    authenticate: function(plainText) {
        return this.encryptPassword(plainText) === this.hashed_password;
    },

    encryptPassword: function(password) {
        if (!password) return "";
        try {
            return crypto
                .createHmac("sha1", this.salt)
                .update(password)
                .digest("hex");
        } catch (err) {
            return "";
        }
    }
};

// encrypt entire doc

userEncSchema.plugin(encrypt, { encryptionKey: encKey, signingKey: sigKey, additionalAuthenticatedFields: ['email'] });

module.exports = mongoose.model("UserEnc", userEncSchema, 'users_enc');

controller method:

const UserEnc = require("../models/user_enc");

exports.createUserEnc = async ( req, res ) =>
{
    let a = {}
    try {
        a.unsaved_user_enc = new UserEnc( req.body )
        a.saved_user_enc = await a.unsaved_user_enc.save().catch( err => log( `a.unsaved_user_enc.save err: `, err ) )
        res.json( a.saved_user_enc )
    } catch ( e ) {
        log( `createUserEnc e: `, e )
        res.status( 400 ).json( { error: e } )
    }
}

Resulting 'encrypted' document example:

{
    "_id": {
        "$oid": "xxxxxxxxxxxxxxxxxxxxxxxx"
    },
    "email": "email@email.com",
    "__v": 0,
    "_ct": {
        "$binary": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "$type": "0"
    },
    "_ac": {
        "$binary": "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "$type": "0"
    }
}

Please let me know how to also get the emails encrypted.

Thank you.

@proffnick
Copy link

proffnick commented May 30, 2022

Have you tried checking to see if you are indexing email in your schema? if so the documentation says indexed fields will not be encrypted, secondly, have you tried encrypting only the email to see if it works? by adding the property encryptedFields: ['email']? if not, try it let us know. Also check the version of mongoose you are using and be sure it is up to date. I just checked now, you are making the email field unique, email: { type: String, trim: true, required: true, unique: true }, , as such it may not be encrypted. A unique field is equivalent to an indexed field internally.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants