Monzo urges 480k customers to change their pin numbers
theguardian.com
theguardian.com
I love Monzo, but one thing that does concern me greatly are banking apps (or any apps that touch highly sensitive pieces of information) that include third party components or make any communication to third parties.
In the case of Monzo: https://reports.exodus-privacy.eu.org/en/reports/88809/
+ Facebook Analytics
+ Facebook Login
+ Google Ads
+ Google CrashLytics
+ Google DoubleClick
+ Google Firebase Analytics
And according to NetGuard locally:
ws-eu.pusher.com
graph.facebook.com
e.crashlytics.com
app.adjust.com
graph.accountkit.com
Of those, aside from generally "Why?" I'm most concerned by crashlytics.com . Is this like Sentry? Does it send a stack on a crash? If I'm paying someone and entered my PIN and it crashes, did my PIN go to a third party?I saw an app recently that gave me the option in the settings to opt out of crashlytics - more of that please!
I'd be much happier seeing nothing third party in apps that deal with sensitive information.
And I'd be happy to memorise a 2nd less important software PIN for app transaction authorisation that wasn't the same as the ATM and hardware PIN.
Two APIs were accepting the PIN as URL parameters on GET requests, since in terms of REST principles, the operations were to retrieve information.
They were changed to non-GETs with the PIN sent in the body instead. The apps needed to be updated to switch to the new APIs.
That's worse than accidental logging.
Engineers should know the GET params get logged fairly routinely and shouldn't be used for anything sensitive.
But if you're terminating TLS on behalf of a customer, you can see everything. e.g. https://new.blog.cloudflare.com/terminating-service-for-8cha...
> Among other things, that resulted in us cooperating around monitoring potential hate sites on our network and notifying law enforcement when there was content that contained an indication of potential violence.
That indicates deep inspection of traffic going through CloudFlare.
Before:
.method public abstract pan(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lio/reactivex/Single;
.param p1 # Ljava/lang/String;
.annotation runtime Lretrofit2/http/Query;
value = "account_id"
.end annotation
.end param
.param p2 # Ljava/lang/String;
.annotation runtime Lretrofit2/http/Query;
value = "card_id"
.end annotation
.end param
.param p3 # Ljava/lang/String;
.annotation runtime Lretrofit2/http/Query;
value = "challenge_type"
.end annotation
.end param
.param p4 # Ljava/lang/String;
.annotation runtime Lretrofit2/http/Query;
value = "challenge"
.end annotation
.end param
.param p5 # Ljava/lang/String;
.annotation runtime Lretrofit2/http/Query;
value = "idempotency_key"
.end annotation
.end param
.annotation system Ldalvik/annotation/Signature;
value = {
"(",
"Ljava/lang/String;",
"Ljava/lang/String;",
"Ljava/lang/String;",
"Ljava/lang/String;",
"Ljava/lang/String;",
")",
"Lio/reactivex/Single<",
"Lcom/monzo/card/data/api/PanResponse;",
">;"
}
.end annotation
.annotation runtime Lretrofit2/http/GET;
value = "card/pan"
.end annotation
.end method
After (v2.59.1 has the fix): .method public abstract pan(Lcom/monzo/card/data/api/RetrievePanRequest;)Lio/reactivex/Single;
.param p1 # Lcom/monzo/card/data/api/RetrievePanRequest;
.annotation runtime Lretrofit2/http/Body;
.end annotation
.end param
.annotation system Ldalvik/annotation/Signature;
value = {
"(",
"Lcom/monzo/card/data/api/RetrievePanRequest;",
")",
"Lio/reactivex/Single<",
"Lcom/monzo/card/data/api/PanResponse;",
">;"
}
.end annotation
.annotation runtime Lretrofit2/http/PUT;
value = "card/retrieve-pan"
.end annotation
.end methodIdempotency and implications for which operations can be cached is why.
GETs are cacheable, but if a PIN can change so can the answer. This is an authentication action, and it should have been POST.
For my company, it's all POST-only, no URL params allowed, all inputs as JSON in the body only, no resource IDs in the path - just the method & version only.
Principle of least surprise and all that.
AdColony
Adincube
AppLovin
ATInternet
Facebook Ads
Google Ads
Google CrashLytics
Google DoubleClick
Google Firebase Analytics
Inmobi
MAdvertise
Millennial Media
Ogury Presage
Smart
Tapjoy
Twitter MoPub
Unity3d AdsIt's just like Sentry and does send back stack traces on a crash or any error the developer chooses to send back.
Crashlytics part of fabric.io, which was bought by Google and is actively being integrated into Google's Firebase.
dig internal-api.monzo.com
;; QUESTION SECTION:
;internal-api.monzo.com. IN A
;; ANSWER SECTION:
internal-api.monzo.com. 288 IN CNAME k8s-worker-external-alb-prod-1306866561.eu-west-1.elb.amazonaws.com.
k8s-worker-external-alb-prod-1306866561.eu-west-1.elb.amazonaws.com. 8 IN A 34.254.57.66
k8s-worker-external-alb-prod-1306866561.eu-west-1.elb.amazonaws.com. 8 IN A 52.212.7.167
k8s-worker-external-alb-prod-1306866561.eu-west-1.elb.amazonaws.com. 8 IN A 34.255.246.8
Monzo the bank, runs from Amazon and not via Cloudflare. dig www.monzo.com
;; QUESTION SECTION:
;www.monzo.com. IN A
;; ANSWER SECTION:
www.monzo.com. 59 IN A 104.25.212.99
www.monzo.com. 59 IN A 104.25.211.99
Monzo the marketing website for the bank, uses Cloudflare.If you go through the DNS logs for the Monzo app, you'll see everything else goes direct... Google, Facebook, Status Page, AWS.
With the only exception being some image assets:
dig monzo-prod-user-images.imgix.net
;; QUESTION SECTION:
;monzo-prod-user-images.imgix.net. IN A
;; ANSWER SECTION:
monzo-prod-user-images.imgix.net. 2280 IN CNAME dualstack.com.imgix.map.fastly.net.
dualstack.com.imgix.map.fastly.net. 4 IN A 151.101.18.208I would argue that using a third party that specialises in security is better than remaking the wheel yourself.
Cloudflare invest a significant amount in the security of their platform and have a lot of talented engineers that focus solely on that. They have a lot more data to play around with and I would expect they can do a better job at security than Monzo alone, with their own infrastructure, with their own engineers. Note that Cloudflare is PCI compliant (https://support.cloudflare.com/hc/en-us/articles/202249734-C...)
Not sure I understand the hype of remaking the wheel, when specialist services exist that probably do the work better, more safely and cheaper.
The leaked PINs were "leaked" to employees (and even then there's no evidence they were misused) and I expect them to be able to do damage even without those PINs if they wanted to, so to me it's not that big of a deal. The risk here could be if you reused the PIN on other cards.
Different PIN for app and ATM.
'Always on' app not being always on. By this I mean opening the app and instantly being logged - no password - in with balance, transaction history, access to funds, etc. Material concern if phone lost. N26 by comparison always request password.
Again, comparing to N26, no self-imposed limit on ATM or online transactions. In N26 this is set in the app/web interface. Monzo doesn't have this self-set limit feature.
No web interface. Using a phone for everything is annoying.
Monzo do have very responsive and knowledgable customer service. And a very distinctively coloured card.
[1] https://krebsonsecurity.com/2019/03/facebook-stored-hundreds...
[2] https://www.theverge.com/2019/5/21/18634842/google-passwords...
This design is safe because your systems don't have any secrets to mistakenly log or otherwise lose. Make things we don't want to happen _impossible_ and they'll stop happening. Merely saying "Don't do that" doesn't make it stop happening.
Your site can literally post all the WebAuthn registration data for users on the front page, and it won't make it any easier for bad guys to sign in as those users, there aren't any secrets in there. That's a correct design.
These systems are typically backed by HSMs, and the HSM generates a high-entropy "challenge". The challenge is sent to the client, which combines the challenge with the characters the user entered. The resulting hash is sent back to the HSM, which can verify internally that the correct characters were selected, by computing the expected hash for the correct response (hopefully in constant-time).
It seems there is a bigger issue here -- Monzo used card PINs as a generic security credential in their app, and was storing them in a recoverable form (albeit only accessible to a very small number of staff). That's not standard practice elsewhere that I'm aware of - given use of the PIN is the "proof" you approved the transaction, it's usually used only in environments with dedicated PIN entry devices (ATM, card readers), rather than commodity devices (phones), unless those go through PCI-style verification and approval.
The problem is not that we can't do this securely, it's two separate but related problems:
1. The web stack was never designed for RPC and attempts to use it that way are often unsafe.
2. Poor or missing libraries to make common patterns safe. Why was the logging framework happy to log the PIN, well, because the type system didn't know the PIN is sensitive. Why was the PIN even sent in the clear at all, well, because libraries to do this securely aren't well known and the web doesn't help.
Imagine how long this would have been an issue if it had happened at Barclays or TSB.
Not entirely: https://www.bbc.co.uk/news/business-44121901
https://www.theguardian.com/business/2018/apr/28/warning-sig...
Equifax was a "security blunder of the highest order". This is an it-happened-to-Facebook-and-Google "shit, some sensitive info ended up in internal logs" blunder where there's no reason to suspect the PINs actually leaked out of the company. And even if they did, a PIN on its own is not sensitive information - unlike a password, it's just a 4 digit number, there's only 10000 of them. And unlike SSNs, they can be changed. I can tell you my PIN is 1077 and what on earth are you going to do with that information?
No information was leaked... it's really kind of a non-issue. Monzo's approach is radical transparency. Any other bank probably would have never said anything.
How can you be sure of that?
I don’t know what any of these words mean, and I’m relatively technical
The sign-in I use requires a password (something you know) and a OTP generated by an irretrievable key, eg, something I have.
Using LineageOS lets you do many more awesome things with your device, but financial apps (and even some apps like bus ticket apps) often don't work on this setup because it's viewed as insecure.
It's your personal personal identification number number
That page does link to 'Ostensive definition' though:
"An ostensive definition conveys the meaning of a term by pointing out examples"
So perhaps 'Auto-ostensive'?