---
title: Unsafe Liquid metafield or setting output
description: >-
  Detects metafield and merchant-setting output without context-appropriate
  escaping or serialization.
source_url:
  html: >-
    https://shopify.dev/docs/apps/build/security/app-security-checks/liquid-unsafe-render
  md: >-
    https://shopify.dev/docs/apps/build/security/app-security-checks/liquid-unsafe-render.md
---

# Unsafe Liquid metafield or setting output

Detects metafield and merchant-setting output without context-appropriate escaping or serialization.

| Detail | Value |
| - | - |
| Check ID | `LIQUID_UNSAFE_RENDER` |
| Severity | Medium |
| How it runs | Deterministic scan and agent review |
| Applies to | Apps with a theme app extension |

***

## Vulnerable example

## extensions/promo-banner/blocks/banner.liquid

```liquid
{% comment %}
  Merchant setting rendered straight into markup.
{% endcomment %}
<div title="{{ block.settings.title }}">{{ block.settings.title }}</div>


{% comment %}
  And into a script, where it becomes executable.
{% endcomment %}
<script>
  const config = {{ product.metafields.app.config }};
</script>
```

***

## How to fix

Use `escape` for HTML text and attributes, `json` for JavaScript data, or `metafield_tag` for supported rich content.

## extensions/promo-banner/blocks/banner.liquid

```liquid
{% comment %} escape for HTML text and attributes. {% endcomment %}
<div title="{{ block.settings.title | escape }}">
  {{ block.settings.title | escape }}
</div>


{% comment %}
  json for anything crossing into JavaScript.
{% endcomment %}
<script>
  const config = {{ product.metafields.app.config.value | json }};
</script>
```

***

## Related

* [`shopify app security check`](https://shopify.dev/docs/api/shopify-cli/app/app-security-check), the command that runs this check
* [All app security checks](https://shopify.dev/docs/apps/build/security/app-security-checks)

***
