Eclipse EDC: Consumer pull transfer token validation does not apply any rules (e. g., expiration check)
Basic information
Project name: Eclipse EDC
Project id: technology.edc
Maven artifact: org.eclipse.edc:transfer-data-plane
What are the affected versions?
[0.5.0 - current]
Who is affected: Anyone using EDC version 0.5.0 or newer if they (a) have a dataplane configured to support http proxy consumer pull AND (b) include the modules "transfer-data-plane" and "data-plane-public-api".
Details of the issue
The issue is located in the ConsumerPullTransferTokenValidationApiController
at this position in the code ("issue location"):
The TokenValidationService
's validate method takes 3 arguments:
validate(@NotNull String token, PublicKeyResolver publicKeyResolver, TokenValidationRule... rules)
.
But only two arguments are provided in the "issue location".
The third argument determines which rules should be checked during validation.
Therefore, we will have an empty array at runtime, resulting in an empty list.
The ExpirationDateValidationRule
should be checked for context TRANSFER_DATAPLANE_TOKEN_CONTEXT = "dataplane-transfer"
.
See registration to tokenValidationRulesRegistry
.
But the tokenValidationRulesRegistry
is never queried for that context.
In the "issue location" mentioned above, there should be something like tokenValidationRulesRegistry.getRules(TRANSFER_DATAPLANE_TOKEN_CONTEXT)
as the third argument.
Lacking this third argument causes that the token is only checked regarding valid signature.
The expiration is not checked, i.e., expired tokens will indefinitely be considered as valid.
The logic of the "issue location" / ConsumerPullTransferTokenValidationApiController
is used for example in consumer pull scenarios.
In a Consumer Pull scenario the consumer / consumer-side systems can "pull data" from the provider using the token beyond its expiration.
But data cannot only be pulled from the provider by the consumer. With EDC, "data transfers" can be used to modify resources at the provider side. Therefore, the impact of this vulnerability can be twofold:
-
Data can be pulled / data sources can be queried longer than actors are allowed to do so. This threatens confidentiality of the resources as consumers (that are no longer allowed to access the data) can still access the data.
-
There is a feature in EDC to proxy / forward the http request method, path, parameters, payload of the pull towards the data source (i.e., one can effectively expose a Web API to the consumer that can have POST endpoints and accepts payloads etc.). One can use consumer pull to issue an API call (with payload) to the provider's data source and receive the response (proxyMethod/Path/Payload/... feature enables some kind of bi-directional data transfer). Therefore, the threat is not limited to confidentiality / accessing resources longer than allowed but also to modify resources beyond the time allowed => threatens integrity.
Result: Defective expiration / revocation of permissions granted to an entity to access / modify protected (possibly sensitive) resources.
In case the token leaks, entities that were never allowed to access the resources can access them indefinitely.
The only way to prevent access to the resources beyond expiration might be to block all accesses to the public (consumer pull) endpoint until a fix is available and the connector has been updated.
As far as I was able to track, the issue / vulnerability has been introduced with version v0.5.0 via commit https://github.com/eclipse-edc/Connector/commit/19ebb19495dc78c5b27b925baaf378b7e85885c7 and is still present in main branch (i.e., most recent versions).
The issue is located in the maven artifact "org.eclipse.edc:transfer-data-plane" ([0.5.0 - current]).
I'm unsure which CWEs suit best here.
All in all, the issue is a missing check regarding the expiration of a JWT.
So the JWT can be used to access the data source (i.e., a HTTP Endpoint; possibly with the http request method, path, parameter, payload of ones choice) way beyond its expiration.
I would grade the vulnerability as a
CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:N/VA:L/SC:H/SI:H/SA:L
5.6 Medium
-
AV Network, because the (consumer pull) public endpoint at the provider side is exposed to the internet.
-
AC Low, as consumers can just keep using their system to access the resources beyond token expiration time.
-
AT Present, as the consumer needs to have negotiated a contract agreement with the provider and requested a data transfer using http proxy consumer pull method to get the EDR with the token. To threat integrity of subsequent systems, proxyMethod/Path/Payload/... configuration needs to be enabled for the asset.
-
PR Low, one needs access to the consumer's system to request the data from the provider's public (consumer pull) endpoint
-
UI none, no additional user interaction required
-
VC none, as no information is leaked from the connector / control plane
-
VI none, no state change in the connector
-
VA low, small load on the connector to check the token and to proxy/forward the request to the subsequent system (data source / API).
-
SC high, (at least potentially) as the data / API access is provided based on strict policies to other data space participants that must meet certain criteria. => potentially access to sensitive data
-
SI high, (at least potentially) as the data / API access is provided based on strict policies to other data space participants that must meet certain criteria. => potentially access to business critical systems / APIs?
-
SA low, load on the subsequent system / API
Please let me know if the above description is sufficient to understand and assess the vulnerability and what are the next steps in the process.
Steps to reproduce
Run the sample: https://github.com/eclipse-edc/Samples/tree/3a08baeb959b4bc177a3b80814abddd2f37fb254/transfer/transfer-02-consumer-pull
Make sure to use a version before commit https://github.com/eclipse-edc/Samples/commit/e2387fc2e5560c1b84c5a3fd33a776d6792aa0e7 (in that commit they switched from "transfer-data-plane"/"data-plane-public-api" to "transfer-data-plane-signaling"/"data-plane-public-api-v2").
I tested it with revision 3a08baeb959b4bc177a3b80814abddd2f37fb254.
Make sure to use Linux to run the samples (because of this bug)
Use the token to retrieve the data (see 4. step of the guide).
You can inspect the token using jwt.io (by default, the token expires 10 minutes after being issued). Wait 10 minutes, token should be expired then. Repeat step 4. => Token is still accepted.
You can observe that the token / authCode can be used beyond its expiration.
Do you know any mitigations of the issue?
- Block access to the public (consumer pull) endpoint.
Once version with fix is available:
-
Update to version with fix
-
Unblock access to the public (consumer pull) endpoint.
Or take the chance to get rid of deprecated "data-plane-public-api" and switch to "data-plane-public-api-v2" (which is not using the ConsumerPullTransferTokenValidationApiController
with the missing checks).