CVE-2021-43815 (published 2021-12-10T21:15Z)

Grafana is an open-source platform for monitoring and observability. Grafana prior to versions 8.3.2 and 7.5.12 has a directory traversal for arbitrary .csv files. It only affects instances that have the developer testing tool called TestData DB data source enabled and configured. The vulnerability is limited in scope, and only allows access to files with the extension .csv to authenticated users only. Grafana Cloud instances have not been affected by the vulnerability. Versions 8.3.2 and 7.5.12 contain a patch for this issue. There is a workaround available for users who cannot upgrade. Running a reverse proxy in front of Grafana that normalizes the PATH of the request will mitigate the vulnerability. The proxy will have to also be able to handle url encoded paths.

Severity: LOW
CVSS v2 base score: 3.5 (AV:N/AC:M/Au:S/C:P/I:N/A:N)
CVSS v3 base score: 4.3, MEDIUM (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N)

Weakness information:
cwe_id: CWE-22
cwe_name: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
description: The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.
extended_description: 
            Many file operations are intended to take place within a restricted directory. By using special elements such as ".." and "/" separators, attackers can escape outside of the restricted location to access files or directories that are elsewhere on the system. One of the most common special elements is the "../" sequence, which in most modern operating systems is interpreted as the parent directory of the current location. This is referred to as relative path traversal. Path traversal also covers the use of absolute pathnames such as "/usr/local/bin" to access unexpected files. This is referred to as absolute path traversal.
         
         

Fix information:
repo_url: https://github.com/grafana/grafana
commit_details: repo_url: https://github.com/grafana/grafana
author: Timur Olzhabayev
author_date: 2021-12-10 16:52:27+01:00
msg: chore(release-notes): add release notes for 8.2.3 and 7.5.12 (#42987)

* chore(release-notes): add release notes for 8.2.3 and 7.5.12

* chore(release-notes): add release notes to the index

* chore(release-notes): add release notes to index and changelog

* chore(release-notes): add release notes to index and changelog

* chore(latest.json): bump
repository: repo_url: https://github.com/grafana/grafana
repo_name: grafana/grafana
description: The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more. 
repo_language: TypeScript
owner: grafana
file_changes: filename: CHANGELOG.md
change_type: ModificationType.MODIFY
diff: @@ -1,3 +1,11 @@
+<!-- 8.3.2 START -->
+
+# 8.3.2 (2021-12-10)
+
+- **Security**: Fixes CVE-2021-43813 and CVE-2021-PENDING. For more information, see our [blog](https://grafana.com/blog/2021/12/10/grafana-8.3.2-and-7.5.12-released-with-moderate-severity-security-fix/
+
+<!-- 8.3.2 END -->
+
 <!-- 8.3.1 START -->
 
 # 8.3.1 (2021-12-07)

programming_language: Markdown
filename: _index.md
change_type: ModificationType.MODIFY
diff: @@ -8,6 +8,7 @@ weight = 10000
 Here you can find detailed release notes that list everything that is included in every release as well as notices
 about deprecations, breaking changes as well as changes that relate to plugin development.
 
+- [Release notes for 8.3.2]({{< relref "release-notes-8-3-2" >}})
 - [Release notes for 8.3.1]({{< relref "release-notes-8-3-1" >}})
 - [Release notes for 8.3.0]({{< relref "release-notes-8-3-0" >}})
 - [Release notes for 8.3.0-beta2]({{< relref "release-notes-8-3-0-beta2" >}})
@@ -45,6 +46,7 @@ about deprecations, breaking changes as well as changes that relate to plugin de
 - [Release notes for 8.0.0-beta3]({{< relref "release-notes-8-0-0-beta3" >}})
 - [Release notes for 8.0.0-beta2]({{< relref "release-notes-8-0-0-beta2" >}})
 - [Release notes for 8.0.0-beta1]({{< relref "release-notes-8-0-0-beta1" >}})
+- [Release notes for 7.5.12]({{< relref "release-notes-7-5-12" >}})
 - [Release notes for 7.5.11]({{< relref "release-notes-7-5-11" >}})
 - [Release notes for 7.5.10]({{< relref "release-notes-7-5-10" >}})
 - [Release notes for 7.5.9]({{< relref "release-notes-7-5-9" >}})

programming_language: Markdown
filename: release-notes-7-5-12.md
change_type: ModificationType.ADD
diff: @@ -0,0 +1,13 @@
++++
+title = "Release notes for Grafana 7.5.12"
+[_build]
+list = false
++++
+
+<!-- Auto generated by update changelog github action -->
+
+# Release notes for Grafana 7.5.12
+
+### Bug fixes
+
+- **Security**: Fixes CVE-2021-43813 and CVE-2021-PENDING. For more information, see our [blog](https://grafana.com/blog/2021/12/10/grafana-8.3.2-and-7.5.12-released-with-moderate-severity-security-fix/)

programming_language: Markdown
filename: release-notes-8-3-2.md
change_type: ModificationType.ADD
diff: @@ -0,0 +1,13 @@
++++
+title = "Release notes for Grafana 8.3.2"
+[_build]
+list = false
++++
+
+<!-- Auto generated by update changelog github action -->
+
+# Release notes for Grafana 8.3.2
+
+### Bug fixes
+
+- **Security**: Fixes CVE-2021-43813 and CVE-2021-PENDING. For more information, see our [blog](https://grafana.com/blog/2021/12/10/grafana-8.3.2-and-7.5.12-released-with-moderate-severity-security-fix/)

programming_language: Markdown
filename: latest.json
change_type: ModificationType.MODIFY
diff: @@ -1,4 +1,4 @@
 {
-  "stable": "8.3.1",
-  "testing": "8.3.1"
+  "stable": "8.3.2",
+  "testing": "8.3.2"
 }

programming_language: None
repo_url: https://github.com/grafana/grafana
commit_details: repo_url: https://github.com/grafana/grafana
author: Marcus Efraimsson
author_date: 2021-12-10 16:10:04+01:00
msg: Backport fix to main (#42979)

* fixes

(cherry picked from commit a2c386915ce11b9422f4af8ae181eaa1a22bc5c3)
(cherry picked from commit 06706efbbe59ad9d3075835cc31e2f734e36df95)

* fix regex

(cherry picked from commit a259213a3badc9618e969f2c8db0a0143f00faee)
(cherry picked from commit 1d7105c0959df2083814237024f7ec098a76099b)

* lint (#42970)

(cherry picked from commit afb9e8e5f3c33fa59c5a1053d98d8d97815af002)

Co-authored-by: Will Browne <will.browne@grafana.com>
Co-authored-by: malcolmholmes <42545407+malcolmholmes@users.noreply.github.com>
repository: repo_url: https://github.com/grafana/grafana
repo_name: grafana/grafana
description: The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more. 
repo_language: TypeScript
owner: grafana
file_changes: filename: plugins.go
change_type: ModificationType.MODIFY
diff: @@ -490,15 +490,15 @@ func (hs *HTTPServer) pluginMarkdown(ctx context.Context, pluginId string, name
 	}
 
 	// nolint:gosec
-	// We can ignore the gosec G304 warning on this one because `plugin.PluginDir` is based
-	// on plugin the folder structure on disk and not user input.
-	path := filepath.Join(plugin.PluginDir, fmt.Sprintf("%s.md", strings.ToUpper(name)))
+	// We can ignore the gosec G304 warning since we have cleaned the requested file path and subsequently
+	// use this with a prefix of the plugin's directory, which is set during plugin loading
+	path := filepath.Join(plugin.PluginDir, mdFilepath(strings.ToUpper(name)))
 	exists, err := fs.Exists(path)
 	if err != nil {
 		return nil, err
 	}
 	if !exists {
-		path = filepath.Join(plugin.PluginDir, fmt.Sprintf("%s.md", strings.ToLower(name)))
+		path = filepath.Join(plugin.PluginDir, mdFilepath(strings.ToLower(name)))
 	}
 
 	exists, err = fs.Exists(path)
@@ -510,11 +510,15 @@ func (hs *HTTPServer) pluginMarkdown(ctx context.Context, pluginId string, name
 	}
 
 	// nolint:gosec
-	// We can ignore the gosec G304 warning on this one because `plugin.PluginDir` is based
-	// on plugin the folder structure on disk and not user input.
+	// We can ignore the gosec G304 warning since we have cleaned the requested file path and subsequently
+	// use this with a prefix of the plugin's directory, which is set during plugin loading
 	data, err := ioutil.ReadFile(path)
 	if err != nil {
 		return nil, err
 	}
 	return data, nil
 }
+
+func mdFilepath(mdFilename string) string {
+	return filepath.Clean(filepath.Join("/", fmt.Sprintf("%s.md", mdFilename)))
+}

programming_language: Go
filename: csv_data.go
change_type: ModificationType.MODIFY
diff: @@ -77,13 +77,14 @@ func (s *Service) handleCsvFileScenario(ctx context.Context, req *backend.QueryD
 }
 
 func (s *Service) loadCsvFile(fileName string) (*data.Frame, error) {
-	validFileName := regexp.MustCompile(`([\w_]+)\.csv`)
+	validFileName := regexp.MustCompile(`^\w+\.csv$`)
 
 	if !validFileName.MatchString(fileName) {
 		return nil, fmt.Errorf("invalid csv file name: %q", fileName)
 	}
 
-	filePath := filepath.Join(s.cfg.StaticRootPath, "testdata", fileName)
+	csvFilepath := filepath.Clean(filepath.Join("/", fileName))
+	filePath := filepath.Join(s.cfg.StaticRootPath, "testdata", csvFilepath)
 
 	// Can ignore gosec G304 here, because we check the file pattern above
 	// nolint:gosec

programming_language: Go