Skip to main content

ScriptTag URL may be request controlled

Investigates ScriptTag writes whose source URL may be controlled by untrusted input.

DetailValue
Check IDSCRIPT_TAG_URL_INJECTION
SeverityHigh
How it runsAgent review

app/routes/app.pixel.tsx

import type { ActionFunctionArgs } from "react-router";

import { authenticate } from "../shopify.server";

export const action = async ({ request }: ActionFunctionArgs) => {
const { admin } = await authenticate.admin(request);

const src = String((await request.formData()).get("scriptUrl"));

// A ScriptTag runs on every storefront page view. A
// request-controlled src turns one form post into script
// execution for every visitor.
return admin.graphql(
`#graphql
mutation AddPixel($input: ScriptTagInput!) {
scriptTagCreate(input: $input) { userErrors { message } }
}`,
{ variables: { input: { src, displayScope: "ONLINE_STORE" } } },
);
};

Remove ScriptTag usage or restrict sources to trusted versioned assets.

extensions/storefront-pixel/blocks/pixel.liquid

{% comment %}
Delete the ScriptTag mutation and ship storefront JavaScript as
a theme app extension asset instead. The URL is a versioned
file you control, the merchant can see and remove the block,
and no request input can change what runs.
{% endcomment %}
<script src="{{ 'pixel.js' | asset_url }}" defer></script>

{% schema %}
{ "name": "Analytics pixel", "target": "head" }
{% endschema %}


Was this page helpful?