Search code examples
javascripthtmlforms

Why formdata submitted to server not changed after I being set by `formdata.set()`?


I am encrypting password for users:

<form method="post" onsubmit="usernamePasswordLogin(event);">
// want to encrypt password field before submit formdata
    function usernamePasswordLogin(x) {
        var formData = new FormData(x.target);
        var formDataEntries = formData.entries()
        var formDataEntry = formDataEntries.next()
        var pair;
        while (!formDataEntry.done) {
            pair = formDataEntry.value;
            if (pair[0] === 'password') {
                var encrypt = new JSEncrypt()
                encrypt.setKey(publicKey)
                var encrypted = encrypt.encrypt(pair[1])
                formData.set(pair[0], encrypted)
                console.log('formdata', formData.get(pair[0])) // print encrypted password
                break;
            }
            formDataEntry = formDataEntries.next();
        }
    }

When I submit the form, the console log shows formdata has been changed:

formdata YWFHmy9Da5x7XSKnF0jhgIrJbJF/eWo193VJIsYqcGbRh5gLVyL6U+ZGxiphOYSXVgXMQ0041c+IaLRvguwBXiwYm5pKE7xCFamdiwAzRA0YCzdIN9Rh/0rKq6G/QAAEbetdlgeDGnS8+hYo8eDJKZWhroNqku8vTxVT8+YiAcM=

but at server side, I see original plain text password.


Solution

  • While you can initialize a FormData object from a <form>, there is no ongoing link between them. Edits to the data in a FormData object are not reflected back in the original form.

    Use DOM to set the value of the <input> if you want to update the form before it is submitted.


    Note that it is almost never useful to encrypt a password with JSEncrypt or similar on the client.

    Most usecases are better handled by sending the password over HTTPS and hashing it server side.