简体   繁体   中英

Correct way to send auth headers via ajax request to an API

I have a form where I've stored the auth key in a hidden field.

hidden_field_tag 'auth_key', Settings.biometric.auth_key

I am sending an ajax request to an API where I'm setting the auth key in the header which requires the key:

var authKey = $("input[id='auth_key']").val();
beforeSend: function (xhr) {
  xhr.setRequestHeader ("auth", authKey);
}

All is working fine, just that the auth key resides in the form and is easily inspectable by any malicious user.

I think this might not be the right way to do this What is the best approach to perform this?

TL;DR:

Anyone who has access to the client-side (aka your User using a browser), can ultimately find a way to get this auth_key , because a client-user has and will always have power/access on what "data" gets sent/received/stored, especially easier here in webapps because of built-in browser developer tools.

Some Explanations:

Disclaimer: I am not well versed in this field, so if anyone, please let me know.

  • Yes, it can be encrypted in the client-side, but a user/hacker can decrypt them because the "encryption" trace can be found somewhere in your JS script file:

     // application.js example ...beforeSend: function (xhr) { var encryptedAuthKey = localstorage.get('encrypted-auth-key'); var decryptionPassword = 'abcd'; var authKey = doSomeFancyDecryption(encryptedAuthKey, decryptionPassword); xhr.setRequestHeader ("auth", authKey); } 
  • However, a secure way would be to encrypt them using a password stored in the server-side, so that the client cannot debug/inspect/find this password in the JS code... except that this is not possible, see below:

     // application.js example ...beforeSend: function (xhr) { var encryptedAuthKey = localstorage.get('encrypted-auth-key'); var decryptionPassword = someFunctionThatPerformsAjaxRequestToServerAndReturnsTheDecryptionPassword(); var authKey = doSomeFancyDecryption(encryptedAuthKey, decryptionPassword); function someFunctionThatPerformsAjaxRequestToServerAndReturnsTheDecryptionPassword() { // do some ajax request with Auth header equals Something... // ummm... what's the value of this something? // ummm... I cannot pass in my Username and Password, of course! // ummm... I cannot pass in another-kind of "auth_key", which just basically loops this process itself. } xhr.setRequestHeader ("auth", authKey); } 
  • You can "sign" your request so that you won't need to directly supply anymore the auth_key as part of your request (but the client-user can still hack this and get the auth-key and create their own request themselves, precisely because they can see and have access to your underlying code like below):

     // application.js example ...beforeSend: function (xhr) { var authKey = localstorage.get('auth-key'); var params = // assign all input fields as key-values object here var url = this.url; var signature = generateSignatureUsingHMAC(authKey, url, params) xhr.setRequestHeader ("Signature", signature); } 

I would personally do something like the signature-based authorization above

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM