← Back to list

The curious case of Daraja, The London bridge and Safaricom.

Hello, I am Brian a software engineer, and as is customary for my country people else many won’t believe here is my github, I do mostly…

brian · 2024-11-05 19:59 · 19 claps · 6.6 min read
#safaricom #daraja #privacy #api-development #api-gateway
Open on Medium ↗
Wiki topics: 💻 · Programming 🔒 · Cybersecurity 🔓 · Open Source

The curious case of Daraja, The London bridge and Safaricom.

Hello, I am Brian a software engineer, and as is customary for my country people else many won’t believe here is my github, I do mostly backend, and have been looking into blockchain technology of late, but that shouldn’t matter much as I’ll try to make this article as basic as possible with not that much jargon that anyone who is familiar in some way with Safaricom Daraja can understand. So what is Daraja, and what does it have to do with the London bridge?

Well Daraja is a set of APIs exposed by Safaricom to allow users to integrate MPesa into their software, Daraja also is the kiswahili word for bridge. So what’s the similarity with Safaricom Daraja and London Bridge? Well London bridge at some points in time had small issues that went undetected until one day it led to the bridge falling, there is even whole nursery rhythms and poems written about it.

So what is the problem with Daraja API? Folks have been using it for almost a decade now you might say without any issues, it’s so widely used that jokes are made about how almost every fintech in Kenya is just an MPESA wrapper using Daraja 😆. Well read on ahead, you might be amazed.

Photo by Gonzalo Facello on Unsplash

Photo by Gonzalo Facello on Unsplash

The bridge that leaks.

In a bridge of critical importance, for example imagine a bridge that leads into a kingdom from any fairy tale, such a kingdom would only want people who are authorized to enter the kingdom to use that bridge, you wouldn’t want to allow anybody from any other kingdom to just use the bridge as that could easy lead to an invasion, you’d want a secure bridge, strong and not easy to bypass.

So what is the problem? In this article we will focus on the C2B API offered via Safaricom especially since I believe it’s the one most commonly used by SMEs and Mom and Pap shops, but most of what is stated here probably applies to way more, and I try offer some possible workarounds in the end with a solution that I think if implemented by Safaricom can save a lot of hustle.

C2B Safaricom flow.

C2B Safaricom flow.

Exhibit A: URL registration.

Users of this C2B are expected to expose two endpoints, one for validation and the other for confirmation, These are the endpoints that Safaricom will interact with when a payement transaction by the user is started. The problem? Well they are also accessible to anyone who knows they exist, and the Safaricom API is open and easy for people to just send spoofed requests once they know what endpoint, you might ask, “but where is the problem? only me and my devs know it exists”, but what happens when dev leaves one of the endpoint in one of the frontends by mistake and someone reverse engineers your front end, or what if the endpoints are so basic like just adding a /validate or /result to the current base url? or worse a dev leaves the company who knew the endpoints and they go do fake transactions or share it with their buddies😆. A possible solution is to make sure a different endpoint is registered over periods of time, hopefully this is handled properly on the code and has some randomness to it to prevent former employees who had access to code base being able to predict them, this seems to work fine on sandbox environment however on production automating this change isn’t as easy as sending a REST request as documented on the Daraja docs.

Exhibit B: IP addresses.

Safaricom’s listIPs from daraja dev website

Safaricom’s listIPs from daraja dev website

“But in those endpoints we have added IP restrictions to only Safaricom IPs”,

The Good news you went this far, you are actually checking for IPs, most products out there don’t even do that 😆, the bad news is it might still be undone, why? IP spoofing. Given again that Safaricom has their IPs public, anyone can still use this information and make spoof requests to your endpoints and a transaction can easily be registered though there are ways of detecting this, for example ingress filtering, but again how many do it? Most devs would reach out to checking the IP post data arriving fully, aka via their code from their library/framework which normally just reads the stream and rarely verifies that the IP contained in the header of the Response actually matches the source IP from each packet that was sent, but even if, what happens when Safaricom adds another IP and you don’t update? suddenly you gonna start rejecting valid requests 😐

Exhibit C: Point of validation.

As from the C2B flow diagram that was shown above you will not there is a validation end point, and from the official docs from Daraja you will not that the validation end point is optional, what does this mean? that there is another thing to check, apart from the top exhibits, but also the logic.

The good news if you have enabled the validation endpoint, means that should anyone try spoofing to your results endpoint success messages then you can choose to ignore them if they never had a validation step, this can be done by using state machines with two states per transaction, and we can easily spot a fake result requests, the bad news if both have leaked tough luck, they can fake validation request and result request.

Safaricom’s recommended steps

The recommended steps are good, they acknowledge that these endpoints are a critical point of interaction, as they basically recommend not making the endpoints easily predictable, and also advice one to keep it private to themselves, though the last one might prove hard to do, as often in matters coding, rarely is it ever just 1 person/dev involved, so they are also potential attackers, and as we can remember from Exhibit A automatic endpoint changing isn’t that easy in production, a feature which sandbox environment in Daraja API has.

My solution that Safaricom can adopt.

Simple asymmetric encryption with signatures. The use private and public keys would greatly simplify all the Exhibits we have seen. Something similar to JWT can be used with the following steps:

  1. Safaricom produce a private, and public key pair that they generate on their side, they then share the public key openly, so folks can use it to decrypt the signature.
  2. All the steps can remain as they were, except for the key endpoints we spoke about, validation and result, here Safaricom would hash the message they have probably using sha256, then encrypt it using their private key, this would be the signature, Safaricom then send that request over to the users(our) respective endpoint with that signature as an extra field to what they would have sent before in the JSON…
{
  data: {....} //old fields same as before go here
  signature: asdwqesdasdqweasd //field containing private key encrypted hash of the data field
}
  1. The request reaches our server on the respective endpoint, we hash the data field, and then use the public key that Safaricom shared with us to decrypt the signature field. We then compare the signature decrypted hash to the one we got and if they match we can conclude only Safaricom sent this request, then go forward as we would have, else cancel/invalidate the request before going any further.

This system would solve all our exhibits in the following.

  • Exhibit A: URL registration-> Even if your url leaks, even if the dev knows about it after leaving, even if they share it, you are safe, as only Safaricom has the private key to which can be used to encrypt the signature, hence one can be sure after verifying the message that only Safaricom sent it.
  • Exhibit B: IP addresses -> No more need to have code to keep checking this IPs, Safaricom itself can choose to start rotating them for other services and uses, also no more need to remember to use ingress filtering to confirm each packet, not only will this save more CPU cycles overall but reduce the amount of knowledge required out of the box, the concept of signature verification can easily be implemented on code, and user/dev need not know anything about ingress filtering or bother updating IP lists to configure it.
  • Exhibit C: Point of validation-> Same with exhibition A, no more praying, or wishing, signature can be verified.

I have tried to simplify my solution and keep it as short as possible, but for those who don’t understand perhaps a YouTube search about “asymmetric encryption with signatures” could yield a longer explanation, but you can also watch this short video that tries to explain it too with images and animations, please note: They encrypt the whole message, but my solution we encrypt a hash of the message, for a performance gain.

2 — Cryptography Basics — Digital Signature (youtube.com)

That’s it, you have read through it, thank you for your time, but I am also sure there there are more scenarios and more leaks in Daraja on the other APIs, I didn’t want to write a whole book 😆.


메타데이터
post_id
562b43fc84eb
slug
the-curious-case-of-daraja-the-london-bridge-and-safaricom-562b43fc84eb
url
https://medium.com/@brian.orwe/the-curious-case-of-daraja-the-london-bridge-and-safaricom-562b43fc84eb
canonical_url
https://medium.com/@brian.orwe/the-curious-case-of-daraja-the-london-bridge-and-safaricom-562b43fc84eb
author_url
https://medium.com/@brian.orwe
status
ok
fetched_at
2026-07-22 07:06:13