Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Security concerns #1026

Closed
duckdoom4 opened this issue Feb 13, 2023 · 31 comments
Closed

Security concerns #1026

duckdoom4 opened this issue Feb 13, 2023 · 31 comments

Comments

@duckdoom4
Copy link

duckdoom4 commented Feb 13, 2023

I have some concerns about the way some of this code is implemented.

To name the two I've noticed so far, the llm_math and sql_database chains.

It seems these two will blindly execute any code that is fed to it from the llm

This is a major security risk, since this opens anyone who uses these up for remote code execution. (The python one more then the sql one).

With a mitm attack, anyone can just return back a piece of code in the reply, pretending it is the bot. And if that's not enough, with some well crafted prompt, you can probably make it execute code as well (by making the llm return text with the same prompt pattern but custom python code)

I understand that this is in very early beta, but I've already seen this used in different places, due to ChatGPT's popularity.

In any case, it might be beneficial to switch from exec() to eval() for the python calculator, since eval() is build for the purpose of evaluating math expressions.

@duckdoom4
Copy link
Author

duckdoom4 commented Feb 13, 2023

https://blog.finxter.com/python-exec/
This should give a general idea of how the exec function can be abused

@phr33b4d
Copy link

phr33b4d commented Feb 14, 2023 via email

@kjannette
Copy link

@duckdoom4 @hwchase17 please see hwchase17/adversarial-prompts#7 (referenced in post immediately above). There is a serious underlying vulnerability here: both in the models themselves and in add-on frameworks (i.e. Langchain) that open up another attack vector.

Containerization via Docker is a good start, for those willing and able to use it. See #1031

But it fails to address the underlying vulnerability. Also, Docker escapes are very possible, so that is at beast a band-aid. See https://attackdefense.pentesteracademy.com/listingnoauth?labtype=container-security-container-host-security&subtype=container-security-container-host-security-breakouts.

@blob42
Copy link
Contributor

blob42 commented Feb 14, 2023

@kjannette I am putting together in #1031 the band-aid solution using a non priviliged docker user. I will follow up with a proposal update to the repls, bash and sql chains so they can execute in the container context when docker is setup.

I agree that the security risks are a big concern. My use of langchain will require heavy usage of shell contexts which I had to postpone until there is some minimal isolation.

Right now anyone pulling the repo and using the Repl/Shell/Sql chains is running arbitrary and potentially malicious code without any disclaimer.

May be adding a warning message that can be turned off by users so at least they are aware of the risks ?

@brandco
Copy link

brandco commented Feb 16, 2023

Would running tools in docker containers solve some of the security issues?
It would be pretty easy to make a template out of a command like this
docker run --name python_langchain -it --rm python python -c "print({python_expression_to_be_evaluated})"

A docker tool might be a nice addition to langchain for other use cases as well.

@duckdoom4
Copy link
Author

duckdoom4 commented Feb 16, 2023

Would running tools in docker containers solve some of the security issues?
It would be pretty easy to make a template out of a command like this
docker run --name python_langchain -it --rm python python -c "print({python_expression_to_be_evaluated})"

A docker tool might be a nice addition to langchain for other use cases as well.

Well, it might help. But I don't think it's going to solve the core problem. Which is that {python_expression_to_be_evaluated} could contain unsafe code/ code with mal intent.

For example; Imagine someone supplying the following python code: )\nevil_python_function() or even worse, if the command line string is not sanitized: )"&[sys cmd to run]

As mentioned before, simply swapping from exec() to eval() would already help a great deal (But eval is still dangerous), tho depending on the final intentions might be too limiting.

Another option is having some tool that sanitizes the allowed python code with eg. regex patterns

@duckdoom4
Copy link
Author

duckdoom4 commented Feb 16, 2023

There are plenty of useful sources online on how to do it safely and what to look out for. Here are some examples:

https://stackoverflow.com/questions/10661079/restricting-pythons-syntax-to-execute-user-code-safely-is-this-a-safe-approach

PyPy sandbox (I recommend using this):
https://doc.pypy.org/en/latest/sandbox.html

Example of how difficult this problem is:
https://softwareengineering.stackexchange.com/questions/191623/best-practices-for-execution-of-untrusted-code/191628#191628

@blob42
Copy link
Contributor

blob42 commented Feb 16, 2023

Quick update on the docker PR #1055 . I made a fully isolate container with no elevated privileges. The dependencies and the langchain package are all compiled in the image.

I avoided the virtualenv (poetry, pyenv, venv .. ) used a minimal python based image. When changed is detected only the the main package is installed.

Would be great to have some testers / feedback.

@duckdoom4
Copy link
Author

@blob42 Check out PyPy's sandbox. This seems like a very well implemented sandboxing environment. Having that running in a docker container and we're basically as safe as can be. https://doc.pypy.org/en/latest/sandbox.html

@blob42
Copy link
Contributor

blob42 commented Feb 16, 2023

@duckdoom4 thanks I will read about it and see how to integrate in the
container. I was thinking to have two separate images, one that can be
used for dev/testing with live reload (bind mount) and an other one especially crafted for agents.

@blob42
Copy link
Contributor

blob42 commented Feb 18, 2023

I took a look to the sandboxlib project. I think should be feasible to use it for the Agent's container. However I noticed that there was no activity on the project since 3 years, the project's repo is here

There are other options that can be considered for running untrusted code. Here is a summary of what can be done on the sandboxing topic:

  • Using a virtualized runtime for docker like gVisor
    Pros: Almost same sandboxing as full virtualization
    Cons: Performance ?

  • Drop all capabilities from container see

  • For Python: Use sandboxlib

  • Update the exec family of Agent tools and allow execution on a remote shell (like ssh) . Users can redirect the shell to a full virtual machine (kvm, xen ... )

@duckdoom4
Copy link
Author

duckdoom4 commented Feb 18, 2023

I took a look to the sandboxlib project. I think should be feasible to use it for the Agent's container. However I noticed that there was no activity on the project since 3 years, the project's repo is here

There are other options that can be considered for running untrusted code. Here is a summary of what can be done on the sandboxing topic:

  • Using a virtualized runtime for docker like gVisor
    Pros: Almost same sandboxing as full virtualization
    Cons: Performance ?

  • Drop all capabilities from container see

  • For Python: Use sandboxlib

  • Update the exec family of Agent tools and allow execution on a remote shell (like ssh) . Users can redirect the shell to a full virtual machine (kvm, xen ... )

Ah yes, you clicked to link to the old repo. This one is up to date :): https://foss.heptapod.net/pypy/pypy

If you look at the 'how to' section on the page I mentioned, they posted that you should download from that link.

Tho RestrictedPython like used in #1134 might also be good enough

All the other things you mentioned also sound like a great idea 👍🏼

@kjannette
Copy link

kjannette commented Feb 18, 2023 via email

@bborn
Copy link
Contributor

bborn commented Feb 26, 2023

I have a PR related to this that uses RestrictedPython (https://restrictedpython.readthedocs.io/):

#1134

Would love to get this (or something similar) merged.

@blob42
Copy link
Contributor

blob42 commented Mar 3, 2023

I made some progress in #1266 . It is now possible to run arbitrary commands to any image or attach to existing containers. If gVisor is installed it will be automatically used. Check out the notebook for a few examples.

@bborn is there an official docker image for restrictedpython or something similar ? Is there a way to call the python process with a sane default sandbox environment with a simple command ? I could then make an image template (see docker/images.py) to use it by default.

@bborn
Copy link
Contributor

bborn commented Mar 4, 2023

@blob42 I'm not aware of anything like that. But yes, I think RestrictedPython is a good framework for setting up a sane sandbox with limited modules/functions.

Much of this is kind of out of my league (I'm just learning Python), but there is a lot that could be taken from here:

https://github.com/zopefoundation/AccessControl/tree/master/src/AccessControl

@manziman
Copy link

Been looking for a way to contribute now that I am using this awesome framework and I stumbled upon this thread.

Maybe someone has already addressed this - though I don't think I saw this suggested yet - but would os.chroot be a good (partial) mitigation for the code execution attack vector?

The concern I have with using Docker as the only option is that it limits the use of this particular tool to platforms to execution environments where you have access to Docker. For instance, if I wanted to run this in AWS Lambda or some other FaaS environment, docker isn't an option whereas chroot might be.

More generally, the best mitigation to this attack vector is to put in place defenses against MitM attacks more generally, which seems like something out of the scope of this framework, no?

Hoping there's somewhere I can contribute here.

@blob42
Copy link
Contributor

blob42 commented Mar 14, 2023

@manziman I have been working on the docker API integration. Like you mentioned it is a very specific need so maybe it does not make sense to include it in langchain. I will post a link to the library when it's ready.

@manziman
Copy link

manziman commented Mar 16, 2023

I have been hacking on this a little more in a related project. Needless to say, as many here probably already know, running untrusted code in python is practically speaking not possible without using something like docker or jails, which will complicate things. I am messing around with RestrictedPython but I can't really get it to work for my purposes.

Maybe a better approach would be using a domain specific language to serve the same purpose as the Python REPL util? Something like TextX? I've never used it before, maybe there's a better option as far as DSLs or metalanguages go for Python.

@bborn
Copy link
Contributor

bborn commented Mar 16, 2023

@manziman what issues are you having with RestrictedPython? I'm using it in my app and seems fine (granted I haven't tried to hard to break/test it). Here's what I'm doing:

https://gist.github.com/bborn/4c6e769e74f3d6397452bec3c9f294e6

@manziman
Copy link

@bborn

I am working on a way to abstract langchain behind an API, and store langchain objects in a SQL database. The idea is to have a deployable platform on which to run chains, using an API to allow other services to interact with those chains via API calls.

This works pretty well for standard chains, and sequential chains, as those can be represented pretty easily in JSON. Where things start to break down is in the Transform chains, as it requires you to pass in an actual python function.

So I was trying to see if I could allow the API caller to provide a string of python code which could be compiled to bytecode server-side for later execution (in a "secure" way).

@bborn
Copy link
Contributor

bborn commented Mar 16, 2023

@manziman me too! I've been building https://agent-hq.io - which sounds pretty similar. AgentHQ has a 'Custom' tool that lets users write python functions that can call the LLM and be used in Agents, but I use Restricted Python to try to avoid people rm -rfing my server. I know a fully isolated runtime (e.g. Docker or some serverless thing) is better, but this seems ok for now.

@manziman
Copy link

Very cool!

At this point for my use case I think I am going to solve the problem by allowing the user to provide a 'transform URL', which should be an external service serving POST requests containing the arguments to the function. That way you can host the 'transform logic' somewhere else and avoid running untrusted code in the main execution environment altogether.

The more I've been working on this the more I'm starting to think that storing functions as raw code or bytecode server side is asking for problems anyway, security considerations aside.

@mathetake
Copy link

mathetake commented Mar 20, 2023

Hi there from Wasm community, has anyone considered using Wasm as a sandboxed execution env for python repl? You can think of it as an isolated OS kernel in the userland (extremely lightweight) vs Docker containers sharing kernels with the host for example. See https://til.simonwillison.net/webassembly/python-in-a-wasm-sandbox for reference.

Let me know if it helps, and I would be more than happy to craft patches. Thanks!

@jcchavezs
Copy link

There is a similar concern in Coreruleset by running user scripts in the host (see https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v3.x%29#user-content-exec) that we are most likely tackling in @corazawaf by using WASM.

@duckdoom4
Copy link
Author

Hi there from Wasm community, has anyone considered using Wasm as a sandboxed execution env for python repl? You can think of it as an isolated OS kernel in the userland (extremely lightweight) vs Docker containers sharing kernels with the host for example. See https://til.simonwillison.net/webassembly/python-in-a-wasm-sandbox for reference.

Let me know if it helps, and I would be more than happy to craft patches. Thanks!

This seems like an awesome solution and something that can be implemented to work out of the box. That's great for the average user that needs to be protected, but doesn't need the extra protection a docker environment would provide.

@Jflick58
Copy link
Contributor

Jflick58 commented May 27, 2023

@hwchase17 @dev2049 I’m planning on tackling a wasm compilation and execution solution to replace exec. For extra security, it may be worth dynamically scanning generated code and throwing errors if major vulnerabilities are flagged. At the least, it seems straightforward to me to replace exec() with wasm. I’m just checking that there’s no other work in flight on this. FYI #5294

@timxieICN
Copy link

Hi guys - any update on security improvement? Perhaps wasm compilation per #1026 (comment)

@aiakubovich
Copy link

any updates?

@ssutharzan
Copy link

ssutharzan commented Jul 18, 2023

Hi All, Does making a custom version of LangChain by removing code execution part break other functionalities of LangChain or create some other issues? I am thinking of using LangChain this way for now to minimixe code execution vulnerabilities. LangChain is well modularized and could be possible map the inter-code dependencies to customize and install only the needed parts per usecase to be extra safe and easy to review. In this way more mature/safe parts of LangChain can be started to be used in production systems.

@dosubot
Copy link

dosubot bot commented Oct 18, 2023

Hi, @duckdoom4! I'm Dosu, and I'm helping the LangChain team manage their backlog. I wanted to let you know that we are marking this issue as stale.

From what I understand, you raised a concern about security issues with the llm_math and sql_database chains in the code. The suggestion was made to switch from exec() to eval() for the python calculator to mitigate this risk. There have been discussions about potential solutions such as using Docker containers, sandboxing with PyPy, RestrictedPython, and Wasm. Additionally, a pull request related to using RestrictedPython has been made.

Before we close this issue, we wanted to check if it is still relevant to the latest version of the LangChain repository. If it is, please let us know by commenting on the issue. Otherwise, feel free to close the issue yourself or it will be automatically closed in 7 days.

Thank you for your contribution and please don't hesitate to reach out if you have any further questions or concerns!

@dosubot dosubot bot added the stale Issue has not had recent activity or appears to be solved. Stale issues will be automatically closed label Oct 18, 2023
@dosubot dosubot bot closed this as not planned Won't fix, can't repro, duplicate, stale Oct 25, 2023
@dosubot dosubot bot removed the stale Issue has not had recent activity or appears to be solved. Stale issues will be automatically closed label Oct 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.