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?
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?
💡 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.
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');
}
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 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With