This website uses cookies

To provide the highest level of service we use cookies on this site.
Your continued use of the site means that you agree to their use in accordance with our terms and conditions.

Pentest Chronicles

Breaking license validation in a desktop application – how business logic flaw can enable unauthorized activations.

Piotr Ćwikliński

March 07, 2025

Introduction


During one of my security audits, I discovered a business logic flaw in the license verification process of a macOS desktop application. This flaw made it possible for an ordinary user with basic hacking skills to bypass restrictions and activate the software on multiple devices, even though the license was meant for just one machine.

The issue was caused by insufficient server-side validation. While some parameters and their values in the activation request were correctly validated, others were either ignored or not used at all for verification. As a result, it was possible to reuse a legitimate activation request with only minor modifications, completely bypassing the licensing system.

In this article, I’ll explain how this vulnerability works, go through a step-by-step example of how it can be exploited and discuss what can be done to properly secure the license activation process.

The environment

The test was conducted on a web application environment, which included a backend and frontend component.
The backend consisted of an API responsible for license verification, located at https://license-api.example.domain/. This is a placeholder and does not reflect the actual API address of the tested application.

The frontend included a License Manager, which is a web panel for managing purchased licenses, available at https://license-portal.example.domain/. This is also a placeholder and does not correspond to any real-world service. The system also included a macOS desktop application, which communicated with the API to handle licensing.

The vulnerability was found in the license activation process, which is triggered when a user enters a purchased license key in the macOS application.

How license activation works

When a user activates the software, the macOS application sends a request to the API to register the license on a specific device. A properly designed licensing system should ensure that each activation is linked to a unique device, that all request parameters are fully validated and that license sharing between multiple devices is not possible. It should also be designed to reject modified or replayed activation requests.

During testing, I found that some values in the request were properly validated, but others were completely ignored by the server. Because of this, it was possible to reuse an existing license activation request with minor modifications, allowing the same license to be activated on multiple devices without any errors. The system also failed to verify whether a request came from the same device that had originally activated the license, which made it possible to trick the API into thinking that a new machine was a previously authorized one.

EXPLOITING THE LICENCE ACTIVATION MECHANISM

What’s needed for the attack?

Exploiting this issue doesn’t require any advanced hacking skills. A user only needs a valid license key for the application, a way to intercept and modify network traffic, such as Burp Suite or a similar proxy tool and basic knowledge of how HTTP requests work. No special privileges or reverse engineering of the application are required.

Step-by-step exploitation

Step 1: Capturing the activation request

To intercept the activation request, the attacker needs to configure their system to route traffic through a proxy. In this case, the tested application was proxy-aware, meaning it respected system-wide proxy settings, so it was enough to set Burp as the system's HTTP/HTTPS proxy to capture the network traffic.

However, not all applications behave this way. Some are non-proxy-aware, meaning they ignore system proxy settings and communicate directly with the server. In such cases, the attacker would need to enable invisible proxying in Burp Suite. This technique allows Burp to intercept connections even from applications that do not explicitly use a proxy, making it possible to inspect and modify requests.

Once the proxy is set up, the attacker can capture the license activation request. Below is an example request with sample values for readability:


By intercepting the request, the users gain full visibility into the license activation mechanism, allowing them to analyze how the system verifies activations and identify potential weaknesses in the validation process.

Step 2: Identifying the weakness in validation

By analyzing the intercepted request, it became clear that the serial was the main device identifier used for activation. However, since the server did not strictly verify all parameters, this serial number could be reused on different devices by slightly modifying the request.

Step 3: Replaying the activation on another device

On a second machine, I started the activation process again and intercepted the request. This time, I modified it by keeping only the required parameters and using new values for the ones that were not being properly validated. Below is an example of the modified request:


Since the server was only checking specific values, it processed the activation request successfully, even though it came from a completely different device.

Step 4: Confirming unauthorized activation

The server responded with a successful activation message, confirming that the same license was now active on a second device:


At this point, the licensing restrictions had been completely bypassed, allowing a single license to be used on multiple machines.

How to fix license validation

A proper fix for this issue should ensure that the license activation process is secure, device-bound and resistant to request manipulation. One of the best ways to achieve this is by separating license validation from device identification.

Instead of relying on the license key and serial number, the server should generate a unique secret for each activation. This secret should be tied to both the license key and the specific device and should be used in a challenge-response mechanism instead of being sent in every request.

Additionally, session tokens should be used to maintain an active session, ensuring that users don’t have to repeatedly authenticate while still preventing unauthorized device reuse. If the same session token or secret is detected on multiple devices, the system should immediately revoke access.

Example implementation in Python (HMAC-SHA256)

One way to implement this security mechanism is by using HMAC-SHA256 authentication. Below is an example of how this process could work:


By implementing this approach, each device has a unique cryptographic secret, preventing activation requests from being replayed or modified without authorization. Even if an attacker gains access to a valid activation request, they wouldn’t be able to reuse it, as the session relies on dynamically generated values rather than static credentials.

This method not only enhances security but also provides a more robust way to detect and prevent license abuse, ensuring that the software is only used within the intended licensing terms.

Conclusions

This vulnerability exposes a serious flaw in the way license activation is handled. By failing to properly validate all parameters and relying on static values like the serial, the system allows a single license to be activated on multiple devices with minimal effort. A regular user with basic hacking knowledge can exploit this issue simply by modifying a request, leading to license abuse, financial losses and potential software piracy.

The best way to prevent this issue is by implementing a more secure authentication process that separates license validation from device identification. Instead of allowing static values to be reused, the system should generate a unique, device-bound secret and use cryptographic challenge-response authentication to verify activations. Additionally, session monitoring should be in place to detect multiple concurrent activations and block unauthorized usage before it becomes a widespread problem.

This case highlights an important lesson: security isn’t just about preventing injections, buffer overflows or code execution vulnerabilities. Sometimes, simple logic flaws can be just as damaging - especially when they affect business operations like software licensing. Taking the time to review and improve business logic can prevent significant financial and security risks before they are exploited.



Next Pentest Chronicles

When Usernames Become Passwords: A Real-World Case Study of Weak Password Practices

Michał WNękowicz

9 June 2023

In today's world, ensuring the security of our accounts is more crucial than ever. Just as keys protect the doors to our homes, passwords serve as the first line of defense for our data and assets. It's easy to assume that technical individuals, such as developers and IT professionals, always use strong, unique passwords to keep ...

SOCMINT – or rather OSINT of social media

Tomasz Turba

October 15 2022

SOCMINT is the process of gathering and analyzing the information collected from various social networks, channels and communication groups in order to track down an object, gather as much partial data as possible, and potentially to understand its operation. All this in order to analyze the collected information and to achieve that goal by making …

PyScript – or rather Python in your browser + what can be done with it?

michał bentkowski

10 september 2022

PyScript – or rather Python in your browser + what can be done with it? A few days ago, the Anaconda project announced the PyScript framework, which allows Python code to be executed directly in the browser. Additionally, it also covers its integration with HTML and JS code. An execution of the Python code in …

Any questions?

Happy to get a call or email
and help!