7

I have a debate about how to properly log errors for the client part (Java Swing) of a client-server application from a security point of view.

I think it is common sense that exposing error details like exceptions and stacktraces to 'untrusted' users is bad practice and at least can weaken your application security through information disclosure (internal structure, dependencies, etc.).

The solution on the server-side can be solved by ensuring to not expose any error details to your users and storing the details securely on the server. This way the error details can be looked up later by dedicated people during an investigation when needed.

But how can you accomplish to store the error details on the client without exposing it to the user?

A few things came to my mind but each is flawed at certain points.

  1. Sending error details to a dedicated server where they are stored for later lookup.
    • How to send error details for problems in the communication layer (no external communication is possible at all)?
    • Your log server is not accessible from the client network (firewall rules, proxies, etc.).
  2. Asymmetric encrypt error details
    • Potential performance impact during logging.
    • Error details must be decrypted during the error investigation, which makes the process more cumbersome.

On the other hand, you can argument that exposing error details from a client application is not as critical as for error details from a server application.

  • The users already have access to the client binary that can be used gather internal information (reverse-engineering).
  • Most communication details can be gathered by sniffing the traffic between client and server.
  • Internal knowledge about a client application is (in most cases) not as valuable as about the server, because the client acts mainly as an UI and the essential business logic resides on the server.

What are the 'best practices' or the best compromises to store error details on the client from a security point of view? Or to put it differently, is it worth to hide error details (exceptions, stacktraces, etc.) for a client application?

1

Let's try looking at this using threat modeling techniques.

What are we trying to protect?

Client logs for later analysis by support.

What is our risk?

If a client-side handler breaks and is stored on the client side, what could this lead to? Are we looking at having a local command execution, log injection, etc.? It is essential to understand what the application provides, and what could be compromised.

Yes client-side is always dangerous, that doesn't mean it can't be protected or understood.

What's our attacker like?

  1. Basic user: Scrapes the history of the application, tries to search for the files on the system, mainly conducts basic lookup and recon.
    • Risks: tries to understand and haves fun with what breaks the UI controls and how they can change the output. If the logs contain secrets disclosed, they'll be able to grab them and abuse the system (or blackmail the org).
    • Mitigations: employing symmetrical encryption protects the logs as the user don't have enough knowledge to reverse engineer the application and grab the key. If the logs sanitize the input and don't output secrets, the risks are almost non-existent.
  2. Advanced user: on top of the Basic User, this user is capable to have a stronger understanding of what is breaking, and tries to fuzz the service in order to force an unhandled behavior (which could break it). This user is capable to reverse engineer and extract strings from the application if stored.
    • Risks: by identifying how the application behaves, this user is capable to study the client application, identifying its weaknesses, and possibly find issues in it (DoS, local execution, etc.). This user will in most cases report the vulnerabilities or issues to the company behind the application.
    • Mitigations: Create a mapping of the errors with codes which are only known by support. The user will be able to know the exception triggered, but not the details of how it broke exactly and what's happening. Becomes a blind attack (harder to achieve). As u mentioned, asymmetrical encryption can be used. What you can do to speed things up is the use of a nonce with the key in order to create ephemeral sessions, which requires from the user to instantly break the logs and look them up, otherwise only support can get it.
  3. Malicious user: similar to the advanced user, with clear intent to cause damage.
    • Risks: the user builds exploits to try and own other users' systems, destroy the company reputation, etc.
    • Mitigations: in this case, if the application is actually exploitable, the user will already have identified what's happening, and encryption is almost meaningless at this stage. The logs would only confirm the analysis of the attacker. Since this is specifically related to logs, asymmetrical encryption should be used, with possible triggers that call back home if a certain activity is launched or done (system takes too long to conduct a task, a system command is executed, network exfiltration, etc.). This allows for proactive controls which is the best mechanism to protect your user-base.

In all cases, the network attacks are not catered for. The nonce is a public entity, thus always retrievable. Otherwise, no specific secrets were communicated through the channels. I mainly focused on application behavior. There are no major network attacks related to the above approaches.

0

I think there is a bit of misunderstanding at the beginning here. You may absolutely want not to output server exceptions at bad requests, and possibly use a GUID to track server requests to client support calls. Because, as you said, exposing unneeded details may extend the server's attack surface, which normally causes harm if exploited.

But now, from the client's point of view, such thoughts don't necessarily apply. Ask yourself what you have to protect on the client side.

  • Protect the source code and the company's IP?

Don't rely on this. Use a proper obfuscator, which also obfuscates stack traces coherently and is paired with source maps to "deobfuscate" the logs when calling support.

  • Protect from a server exploit?

Never trust user input from the server side. Assume that the client is rogue, manipulated by someone. Use authentication, validate input, enforce utilization checks.

  • Enforce a DRM/paywall

This is another way to tell the previous. Obfuscate your code to make it a hard life to break the DRM scheme, but still validate, validate, validate on the server side. Don't answer the client if the user account has no credit.

Stack traces make no difference when the server is robust

Other thoughts:

can weaken your application security through information disclosure (internal structure, dependencies, etc.).

This can be still achieved with a decent decompiler for the Java world. Dependencies are either stored as jar or embedded in a fat jar. I could even try to guess the exact versions of the framework you depend on if I had your Java binary. Especially when obfuscated.

What are the 'best practices' or the best compromises to store error details on the client from a security point of view?

If I have to speak a name, JetBrain's IntelliJ IDEA Ultimate, which is a paid desktop application, produces non-encrypted logs that I can review before sending in to support. The software is obfuscated to prevent breaking their DRM/licensing scheme. Which, however, is being regularly broken and fixed like any other client-side scheme

-1

I think best practice you should not display full exceptions and stack traces in your GUI to the user. Show them just a friendly message like "sorry, contact our help desk"

If you want to store errors locally to sync them to the mothership at a later date that seams reasonable , just don't store them in a clear text file or on a screen in the GUI. Store them in a file that has restricted permissions . Or store them in a local file that is encrypted. Or store them in a local database that is protected with all your other sensitive data.

If an attacker is already on the box and snooping around they probably aren't that interested in their error messages. If they are serious about breaking into your app they probably will use a debugger and / or reverse it so again probably not too concerned about your error messages.

One big thing to consider when logging errors is ensuring you are sanitizing out sensitive things like passwords, customer data, credit cards, ssns, PII, etc so that they are not in your logs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.