2

I am trying to update all of our influxdb python queries, so that they are not vulnerable to sql injections.

To do this, I have read that you can use params with the query_api() and specifically with the query_data_frame() (https://medium.com/sekoia-io-blog/avoiding-injections-with-influxdb-bind-parameters-50f67e379abb)

The issue I am running into is that I can not figure out how to get my params to be passed into my queries. Below is an example of one of our queries:

client = InfluxDBClient(url="localhost:5000", token="", timeout=100000, retries=0, enable_gzip=True, profilers="query, operator")
query_api = client.query_api()

ver = "data" # This variable would actually come from a function
params = {
    "ver": ver,
}
query =                      '''from(bucket: "db")
                                |> range(start: -200d)
                                |> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")
                                |> filter(fn: (r) => r._measurement == "test_result")
                                |> filter(fn: (r) => r.version == ver)
                                |> keep(columns: ["_time", "test", "run", "status_tag", "duration_sec", "version"])'''

df = query_api.query_data_frame(query=query, params=params)

Running the above gives me a HTTP response body: b'{"error":"type error 5:75-5:78: undefined identifier \\"ver\\""}\n' error.

Does anyone know how to inject params correctly into a flux query with Python?

I also used the following for help: https://influxdb-client.readthedocs.io/_/downloads/en/stable/pdf/

Update based on user16442705 question

I tried another variable name within my dict, and it yielded the same result. I also tried using $ in the query which yielded a different error. See the below code with errors:

client = InfluxDBClient(url="localhost:5000", token="", timeout=100000, retries=0, enable_gzip=True, profilers="query, operator")
query_api = client.query_api()

ver = "data" # This variable would actually come from a function
params = {
    "pVersion": ver,
}
query =                      '''from(bucket: "db")
                                |> range(start: -200d)
                                |> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")
                                |> filter(fn: (r) => r._measurement == "test_result")
                                |> filter(fn: (r) => r.version == pVersion)
                                |> keep(columns: ["_time", "test", "run", "status_tag", "duration_sec", "version"])'''

df = query_api.query_data_frame(query=query, params=params)

HTTP response body: b'{"error":"type error 5:67-5:80: undefined identifier \\"pVersion\\""}\n'

client = InfluxDBClient(url="localhost:5000", token="", timeout=100000, retries=0, enable_gzip=True, profilers="query, operator")
query_api = client.query_api()

ver = "data" # This variable would actually come from a function
params = {
    "pVersion": ver,
}
query =                      '''from(bucket: "db")
                                |> range(start: -200d)
                                |> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")
                                |> filter(fn: (r) => r._measurement == "test_result")
                                |> filter(fn: (r) => r.version == $pVersion)
                                |> keep(columns: ["_time", "test", "run", "status_tag", "duration_sec", "version"])'''

df = query_api.query_data_frame(query=query, params=params)

HTTP response body: b'{"error":"loc 0:0-0:0: expected an operator between two expressions"}\n'

Another data point to note is that we are using the following versions:

  • Influxdb-Version: 1.8.6
  • influxdb-client: 1.19.0
Ryan Burch
  • 500
  • 4
  • 11
  • Does it work if you pass a hardcoded string like `"foo"` instead of `$pVersion`? If so, it's a different problem. –  Jul 14 '21 at 22:48
  • Yes, if I pass the string inline it works. It also works if I pass the variable inline with `f'{pVersion}'` – Ryan Burch Jul 14 '21 at 22:51
  • Maybe you need to prefix your param names with `_`? From the example [here](https://github.com/influxdata/influxdb-client-python/pull/220#issue-607502337). –  Jul 14 '21 at 22:59
  • @user16442705 also not working for me... – Ryan Burch Jul 14 '21 at 23:13
  • Hmm, I'm stumped. Could there be a version mismatch or something like that? [This](https://github.com/influxdata/influxdb-client-python/pull/220#issue-607502337) seems just like what you're doing. –  Jul 14 '21 at 23:19
  • 1
    I agree, I have opened a bug on Influxdb-client, https://github.com/influxdata/influxdb-client-python/issues/285 – Ryan Burch Jul 14 '21 at 23:33

3 Answers3

1

The issue is actually with the version of influxdb I was using (1.8.6). The query params is not a feature of Influxdb 1.8.6, and was only introduced into Influxdb 2.0.x

See the link below for a question opened with the Influxdb-python-client team. https://github.com/influxdata/influxdb-client-python/issues/285

Ryan Burch
  • 500
  • 4
  • 11
1

It appears that parameterized queries are only supported by Influx v2 Cloud. I've been fighting some similar issues in Golang for a bit and found that my local instance of Influx does not support it. Slightly frustrating that it is only a Cloud feature.

Influx blog post about parameterized queries Third sentence first paragraph states it is a Influx Cloud feature

Influx Cloud documentation vs Influx V2 OSS documentation Notice that there is no documentation for parameterized queries at the bottom of the page

0

Try using $ver in your query string, instead of ver.

client = InfluxDBClient(url="localhost:5000", token="", timeout=100000, retries=0, enable_gzip=True, profilers="query, operator")
query_api = client.query_api()

ver = "data" # This variable would actually come from a function
params = {
    "ver": ver,
}
query = '''from(bucket: "db")
           |> range(start: -200d)
           |> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")
           |> filter(fn: (r) => r._measurement == "test_result")
           |> filter(fn: (r) => r.version == $ver)  # <--------------------------------- 
           |> keep(columns: ["_time", "test", "run", "status_tag", "duration_sec", "version"])'''

df = query_api.query_data_frame(query=query, params=params)

Disclaimer