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.