December 29 2024
Hey, this is a brief analysis I have done over Openbank (Spain).
Openbank has a 2FA system for certain actions in their app and webapp, this includes checking the full history of movements, even if you are already logged in.
In case you have an Openbank account and want to try it, here is the route of the webapp where you can see movements of an account. Log in, and replace the zeros with the account id.
By default it only displays movements up to around 3 months ago, if you want to see older movements you need to click on the See More movements button, which prompts the following popup (translated from Spanish):
The issue is that this extra security requirement is basically useless because there is an endpoint from their REST API that we can use to literally query all the transactions from the day the account was created.
I made the following script in JavaScript that uses the mentioned endpoint.
You can get your <CONTRACT_ID>
by digging a bit in the app or webapp, and you can get the <AUTH_TOKEN>
by inspecting some of the requests sent by the webapp.
async function get() {
const categories = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
const contracts = ["<CONTRACT_ID>"] // You can put multiple contracts if you want
const authToken = `<AUTH_TOKEN>`;
let data = []
await Promise.all(categories.map(async (code) => {
const res = await fetch("https://api.openbank.es/categorized-transactions/listbycategorycontracts ", {
"credentials": "omit",
"headers": {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0",
"Accept": "application/json",
"Accept-Language": "en-US,en;q=0.5",
"Content-Type": "application/json",
"version": "2",
"openBankAuthToken": authToken,
"Sec-GPC": "1",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-site",
"Pragma": "no-cache",
"Cache-Control": "no-cache"
},
"referrer": "https://clientes.openbank.es/",
"body": JSON.stringify({
temporalGrouping: "Y",
contracts,
from: "1234-01-23", // LOL
to: "2222-11-22", // still far away
categoryCode: code,
banks: null
}),
"method": "POST",
"mode": "cors"
});
const json = await res.json();
data = [
...data,
...json
]
}));
return
data.map(tx => ({
date: new Date(tx.fecha),
title: tx.concept,
amount: tx.monto
}))
.sort((a, b) => a.date - b.date).reverse();
}
const formatter = new Intl.DateTimeFormat('en-US', { day: "numeric", month: "long" });
for(const tx of await get()) {
console.log(`${formatter.format(tx.date)} ${tx.title} ${tx.amount}`);
}
By running this script I am able to see what it seems to be the whole movements history from the day I created my account.
Random example of a log I can see from some years ago:
Note: I used Deno to run the script but you can use other runtimes or even a browser as long as you are in the openbank website.
But here is more to this story, the endpoint used in the script is used in another route of the webapp.
This other route allows us to see the movements up to 1 year ago with no extra steps, though it will get angry at you if you try an older date.
But that's the UI, because in the other hand, the REST endpoint does not care about minimum dates or extra security requirements.
Something I also noticed is that some endpoints and their parameters, are written in English and others in Spanish, perhaps a lack of coordination between teams lead to this.
I think this issue is kinda dumb but at the same time if you think about... they think they have a security feature, but it doesn't really secure anything, does it? What if other things are also not working as expected?
Btw, I already tried to contact Openbank multiple times privately, I never really got an answer regarding the issue, but rather all I got was "Send it to this other X email" or "Thanks for contacting us, we will answer asap!".
Last message I got was an automated response on December 2nd. It seems they can't afford to have a decent technical support.
Idk, perhaps I am just misunderstanding something... Time will tell I guess!
Anyway, you can find me in X, GitHub or LinkedIn.
Imma go watch Squid Game Season 2 now, thanks for reading!