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

Fix security issues in copilot chat app #1090

Closed
wants to merge 26 commits into from

Conversation

DavidParks8
Copy link
Member

Motivation and Context

Description

api key auth was removed because it was not possible to be secure in a user context. Any user was able to operate on any other user's chats. A new auth policy was introduced to validate userIds coming from tokens rather than request bodies.

Contribution Checklist

@DavidParks8 DavidParks8 marked this pull request as ready for review May 19, 2023 02:58
@adrianwyatt adrianwyatt requested a review from glahaye May 19, 2023 15:39
@adrianwyatt adrianwyatt self-assigned this May 19, 2023
@adrianwyatt adrianwyatt added PR: ready for review All feedback addressed, ready for reviews .NET Issue or Pull requests regarding .NET code labels May 19, 2023
/// <param name="ask">Prompt along with its parameters</param>
/// <param name="skillName">Skill in which function to invoke resides</param>
/// <param name="functionName">Name of function to invoke</param>
/// <returns>Results consisting of text generated by invoked function along with the variable in the SK that generated it</returns>
[Authorize]
[Route("skills/{skillName}/functions/{functionName}/invoke")]
[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<AskResult>> InvokeFunctionAsync(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This controller is a generic controller to invoke SK functions. It should not contain any chat related components.

Copy link
Member Author

@DavidParks8 DavidParks8 May 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yet, it must contain the minimum components required to validate that the user is allowed to pass specific context variables. Otherwise, users will be able to invoke skills for chats they do not own. Validation needs to be here as well as within skills as part of a defense in depth strategy.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This controller will not be used for any chat related features. Maybe we need to be explicit about it.

Copy link
Member Author

@DavidParks8 DavidParks8 May 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regardless of what it will be used for in the app, it still allows for remote execution of the chat skill if a bad actor constructs the proper request. This must be guarded against.

When it comes to backend security, the frontend's default usecase is not relevant. What one could do when calling the backend is what matters. We see people take tokens out of browsers and automate attacks against backends all the time.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally agreed! Need further discussion with @adrianwyatt and @hathind-ms

samples/apps/copilot-chat-app/webapi/Models/Ask.cs Outdated Show resolved Hide resolved
samples/apps/copilot-chat-app/webapi/ServiceExtensions.cs Outdated Show resolved Hide resolved
@TaoChenOSU
Copy link
Contributor

Thanks for your PR!!

Just a note for our team, this PR will create a lot of conflicts with the multi-user feature branch. In the multi-user setting, some chat-related authentication logic may need to change from this PR. For example, the data schema for ChatSession will be different in the multi-user setting. We need to talk about which one we want to let in first.

@DavidParks8
Copy link
Member Author

DavidParks8 commented May 20, 2023

@TaoChenOSU, This PR needs to go in first because if it had been filed via MSRC, your team would have been required to drop everything to fix it immediately. Security takes precedence over new features. I chose to instead save your team all that trouble and, with the goahead from @adrianwyatt, implement it.

@adrianwyatt
Copy link
Contributor

@TaoChenOSU, This PR needs to go in first because if it had been filed via MSRC, your team would have been required to drop everything to fix it immediately. Security takes precedence over new features. I chose to instead save your team all that trouble and, with the goahead from @adrianwyatt, implement it.

I am looking at this today and the review will likely bleed into tomorrow. Thank you for your awesome work on this!

@@ -7,33 +7,26 @@ namespace SemanticKernel.Service.Options;
/// <summary>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have two stories here:

  1. A generic service for SK as a service.
  2. A copilot chat that is built on top of the generic service.

We would like the Copilot chat components to be segregated from the generic service code to make it relatively easy for people to remove Copilot chat from the service.

Can we keep the original class and create the new one called ChatAuthenticationOptions within the CopilotChat dir?

Copy link
Member Author

@DavidParks8 DavidParks8 May 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Such segregation is not recommended or encouraged due to the associated risks.

By separating the Copilot chat components from the generic sk service code, it opens up the possibility of invoking any registered skill without proper validation. This could potentially lead to unauthorized access and misuse of the system. Maintaining a cohesive codebase ensures that necessary checks and balances are in place to validate and authorize skill invocations, thus safeguarding the integrity of the system.

Instead of segregating the components, I would suggest focusing on implementing robust security and validation mechanisms within the codebase. This way, you can ensure that only authorized and validated skills can be invoked, mitigating the risk of potential vulnerabilities. It is crucial to prioritize system security and maintain a unified codebase for better control and protection.

If you were to bring this to a security review, I would tell you to delete the sk controller entirely because it is an avenue for remote code execution vulnerabilities. The reason I did not delete it in this PR is because I was attempting to close the riskiest security issue fast and first.

samples/apps/copilot-chat-app/webapi/ServiceExtensions.cs Outdated Show resolved Hide resolved
samples/apps/copilot-chat-app/webapi/ServiceExtensions.cs Outdated Show resolved Hide resolved
/// <param name="ask">Prompt along with its parameters</param>
/// <param name="skillName">Skill in which function to invoke resides</param>
/// <param name="functionName">Name of function to invoke</param>
/// <returns>Results consisting of text generated by invoked function along with the variable in the SK that generated it</returns>
[Authorize]
[Route("skills/{skillName}/functions/{functionName}/invoke")]
[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<AskResult>> InvokeFunctionAsync(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This controller will not be used for any chat related features. Maybe we need to be explicit about it.

@TaoChenOSU
Copy link
Contributor

Is there anything additional I need to perform before launching the web API and the web app besides the current instructions documented in the ReadMe? The web API throws errors when the web app tries to retrieve chat sessions. I have tried both pass through auth and AAD auth.

@adrianwyatt
Copy link
Contributor

Thanks again for the PR and especially outlining the concerns. The team is meeting this week to discuss how to mitigate the issues in line with our near-future planning. We'll be referencing this PR and will send you the plan as an FYI as soon as we have one.

@adrianwyatt adrianwyatt added PR: paused PR temporarily parked and removed PR: ready for review All feedback addressed, ready for reviews labels May 24, 2023
@adrianwyatt
Copy link
Contributor

@DavidParks8 and I had a great real-time conversation and we'll be bringing in these changes piecewise over the next week or two. Closing this one in light of a set of incoming PRs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR: paused PR temporarily parked
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants