VYPR
Medium severity5.3OSV Advisory· Published Jun 10, 2024· Updated Apr 15, 2026

CVE-2024-37169

CVE-2024-37169

Description

@jmondi/url-to-png is a self-hosted URL to PNG utility. Versions prior to 2.0.3 are vulnerable to arbitrary file read if a threat actor uses the Playright's screenshot feature to exploit the file wrapper. Version 2.0.3 mitigates this issue by requiring input URLs to be of protocol http or https. No known workarounds are available aside from upgrading.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
@jmondi/url-to-pngnpm
< 2.0.32.0.3

Affected products

1

Patches

2
9336020c5e60

fix(security): require screenshot protocol to be http/https

https://github.com/jasonraimondi/url-to-pngJason RaimondiJun 4, 2024via ghsa
3 files changed · +38 3
  • src/lib/schema.ts+17 2 modified
    @@ -7,10 +7,25 @@ const zodStringBool = z
       .transform(x => x === "true")
       .pipe(z.boolean());
     
    -const zodStringUrl = z.string().url();
    +const urlSchema = z
    +  .string()
    +  .url()
    +  .refine(
    +    val => {
    +      try {
    +        const url = new URL(val);
    +        return url.protocol === "http:" || url.protocol === "https:";
    +      } catch (err) {
    +        return false;
    +      }
    +    },
    +    {
    +      message: "must start with http or https",
    +    },
    +  );
     
     export const PlainConfigSchema = z.object({
    -  url: zodStringUrl,
    +  url: urlSchema,
       width: z.coerce.number().nullish(),
       height: z.coerce.number().nullish(),
       viewPortWidth: z.coerce.number().nullish(),
    
  • src/middlewares/extract_query_params.ts+9 1 modified
    @@ -33,7 +33,15 @@ export function handleExtractQueryParamsMiddleware(encryptionService?: StringEnc
         const { validData, errors } = parseForm({ data: input, schema: PlainConfigSchema });
     
         if (errors) {
    -      throw new HTTPException(400, { message: "Invalid query parameters", cause: errors });
    +      let message: string = "Invalid query parameters: ";
    +
    +      const specificErrors = Object.entries(errors).map(([key, value]) => `(${key} - ${value})`).join(" ")
    +
    +      message = `${message} ${specificErrors}`;
    +
    +      console.log(message);
    +
    +      throw new HTTPException(400, { message, cause: errors });
         }
     
         if (validData.width && validData.width > 1920) {
    
  • tests/app.spec.ts+12 0 modified
    @@ -71,6 +71,18 @@ suite("app", () => {
           expect(res.status).toBe(400);
           expect(await res.text()).toMatch(/Invalid query/gi);
         });
    +
    +    [
    +      "file:///etc/passwd&width=4000",
    +      "view-source:file:///home/&width=4000",
    +      "view-source:file:///home/ec2-user/url-to-png/.env",
    +    ].forEach(invalidDomain => {
    +      it(`throws when invalid protocol ${invalidDomain}`, async () => {
    +        const res = await app.request(`/?url=${invalidDomain}`);
    +        expect(res.status).toBe(400);
    +        expect(await res.text()).toMatch(/url - must start with http or https/gi);
    +      });
    +    });
       });
     
       describe("GET /?hash=", () => {
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.