pubnub, how to identify the sender?
Asked Answered
W

2

8

when receiving a message from pubnub, there is no information on the sender. how to know if it's a message from visitorA or visitorB ? there are examples on the web where the sender sends his name with the message, but how to know he isn't spoofing someone else's identity ?

here is an example of a chat interface :

<html>
  <body>
    <form id="message_form">
      <input id="message_input" type="text"/>
    </form>
    <div id="chat"></div>
    <script src="http://cdn.pubnub.com/pubnub-3.7.1.min.js"></script>
    <script>
      var pubnub = PUBNUB.init({
        publish_key: 'demo',
        subscribe_key: 'demo'
      });

      pubnub.subscribe({
        channel: 'chat',
        message: function(message){
          var div = document.createElement("div");
          div.textContent = message;
          var chat = document.getElementById("chat");
          chat.appendChild(div);
        }
      });

      var form = document.getElementById("message_form");
      form.onsubmit = function(e) {
        var input = document.getElementById("message_input");
        pubnub.publish({
          channel: 'chat',
          message: input.value
        });
        input.value = '';
        e.preventDefault();
      };
    </script>
  </body>
</html>
Watershed answered 9/6, 2015 at 18:26 Comment(0)
V
5

Chat User Identification

You can identify the sender by creating a Unique ID as well as a Name attached to the message payload of the chat conversation. This is similar to IRC strategies but a bit more simplistic.

var user_id      = PUBNUB.uuid();
var user_name    = name.value;
var user_message = input.vaule;

Here is a full example which includes the HTML elements for UserName input. Notice also that I added a safe_text() method to prevent XSS attacks.

<form id="message_form">
  Name: <input id="name_input" value="John" type="text"/><br>
  Message: <input id="message_input" value="Hi" type="text"/><br>
  <input type="submit" value="send">
</form>
<div id="chat"></div>
<script src="http://cdn.pubnub.com/pubnub-dev.js"></script>
<script>
  var userid = PUBNUB.uuid();
  var pubnub  = PUBNUB({
    publish_key   : 'demo',
    subscribe_key : 'demo',
    uuid          : userid
  });

  function safe_text(text) {
    return (''+text).replace( /[<>]/g, '' );
  }
  pubnub.subscribe({
    channel: 'chat',
    message: function(message){
      var div = document.createElement("div");
      div.textContent =
        safe_text(message.name) + ": " +
        safe_text(message.text);

      var chat = document.getElementById("chat");
      chat.appendChild(div);
    }
  });

  var form = document.getElementById("message_form");
  form.onsubmit = function(e) {
    var input = document.getElementById("message_input");
    var name  = document.getElementById("name_input"); 

    pubnub.publish({
      channel: 'chat',
      message: { name : name.value, text : input.value, userid :userid }
    });
    input.value = '';
    e.preventDefault();
  };
</script>

While this demonstration provides you with a quick and easy getting started app, you will want to add more enhanced chat security and chat authentication systems.

User Identification for Chat Apps

For additional resources for building chat applications check out Build Real-time Chat Apps in 10 Lines of Code guide and also Building A Basic Chat Application.

Chat Access Control Layer ACL

You will need to add Security ACL Access Control Layer. With PubNub Access Manager (PAM) you can control who has access by granting users permission with access tokens.

PubNub Chat Access Management ACL Access Control Layer

// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Grant Chat Access to Secured Conversations
// All server-side data is stored according to defined security policies.
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
var pubnub = PUBNUB({ 
    publish_key:   "PUBLISH_KEY", 
    subscribe_key: "SUBSCRIBE_KEY", 
    secret_key:    "SECRET_KEY"
})
pubnub.grant({
    channel  : "CHANNEL",
    callback : receiver,
    error    : receiver,
    ttl      : 60, // Minutes
    read     : true,
    write    : true,
    auth_key : "AUTH_KEY"
});

It is recommended to run this level of ACL code on Trusted Systems such as your own data center servers.

Sending/Receiving Secure Encrypted Messages

PubNub client libraries offer built-in Advanced Encryption Standard (AES) 256-bit encryption. To use message encryption, simply use cipher_key at initialization.

To enable Transport Layer Encryption with TLS and the ssl flag.

Then publish/subscribe as usual.

var pubnub = PUBNUB({
    subscribe_key: 'sub-c-f762fb78-...',
    publish_key: 'pub-c-156a6d5f-...',
    ssl: true,
    cipher_key: 'my_cipherkey'
});

Message Verification for Identity of Sender

Attaching user's information to each message is efficient and provides a very powerful level of flexibility within your application. However malicious users may attempt to spoof the identity of users and therefor impersonate other users. In the sample app we have shown that it is easy to impersonate anyone by changing your name in the "message_form" field. This is the same situation you encounter with email and SMTP where arbitrary email header impersonations are possible unless you provide a way to verify the identity of the sender. There is a solution! πŸ˜„

Digital Signatures are fingerprints with embedded secure cryptographic hashes of key components of the message payload optionally including a salt (sometimes a timestamp) and then signing/encrypting with an asymmetric secret key which is used to verify the identity of the sender. This process is used to block spoofers and impersonations.

Chat Message Verification with Cryptographic Digital Signature

A digital signature is a mathematical scheme for demonstrating the authenticity of a digital message or document.

Message Verification for Chat Applications

Start by assuming that only the chat users have been granted access and they can publish and subscribe to chat channels using grant and revoke techniques available in your PubNub Access Manager implementation. The challenge here is that in a group chat room, your chat users have been granted auth_tokens yet they still can impersonate other chat users on the channel.

The goal here is to verify two things when a client receives a message.

  1. Identity of sender.
  2. Integrity of message.

Using asymmetric cryptography, you can provide a layer of validation and security to your users' messages by creating a digital signature. A valid digital signature gives a recipient reason to believe that the message was created by a known sender, that the sender cannot deny having sent the message (authentication and non-repudiation), and that the message was not altered in transit (integrity). Digital signatures are commonly used for financial transactions and message oriented communication such as email and chat and in other cases where it is important to detect forgery or tampering.

You will start by issuing each of your chat users' a set of keys, server generated, with a public-key (asymmetric) algorithm such as ECC/RSA via your server after user login. I recommend ECC as the key size is much smaller than RSA with comparable cryptographic strength. Each chat user in a chatroom is notified of other chat users' public key via a secured read only side-channel. Your users must only receive the Public Key from a public READ-ONLY channel controlled by your server's trusted and secure environment. Your server will be able to write each user's Public Key to this READ-ONLY channel. Your users will read from this channel.

Your user's can receive each other's Public Keys via a PubNub History call before joining the chat room. They should also open a subscription to the same channel to get public key of new chat users joining the chatroom.

The users' Private Key must not be exposed to anyone but the verified owner. This can be done upon email/password sign-on and you can send the private key to the verified user as soon as they log-in.

Sending a Chat Message with Attached Digital Signature

{ userId: 123456,
profilePic: "http://www.chats.com/user1234.jpg",
message: "Hello World",
signature: "tnnArxj06cWHq44gCs1OSKk/jLY" }

You will create the signature by concatenation of the following base string (userId+profilePic+message). Next you need to calculate a message digest using SHA1(signature_base_string) or SHA256(signature_base_string). Now you can use this cryptographically generated hash to sign with the users' private key using an ECC/RSA asymmetric algorithm.

Now attach this digital signature to chat message as shown in the example above and on to the final phase of Chatroom Message Verification.

Chatroom Message Verification

While subscribed to the chatroom channel you will receive user sent chat message with an attached digital signature. You will use this signature to verify the chat message's authenticity. If the message was an attempted spoof you will drop the message altogether.

// Digitally Signed Chat Message
{ userId: 123456,
profilePic: "http://www.chats.com/user1234.jpg",
message: "Hello World",
signature: "tnnArxj06cWHq44gCs1OSKk/jLY" }

To verify the signature you will create the signature by concatenation of the following base string (userId+profilePic+message). Next you need to calculate a message digest using SHA1(signature_base_string) or SHA256(signature_base_string). Now using the chat users' public key you already have for userId 123456 you can Verify/Decrypt digital signature to get original message digest you just generated which was also created by the sender.

Compare current message digest and original message digest. If they are the same then the message is authentic and you have successfully verified the sender's message using Message Verification via digital signing. If the digests do not match, it's a phony message and you may disregard the impersonator.

Creating a PKI Public Key Infrastructure using PubNub

You'll need a way to securely transmit public keys via a read-only PKI. PubNub provides to you a way for exposing a secure read-only PKI list for your chat users. Important to note that PKI requires asymmetric key algorithm like ECC or RSA. Also we are using these crypto algorithms for creating digital signatures rather than encrypting the data. This means we will be able to identify and verify the sender by successfully decrypting the signature using the public key and verifying the salted signed string matches.

  1. Public Key is used as the Decryption Key and Verify Key.
  2. Private Key is used as the Encryption Key and Signing Key.

It is important to note that you should only print the username retrieved from the Public Key Trusted Source and not from the message content. The message content is only used for signing and verifying Identity. If an Identity is changed it must be relayed via the PKI using PubNub’s Broadcast mechanism and Storage and Playback for Secure Authorization.

Access tokens, Identity Name/Photo and Asymmetric Keys must only be generated from trusted execution environments on your servers and relayed over PubNub's Authorized Read-only PKI data channels.

Velasquez answered 9/6, 2015 at 19:55 Comment(8)
i don't understand... what prevents someone from receiving my message, copying my userid, and send a message with my name and userid ? – Watershed
Howdy yes you'll want to add Security ACL Access Control Layer and I updated the answer to add in ACL usage example. It is recommended to run this level of ACL code on Trusted Systems such as your own data center servers. – Velasquez
i don't see how ACL could solve the problem. the problem appears when several people publish, so, of course, ACL should allow them to publish. the problem is still the same : who sent that message on the channel ? is it visitorA or visitorB ? they are both allowed to publish, but which one did it ? – Watershed
Good question! -- Make sure to attach the User's Information in the message payload. { name : my_name, profile : my_picture, text : my_message, userid : my_id }. Also check out this sample app Creating a Polymer Chat App with Material Design. – Velasquez
attaching user's information, user's name or user's id is the same. it can be spoofed. in the sample app you linked, it's very easy to impersonate anyone : just subscribe to the channel, and repeat every message you receive. – Watershed
Thank you for confirming. You'll use Message Verification in order to prevent user impersonations. – Velasquez
I'm updating this page with Message Verification notes for you shortly. – Velasquez
you pulled out big guns, but at least, it works, though a correctly signed message can still be repeated, but that's easy to solve. thank you for your answers. – Watershed
A
1

In the most recent PubNub SDKs (v4), the publisher UUID is now included in subscribe response.

{
    actualChannel: null,
    channel: "my_channel_1",
    message: "Hello World!",
    publisher: "pn-58e1a647-3e8a-4c7f-bfa4-e007ea4b2073",
    subscribedChannel: "my_channel_1",
    subscription: null,
    timetoken: "14966804541029440"
}
Azure answered 22/6, 2017 at 23:25 Comment(2)
What about history? I couldn't find a way to get publisher uuid information for the messages fetched from history API – Stevenage
History only contains the published message content using the channel/publish timetoken as the key. If you would like to preserve that data, include the publisher's UUID and any other meta-data you might want to use later. – Azure

© 2022 - 2024 β€” McMap. All rights reserved.