The vulnerability is a timing attack (CWE-208) that allows an attacker to enumerate External Reference Codes (ERCs) in Liferay Portal. The root cause is inconsistent handling of different error conditions, specifically 'resource not found' versus 'permission denied'. An attacker could measure the server's response time to distinguish between these cases and thereby determine if a resource exists.
The analysis of the provided patches reveals a coordinated effort to remediate this by unifying the application's response to these different error states:
-
Standardizing 'Not Found' Exceptions: The NoSuchWorkflowDefinitionException, which was thrown when a specific workflow was not found, was made a subclass of the more generic NoSuchModelException. This allowed it to be handled by a centralized mapper, and its own specific, vulnerable mapper (NoSuchWorkflowDefinitionExceptionMapper) was removed.
-
Masking Permissions Errors: The PrincipalExceptionMapper, which handles permission errors, was modified. For GET requests, it now throws a NotFoundException instead of returning a Forbidden status. This makes a permission-denied error appear identical to a not-found error, preventing an attacker from distinguishing between the two.
-
Unifying Response Generation: Both NoSuchModelExceptionMapper and PrincipalExceptionMapper were updated to delegate to the standard NotFoundExceptionMapper. This ensures that the HTTP response (status code, headers, and body) is identical in all three scenarios (not found, model not found, and permission denied on GET).
-
Removing Information Leakage: The NotFoundExceptionMapper itself was patched to stop including the exception message in the response body, preventing any potential information leakage.
The identified vulnerable functions are the specific exception mappers that, prior to the patches, created distinguishable responses for different error conditions. The _getWorkflowDefinition function is also included as it is the source of the exception that triggers the vulnerable handling path. By exploiting the differences in how these functions handled exceptions, an attacker could successfully carry out the timing attack.