Should the server respond with the error or a generic "try again" message?
If a user makes an API request to the backend and the request fails because the database had an issue, should the server reply with the error that was thrown or should the server reply with a generic "Something went wrong" message?
I'm leaning towards the generic error messages because showing the error that was thrown could allow an attacker to infer what database your using, and usually, you want to hide as much information about your backend from an attacker.
But showing the actual error message would allow users to report bugs and show the developers the actual error message.
I'm curious to hear your thoughts on this.
8 Replies
If you're relying on users to report an error, you're already in trouble. All the user needs to know is "Something went wrong" Send the real errors to your devs, who will actually understand them.
Logging all errors to the database or to a file? I didn't think of that before. Great idea.
We log ours with a discord bot that @'s all the devs. So we know in real-time if something goes wrong.
Ooh. I'm gunna do that except with a webhook
The first message written by @えみり is indeed correct - from the UX perspective, there is no point in passing specific error information to a user if the user is not a developer. The proposed log collection utilizing the discord bot can do the job of informing people of interest about the error. Still, I can't imagine this system could efficiently handle log collection in an even small sized application with ~100 simultaneous users. Depending on your needs I'd opt to create a system similar to the ELK stack if you want to self host or use some 3rd party service like LogRocket or even use some solution provided by the Cloud: Azure Monitor or Amazon CloudWatch.
Nevertheless, if you decide to use a proper log collection and analysis system, the solution will provide - among others - querying the logs, visualizing the errors, etc.
Then, and only then you should report failed requests to the discord... But I will be unhappy seeing a message popping up every minute with logs about the same errors, because most likely user will try again, and again, and again, until his motivation drops.
I'll give you another possible solution for the issue:
Many years ago YouTube had a m0nk3y way of displaying the error for the user without valuable information visible, but it allowed the administrators to see the message you want to pass to an administrator. I did a similar thing when I developed a small internal mobile application. I created a view with the information "Something went wrong" and a button "Report issue". Clicking on "Report issue" resulted in creating an email to the app admin with encrypted content, so I just had to decrypt it to read error content - like a place where it occurred or its stacktrace.
I'll share some remarks from my implementation
The encryption of the backend error should never be done on the frontend.
You encrypt the message on the backend and make a view with it as I described in the previous paragraph, you are 100% safe nobody without a proper decryption key can't read the message. You need to utilize something called "Asymmetric keys".
The different story is to handle application errors coming from the frontend the same way. You want to display the error coming from the application, not the backend response. First - don't use the same encryption key as the server, it's a major security issue. The second to consider is how well you'll hide your encryption key for the app. When developing a mobile app, you know, Java code is easily readable, without mentioning the served javascript bundle. You can think creating a native library (.so) and baking the key there could be safe - unfortunately - no, every key stored in any file is readable with a little reverse engineering knowledge and tools.
To have a great, and mostly problematic key for an attacker to extract is to load the retrieved key into a native library (.so) after authentication. The encryption key should be an Asymmetric encryption rolling key based on various variables you think are sufficient. I strongly recommend utilizing the chosen timestamp format (like Date) with specific, unique user variables. Then you just need to create another application for decrypting the message, or service to grab emails and pass them to some reporting system.
I stopped my implementation at this point, but I still see improvements to be made:
- Request can be intercepted by MITM attack to retrieve a key, but you harden it by signing the request
- There is also an obfuscation part to implement where the encryption key is split into parts and scattered across a memory pool filled with random data, periodically shuffled to make extraction challenging.
From this point, you're playing a cat & mouse game.
For error tracking, I'd generally just use Sentry and not re-invent the wheel unless I absolutely have to and there's a budget for it)