Command Injection In CopilotForXcode Extension

Here is an overview of a command injection vulnerability in the GitHub CopilotForXcode extension and the original intitni extension from which it was forked:

I was assigned the task of reviewing the high-level functionality of the GitHub CopilotForXcode plugin, as GitHub launched support for the Copilot extension in Xcode, similar to Copilot Chat extension in Visual Studio Code.

Discovery

While reviewing the code, I came across the following code snippet that looked vulnerable if a user can control the reference.filePath input param.

3. Code Snippet https://github.com/intitni/CopilotForXcode/blob/33a785cb7dfce29b7949aed0a94afc1fd99b6719/Core/Sources/ChatGPTChatTab/Chat.swift
Below is the runMethod of Terminal class which uses Swift Process module to execute shell commands. 3. Code Snippet https://github.com/intitni/CopilotForXcode/blob/33a785cb7dfce29b7949aed0a94afc1fd99b6719/Tool/Sources/Terminal/Terminal.swift

This looked vulnerable because there was no logic in place to sanitize or validate the input being passed to the process execution function. I created a sample Swift application and ran the above code snippet to verify. As expected, it was indeed vulnerable. I was able to inject a command successfully.

Exploiting the vulnerabilty

I setup the extension and noticed that the this part of code gets triggered when you interact with the file in the extension chat window.

Now, the only thing left was to build a payload which contains special characters allowed in the file name. After several attempts and some debugging with the help of one of the developers who had the extension set up. I was able to inject the command in the filename.

Steps to Reproduce

  1. Create a file with the following payload

main.swift";cat>xxd -r -p <<< 2f746d702f68657861616161;".swift

3. Code Snippet

  1. The file will be automatically attached to the Xcode chat editor.
  2. Send any message to interact with Copilot.
  3. Click on the referenced file. Command mentioned in the filename will be executed.

3. Code Snippet

I reported this issue to GitHub’s open source security team at opensource-security[@]github.com, as mentioned in their SECURITY.md.
Later, I realized this plugin was forked from the original repository as mentioned in github extension README.md file: https://github.com/intitni/CopilotForXcode

I also reported the issue to the developer of the intitni repository. The maintainer acknowledged the vulnerability and addressed it by passing user input via environment variables in the next release.

Below is the code snippet of the fix 3. Code Snippet

https://github.com/intitni/CopilotForXcode/commit/9340275e615197fd7cd3ee8b2ed992893119b38d

I spent few hours to bypass the fix by manipulating environment variables, but it looks like the Process module is parsing the special characters correctly which prevents any command injection.

GitHub open source team has not responded, and the vulnerability remains present in the latest version of the GitHub fork

Conclusion

It was a typical command injection. I was thinking the ideal fix would be to use Xcode directly instead of passing commands through bash

Feel free to drop any suggestions via my social handles.
Thanks for reading !

Load Comments?