Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Secure Pubnub subscriber key and channel name

Tags:

pubnub

I have an application where each user must receive notifications relevant only to themselves.

To do this, I have created a unique channel name for each user. I subscribe to this channel when the user logs in from the browser using javascript.

pubnub = PUBNUB.init({
   subscribe_key : '<subscriber-key>'
});

pubnub.subscribe({
  channel: "<unique-channel-name>",
})

My question is, if someone gets the name of a user's unique channel, they can setup their own pubnub client and receive the notifications without any authorization? Basically, all that is protecting my user's data is a channel name and subscriber key that are publicly available in the source-code of the page. I looked the pubnub's access manager, but it suffers from the same problem, does it not? If someone opens the source code and copies the auth-key, they can setup their own client and receive messages?

Edit: Additional information

I generate and save a channel name for every user when they sign up. This name is a random UUID like "7304cd62-9ba2-4842-98d8-8a5c8e561275." When I want to notify a user that, let's say, they got a friend request, I pull the channel name from the database and publish a notification. Whenever they login, the rendered page uses Ruby to inject their channel name, and my subscriber key into a hidden field which javascript uses to initialize pubnub.

<%= my_pubnub_subscriber_key %>
<%= current_user.channel.name %>

In this case, using Access Manager would mean that I will have to store an auth key in addition to the channel name and authorize the key to read the channel.

John
- john-channel
- john-key-authorizing-read-on-john-channel

Jane
- jane-channel
- jane-key-authorizing-read-on-jane-channel

The rendered page will then have three fields to initialize pubnub:

<%= my_pubnub_subscriber_key %>
<%= john-channel %>
<%= john-key %>

The original problem remains. If Jane goes to John's house, opens the source-code of John's homepage, copies the 3 keys, goes back home and create her own client, she can subscribe to the John's notifications. I can't know if the receiver of my notifications is actually logged in or just copied the keys.

Is my thinking right that to secure against such a possibility, I should simply regenerate the channel name or auth key regularly, such as when a user logs out or daily?

like image 964
Curious Observer Avatar asked Dec 13 '14 21:12

Curious Observer


1 Answers

Securing Data Streams on PubNub with ACL / Access Management

💡 Check the latest docs using PubNub Access Manager - https://www.pubnub.com/docs/security/access-control

You want to Secure the PubNub Subscriber Key and the Channel Name too. With fine grain read and write access control on a per-connection level you can Provide Authorization and access control to users, devices and channels.

Good Part - With PubNub Access Management and ACL you can prevent someone from setting up their own PubNub client and receive the notifications without any authorization.

This is done with a PubNub auth_key which is an authenticated access token managed by your servers. Essentially you want to Mitigate and Prevent Subscription Sharing for your valuable data on a PubNub Data Stream.

Keep it Secret and Safe - Access Control for Realtime Data Streams

You must treat your PubNub auth_key the same as you would a secret intended only for the user. This is like a Session Key/ID that allows access to a data stream, similar to the way Netflix, Spotify, Facebook and Gmail provide a secure access layer.

This is what your JavaScript should look like for safe access controls.

Wohhhh Note - There are no access keys stored in the JavaScript file.

// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Get User Access Keys from Your Server
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
console.log('getting user login information');
get_user_access( 'https://myservers.com/user/login/', function(user) {
    var pubnub = PUBNUB({
        subscribe_key : user.subscribe_key,
        auth_key      : user.auth_key
    });

    ready( pubnub, user );
} );

// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Data Stream Connection Ready to Start
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
function ready( pubnub, user ) {
    console.log('ready to subscribe to data stream channel');

    pubnub.subscribe({
        channel : user.channels,
        message : receiver
    });
}

// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Data Stream Payloads Received
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
function receiver(data) {
    console.log('received secure data payload');
}

Revoke Access on Malicious Activity

What if a user is logging in twice or opens more than one PubNub data Stream Connection? If you detect abuse, you can revoke access instantly with pubnub.revoke() command.

// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Revoke Access from Your Server
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
pubnub.revoke({
    channel   : 'CHANNEL_NAME',
    auth_key  : 'BAD_APPLE_AUTH_KEY',
    callback  : function(m){console.log(m) }
});

Secure PubNub Subscriber Key and Channel Name

Secure PubNub Subscriber Key and Channel Name by Securing Data Streams on PubNub with ACL / Access Management

Also if you are using Node.JS for Access Management Control we have a fun community forum post for you that describes mass grants at a reasonable speed using PubNub Access Manager with Node.JS for both good and for awesome.

like image 74
Stephen Blum Avatar answered Oct 14 '22 21:10

Stephen Blum