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
6
  • Does it work if you pass a hardcoded string like "foo" instead of $pVersion? If so, it's a different problem. Commented Jul 14, 2021 at 22:48
  • Yes, if I pass the string inline it works. It also works if I pass the variable inline with f'{pVersion}' Commented Jul 14, 2021 at 22:51
  • Maybe you need to prefix your param names with _? From the example here. Commented Jul 14, 2021 at 22:59
  • @user16442705 also not working for me... Commented Jul 14, 2021 at 23:13
  • 1
    I agree, I have opened a bug on Influxdb-client, github.com/influxdata/influxdb-client-python/issues/285 Commented Jul 14, 2021 at 23:33

4 Answers 4

2

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

Sign up to request clarification or add additional context in comments.

Comments

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

Comments

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

2 Comments

Oh, I see that you tried this already @RyanBurch. I'll keep investigating.
Please see the above updates to my question.
0

I suggest you build your query as following:

mydelay = -5
myquery = ('from(bucket: "mybucket")
            |> range(start: {0}s)
            |> filter(fn: (r) => r["_field"] == "myfield")
            |> filt`enter code here`er(fn: (r) => r["lieu"] == "mylieu")'.format(mydelay))

So, everything becomes possible.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.