GrafanaJsonDatasource icon indicating copy to clipboard operation
GrafanaJsonDatasource copied to clipboard

Escaping variables to prevent JSON format errors

Open pepaba opened this issue 5 months ago • 7 comments
trafficstars

When using text variables in dashboard queries (e.g. ${filter}), users may enter special characters like \ or ". These result in invalid JSON and an empty one is sent to the backend, breaking the query.

Since Grafana doesn't automatically escape these values, users have to escape characters manually, which is error-prone and not user-friendly.

Suggestion: Could the plugin automatically apply JSON string escaping to interpolated variable values, or provide an option to sanitize input?

This would make the plugin more robust and reduce friction for dashboard users.

Thanks for the great tool!

pepaba avatar Jun 09 '25 06:06 pepaba

Can you try with latest https://github.com/simPod/GrafanaJsonDatasource 0.7.x branch?

simPod avatar Jun 16 '25 08:06 simPod

Thank you for your reply, I'm ready to try it. However, I don't have a dev/test environment and have no experience in this area. I've already googled grafana and plugin versions topic and this is the level from which I can start testing

pepaba avatar Jun 17 '25 09:06 pepaba

You can just checkout this repo into the grafana plugin folder and run yarn yarn run build commands.

simPod avatar Jun 17 '25 10:06 simPod

Thanks for hint, I try this:

  1. install grafana into /opt/grafana-v12.0.1
  2. use grafana web gui to install JSON Datasource (0.6.7, May 20, 2025)
  3. create a dashboard with a Textbox variable raw_filter and a Table widget
  4. use json query: {"range":["${__from:date:seconds}","${__to:date:seconds}"],"raw_filter":"${raw_filter}"}
  5. everything works fine until I enter " without escaping into the raw_filter field

and the version 0.7.x step by step:

  1. adjust /opt/grafana-v12.0.1/conf/defaults.ini (allow_loading_unsigned_plugins = simpod-json-datasource)
  2. start grafana
  3. uninstall JSON Datasource
  4. stop grafana
  5. remove /opt/grafana-v12.0.1/data/plugins/simpod-json-datasource
  6. cd /opt/grafana-v12.0.1/data/plugins
  7. git clone https://github.com/simPod/GrafanaJsonDatasource.git
  8. cd GrafanaJsonDatasource/.yarn/releases
  9. ./yarn-4.9.2.cjs and /yarn-4.9.2.cjs run build
  10. start grafana and try the dashboard

The behaviour related to " remains the same, I'm ready for further testing

pepaba avatar Jun 18 '25 08:06 pepaba

Maybe try:

"raw_filter":${raw_filter}

or "raw_filter":"${raw_filter:doublequote}" but I'm guessing a bit now

simPod avatar Jun 18 '25 09:06 simPod

I've already tried https://grafana.com/docs/grafana/latest/dashboards/variables/variable-syntax/ (includes what you mentioned) but without success

pepaba avatar Jun 18 '25 09:06 pepaba

from https://grafana.com/docs/grafana/latest/dashboards/variables/variable-syntax/ :

...Before queries are sent to your data source the query is interpolated, meaning the variable is replaced with its current value. During interpolation, the variable value might be escaped in order to conform to the syntax of the query language and where it is used. For example, a variable used in a regex expression in an InfluxDB or Prometheus query will be regex escaped. Read the data source specific documentation topic for details on value escaping during interpolation...

pepaba avatar Jun 18 '25 09:06 pepaba

Currently I'm on "vacations" for 2M and have no time for OSS. I'll be able to take a look in August possibly.

simPod avatar Jul 01 '25 16:07 simPod

Thanks for the info and enjoy. When you get back, I'll be ready to testing again.

pepaba avatar Jul 02 '25 08:07 pepaba

Now I see. You're talking about the payload in the panel.

The variables sent in scopedVars are escaped. That's because we can process each variable individually.

However, when we define json payload with the query in panel, we pass the whole json string to grafana to replace the variables within. And AFAIK there's no way to do it with native TemplateService https://github.com/grafana/grafana/blob/4b217c601a148dd0a27d96f4bb8b980e54856874/public/app/features/templating/template_srv.ts#L263 (I'd not want to write custom one at this time).

What you can do it to use Builder mode where each variable is processed independently as well.

simPod avatar Jul 17 '25 12:07 simPod

I've been also facing this issue, and I think I've found the root cause: cleanMatch of DataSource checks if the interpolated value starts and ends with quotation marks, and then tries to parse it as JSON if so.

Src code link: https://github.com/simPod/GrafanaJsonDatasource/blob/3648aebae3e13946afcd36911bc8218e94100163/src/DataSource.ts#L287

This means that if the variable format option chosen is surrounded by quotes, the string will get parsed as JSON, and any escaping will get lost when the JSON gets converted back to a string. For example, a minimal reproduction:

Variable tags with value foo="bar" Query payload in "code" mode: { "tags": ${tags:doublequote} } This results in an empty payload.

It seems like the value computed here https://github.com/simPod/GrafanaJsonDatasource/blob/3648aebae3e13946afcd36911bc8218e94100163/src/DataSource.ts#L239 is handing an invalid value ({ "tags": foo="bar" }) to the JSON.parse, because the TemplateService replaces ${tags:doublequote} with "foo=\"bar\"", but then cleanMatch parses this as JSON and gets rid of all the escaping, eventually passing back foo="bar" to replace the template.

When I simply remove the branch of cleanMatch that checks for quotation marks, the query parsing just works as expected.

I have no idea why this check is here, to begin with; my best guess is that it maybe originally had something to do with not wanting to have values of the shape $tag be escaped by double quotes, since I think things are in format JSON by default? https://github.com/simPod/GrafanaJsonDatasource/blob/3648aebae3e13946afcd36911bc8218e94100163/src/DataSource.ts#L286 But for single value variables, the json format does not even surround them with quotation marks or escape quotation marks in the value (and for multiple values, the json format starts and ends with brackets), so if this why, this doesn't really make sense.

I really cannot come with any use case where it would intended behavior to parse interpolated values as JSON just because they are surrounded by quotes. I think the if branch in cleanMatch should just be removed?

aytao avatar Aug 04 '25 20:08 aytao

@aytao thank you for investigation.

PR would be welcome

I really cannot come with any use case where it would intended behavior to parse interpolated values as JSON just because they are surrounded by quotes. I think the if branch in cleanMatch should just be removed?

There are not many tests yet. If it does not break any, I'm for removing the branch.

I'm still kinda vacationing, had not much time to look into it again

simPod avatar Sep 04 '25 05:09 simPod

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

github-actions[bot] avatar Oct 05 '25 02:10 github-actions[bot]

This issue has not seen any activity since it was marked stale. Closing.

github-actions[bot] avatar Oct 13 '25 02:10 github-actions[bot]