Verifying notification/callback message content

238 views
Skip to first unread message

edd...@gmail.com

unread,
Mar 27, 2017, 9:14:28 PM3/27/17
to Kill Bill users mailing-list
Any suggestion to verifying the content of the notification/callback message? Is there any auth mechanism or any way to verify the message either using hash or making a call to killbill?

Thanks,

Ed

Pierre-Alexandre Meyer

unread,
Mar 28, 2017, 6:21:20 AM3/28/17
to edd...@gmail.com, Kill Bill users mailing-list
Hi Ed,

By design, the push notifications don't contain a lot of information, typically only the object id affected and the type of object. The idea is that your application would fetch the full state of the object (subscription, invoice, payment, etc.) using the Kill Bill API upon receiving the callback.

Even if an attacker was able to send dummy information to your app (e.g. fake payment received), you would be able to verify it when retrieving the state (e.g. invoice balance) since the Kill Bill API requires authentication.

Does that help?


--
You received this message because you are subscribed to the Google Groups "Kill Bill users mailing-list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to killbilling-users+unsubscribe@googlegroups.com.
To post to this group, send email to killbilling-users@googlegroups.com.
Visit this group at https://groups.google.com/group/killbilling-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/killbilling-users/29e51ec5-d59e-4c97-9f5e-f1b41988e688%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Pierre

edd...@gmail.com

unread,
Mar 28, 2017, 6:36:56 PM3/28/17
to Kill Bill users mailing-list, edd...@gmail.com
Pierre, thanks for the response.

If events are verified with the current state, we can possibly invalidate messages if not ingested before states change (eg. system down for sometime and received events delayed but the state changed already) I don't have a use case in need to support these scenario now, but I feel like the current notification design is not complete without verification mechanism.

Are you open to add some notification message verification in the future? Or maybe a new plugin will work better?

Thanks,

Ed

On Tuesday, March 28, 2017 at 3:21:20 AM UTC-7, Pierre-Alexandre Meyer wrote:
> Hi Ed,
>
>
> By design, the push notifications don't contain a lot of information, typically only the object id affected and the type of object. The idea is that your application would fetch the full state of the object (subscription, invoice, payment, etc.) using the Kill Bill API upon receiving the callback.
>
>
> Even if an attacker was able to send dummy information to your app (e.g. fake payment received), you would be able to verify it when retrieving the state (e.g. invoice balance) since the Kill Bill API requires authentication.
>
>
>
> Does that help?
>
>
> On Mon, Mar 27, 2017 at 6:14 PM, <edd...@gmail.com> wrote:
> Any suggestion to verifying the content of the notification/callback message? Is there any auth mechanism or any way to verify the message either using hash or making a call to killbill?
>
>
>
> Thanks,
>
>
>
> Ed
>
>
>
> --
>
> You received this message because you are subscribed to the Google Groups "Kill Bill users mailing-list" group.
>

> To unsubscribe from this group and stop receiving emails from it, send an email to killbilling-us...@googlegroups.com.
>
> To post to this group, send email to killbill...@googlegroups.com.

Pierre-Alexandre Meyer

unread,
Mar 29, 2017, 10:32:36 AM3/29/17
to edd...@gmail.com, Kill Bill users mailing-list
On Tue, Mar 28, 2017 at 3:36 PM, <edd...@gmail.com> wrote:
If events are verified with the current state, we can possibly invalidate messages if not ingested before states change (eg. system down for sometime and received events delayed but the state changed already)

Could you explain this a little further and/or give a concrete example? I'm not sure I follow. 

Are you open to add some notification message verification in the future? Or maybe a new plugin will work better?

We can absolutely enhance these notifications as needed.

About the plugin approach, you could also write your own notification plugin which would listen to the external bus and modify / publish your own messages over HTTP (it's roughly what the core system is doing today, see https://github.com/killbill/killbill/blob/585ec7e97b43b36dd311cc6dcae97bc90dbe8e2a/profiles/killbill/src/main/java/org/killbill/billing/server/notifications/PushNotificationListener.java#L98-L122).

--
Pierre

edd...@gmail.com

unread,
Mar 29, 2017, 1:33:06 PM3/29/17
to Kill Bill users mailing-list, edd...@gmail.com
Cool, I'll take a look at the push notification listener.

> Could you explain this a little further and/or give a concrete example? I'm not sure I follow. 
1. New subscription A created.
2. Notification receiving server went down
3. Killbill tried to send a notification with eventType SUBSCRIPTION_CREATION and objectId A but failed to deliver
4. Subscription A is canceled
5. Killbill tried to send a notification with eventType SUBSCRIPTION_CANCEL and objectId A but failed to deliver
6. Notification receiving server came back online
7. Killbill successfully sends SUBSCRIPTION_CREATION notification for subscription A, but the notification receiving server invalidate the message since the current state of subscription A is CANCELLED.
8. Killbill successfully sends SUBSCRIPTION_CANCEL notification for subscription A, and the notification receiving server successfully process it since the current state of subscription A is CANCELLED.

In #7 the notification receiving server wouldn't necessarily return non-2xx, but still has no way if the message is sent from an attacker or killbill.

Ed

Pierre-Alexandre Meyer

unread,
Mar 29, 2017, 1:48:24 PM3/29/17
to Ed Kim, Kill Bill users mailing-list
On Wed, Mar 29, 2017 at 10:33 AM, <edd...@gmail.com> wrote:
> Could you explain this a little further and/or give a concrete example? I'm not sure I follow. 
1. New subscription A created.
2. Notification receiving server went down
3. Killbill tried to send a notification with eventType SUBSCRIPTION_CREATION and objectId A but failed to deliver
4. Subscription A is canceled
5. Killbill tried to send a notification with eventType SUBSCRIPTION_CANCEL and objectId A but failed to deliver
6. Notification receiving server came back online
7. Killbill successfully sends SUBSCRIPTION_CREATION notification for subscription A, but the notification receiving server invalidate the message since the current state of subscription A is CANCELLED.

What do you mean exactly by "invalidate"?

I would expect the notification receiving server to always fetch the latest subscription state for any SUBSCRIPTION_* message received, and implement state-specific logic based off of the latest state (switch(latestState) { case CANCELLED: ... }). Step 8 would then be a no-op (idempotency).

Also, the server is expected to return 2xx at step 7, otherwise Kill Bill will continue trying to deliver that SUBSCRIPTION_CREATION message.

--
Pierre

edd...@gmail.com

unread,
Mar 29, 2017, 2:15:08 PM3/29/17
to Kill Bill users mailing-list, edd...@gmail.com
> What do you mean exactly by "invalidate"?
The notification receiving server would consider the message is from an attacker. Since verification against the current state failed.

>
>
> I would expect the notification receiving server to always fetch the latest subscription state for any SUBSCRIPTION_* message received, and implement state-specific logic based off of the latest state (switch(latestState) { case CANCELLED: ... }). Step 8 would then be a no-op (idempotency).
This will involve the notification receiving server to keep track of the last processed state and perform no-op if state remained same. So in step #7 the notification receiving server processes the Subscription A CANCELLED and store in its own db that Subscription A CANCELLED event is processed. Then in step #8 it needs to check the current state of Subscription A from killbill and compare it with its own db for last state to decide whether or not to perform no-op.
But regardless of supporting idempotency in the notification receiving server, my concern is not being able to process SUBSCRIPTION_CREATION event, which actually occurred.

>
>
> Also, the server is expected to return 2xx at step 7, otherwise Kill Bill will continue trying to deliver that SUBSCRIPTION_CREATION message.
Yes, I agree.

Ed

Pierre-Alexandre Meyer

unread,
Mar 29, 2017, 5:42:44 PM3/29/17
to Ed Kim, Kill Bill users mailing-list
On Wed, Mar 29, 2017 at 11:15 AM, <edd...@gmail.com> wrote:
This will involve the notification receiving server to keep track of the last processed state and perform no-op if state remained same. So in step #7 the notification receiving server processes the Subscription A CANCELLED and store in its own db that Subscription A CANCELLED event is processed. Then in step #8 it needs to check the current state of Subscription A from killbill and compare it with its own db for last state to decide whether or not to perform no-op.
But regardless of supporting idempotency in the notification receiving server, my concern is not being able to process SUBSCRIPTION_CREATION event, which actually occurred.

I think all of this will depend on the actions the receiving server needs to take. Typically, at least for SUBSCRIPTION_* events, these messages are used to sync the subscription status with a provisioning service (maybe to allocate or to reclaim hardware for a cloud service company), so the app already has some state to maintain anyways.

That being said, in general, having your handler idempotent is a good practice.

--
Pierre
Reply all
Reply to author
Forward
0 new messages