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

appservice: Fix site files by avoiding kudu redirect #1537

Merged
merged 4 commits into from
Jul 20, 2023

Conversation

alexweininger
Copy link
Member

@alexweininger alexweininger commented Jul 20, 2023

Browsing site files was broken during the migration to Track 2 SDK in #1450. Detailed explanation below.

Related extension issue: microsoft/vscode-azureappservice#2544

Problem

The App Service VFS API endpoints are in the format /api/vfs/${path}?api-version=2022=03-01 where path is a path to a file or folder. If you make a request for a folder, but omit the trailing slash the API will correct this by redirecting the request and adding the slash onto the redirect location.

So /api/vfs/thisIsAFolder?api-version=2022=03-01 will be redirected to /api/vfs/thisIsAFolder/?api-version=2022=03-01 (see the added slash).

Sounds great right? Wrong! The redirection causes a 401 error. We recently migrated to the Track 2 client. The Track 2 client redirection policy purposefully removes the authentication header from the redirected request. This is a security fix and not a bug according to the SDK team.

I haven't checked, but I'm assuming Track 1 client didn't have this security patch so it just worked even with the redirections.

Solution

Technically we could circumvent the default redirect policy, however A. it's a security risk, and B. a lot of work.

Instead, we now form requests to the App Service VFS API such that no redirect is needed. We can do so by ensuring we include or exclude trailing slashes based on if the path points to a folder or file. I also found that we were including an extra leading slash which also resulted in a redirect.

To do this, I refactored how the site files and site file tree items worked. Instead of tracking file paths to make requests, I'm just storing the href property that the API returns which in my testing is always correct. This makes it really easy for us and means I was able to delete some code. I don't know why we didn't use this property originally, maybe it's new.

I tested this extensively in both App Service and Functions extensions. This impacts the Logs feature too which I also tested. Afaik Logs and Files are the only thing these changes impact.

It'd be awesome if we could mock the Kudu APIs or maybe just test against a live App Service resource. I'm super open to brainstorming ways we can refactor this stuff to make it more testable to prevent this sort of bug in the future.

@alexweininger alexweininger requested a review from a team as a code owner July 20, 2023 04:45
bwateratmsft
bwateratmsft previously approved these changes Jul 20, 2023
* @param path - Do not include leading slash. Include trailing slash if path represents a folder.
*/
export function createSiteFilesHref(site: ParsedSite, path: string): string {
return `${site.kuduUrl}/api/vfs/${path}?api-version=2022=03-01`
Copy link
Member

Choose a reason for hiding this comment

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

I'm pretty sure that Kudu doesn't have an api-version. That was my mistake when migrating over Kudu calls (because I was thinking it was an ARM call)

Copy link
Member Author

Choose a reason for hiding this comment

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

Removed it.

@@ -80,7 +82,7 @@ async function getFsResponse(context: IActionContext, site: ParsedSite, filePath
try {
return await client.sendRequest(createPipelineRequest({
method: 'GET',
url: `${site.id}/hostruntime/admin/vfs/${filePath}/?api-version=2022-03-01`
url: href,
Copy link
Member

Choose a reason for hiding this comment

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

Might make sense to just have href be assigned url to match the property.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok, I'm assigning the href property to url when creating the folder/file tree items. So now it's known as url everywhere.

@nturinski
Copy link
Member

I tested this extensively in both App Service and Functions extensions. This impacts the Logs feature too which I also tested. Afaik Logs and Files are the only thing these changes impact.

This should be correct.

Copy link
Member

@nturinski nturinski left a comment

Choose a reason for hiding this comment

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

🤩

try {
if (site.isFunctionApp) {
const linuxHome: string = '/home';
if (site.isLinux && !filePath.startsWith(linuxHome)) {
Copy link
Member

Choose a reason for hiding this comment

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

Oh yeah, are you still considering this special case?

Copy link
Member Author

Choose a reason for hiding this comment

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

We aren't using the path anymore so this isn't needed. I'm assuming the href returned by the API is always correct. Do you know how to test this case?

Copy link
Member Author

Choose a reason for hiding this comment

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

I verified it works with a Linux Function App. Not sure how else to test it.

Copy link
Member

Choose a reason for hiding this comment

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

That works for me. I honestly don't remember the full context of why we had this in the first place.

@alexweininger alexweininger merged commit c274510 into main Jul 20, 2023
4 checks passed
@alexweininger alexweininger deleted the alex/aqua-mosquito branch July 20, 2023 17:06
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 this pull request may close these issues.

3 participants