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

Plugins: Only set non-existing headers for core plugin requests #78633

Merged
merged 2 commits into from
Nov 30, 2023

Conversation

aangelisc
Copy link
Contributor

Fixes #78629

When a plugin request has headers that have been set by some logic in the plugin or some other middleware this change prevents the HTTPClient middleware from overwriting those headers. This is the same logic as that which already exists in the plugin-sdk.

- Add test scenario
@aangelisc aangelisc added this to the 10.3.x milestone Nov 24, 2023
@aangelisc aangelisc requested a review from a team as a code owner November 24, 2023 10:54
@aangelisc aangelisc self-assigned this Nov 24, 2023
@aangelisc aangelisc requested review from wbrowne and xnyo and removed request for a team November 24, 2023 10:54
Copy link
Contributor

@andresmgot andresmgot left a comment

Choose a reason for hiding this comment

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

LGTM, makes sense.

Copy link
Member

@wbrowne wbrowne left a comment

Choose a reason for hiding this comment

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

Please make sure to document this as a breaking change 🙏

@andresmgot
Copy link
Contributor

andresmgot commented Nov 24, 2023

Please make sure to document this as a breaking change 🙏

Can this be considered a breaking change? I would say it's more of a bug fix.

@wbrowne
Copy link
Member

wbrowne commented Nov 24, 2023

Please make sure to document this as a breaking change 🙏

Can this be considered a breaking change? I would say it's more of a bug fix.

Hmmm.. I guess depending on how you look at it, but not sure if someone could be tripped up by this as result and it'd be better to have notice like this to point to. I would say it's safer to add this, but I'd defer to @marefr as he has the most context here.

@marefr
Copy link
Member

marefr commented Nov 29, 2023

@aangelisc can you provide an example of headers causing problems for you? Might be security concerns to allow the client (end user) to override certain headers

@aangelisc
Copy link
Contributor Author

@marefr the Azure auth middleware sets the Authorization header. When attempting to do user-based authentication the access token sent in the plugin request will be exchanged for another access token with the appropriate permissions. This middleware will then overwrite the new token with the original one which does not have the required permissions.

Afaict, the plugin-sdk middleware will not overwrite a header if it has a non-empty value which is what I'd expect to happen in core as well.

@marefr
Copy link
Member

marefr commented Nov 30, 2023

@marefr the Azure auth middleware sets the Authorization header. When attempting to do user-based authentication the access token sent in the plugin request will be exchanged for another access token with the appropriate permissions. This middleware will then overwrite the new token with the original one which does not have the required permissions.

Afaict, the plugin-sdk middleware will not overwrite a header if it has a non-empty value which is what I'd expect to happen in core as well.

@aangelisc thanks. Since only Authorization header I would perhaps suggest to only add this logic for this specific header. I'm a bit concerned with security and at the same time have a hard time to see everything that this potentially could affect. But a general example I think about is that the client/user could include HTTP headers that with your logic they'll be sent to the plugin rather than being overwritten by Grafana's internal middlewares.

Your main problem is that your Azure HTTP client middleware is executed after the ContextualMiddleware. Rather than appending your middleware here https://github.com/grafana/grafana-azure-sdk-go/blob/b20aac068928f54c7c89e32ef07b517d9cec8750/azhttpclient/options.go#L26 you might be able to use the clientOpts.ConfigureMiddleware function to insert the azure middleware before the contextual middleware. Something along these lines:

opts.ConfigureMiddleware = func(opts Options, existingMiddleware []Middleware) []Middleware {
	mws := []httpclient.Middleware{}
        inserted := false
	for _, mw := range existingMiddleware {
		if name, ok := mw.(httpclient.MiddlewareName); ok && name.MiddlewareName() ==httpclient.ContextualMiddlewareName {
			mws = append(mws, <azure middleware>
			inserted = true
		}
		mws = append(mws, mw)
	}

	if !inserted {
		mws = append(mws, <azure middleware>
	}
}

Update:
Sorry I thought about this the wrong way. Please disregard my comment above. I'll leave it for completeness. A bit confusing and easy to get tricked with the contextual middleware which is for HTTP headers in outgoing HTTP requests and not plugin request. In addition the HTTP requests are created from each plugin so the plugin author should be able to set HTTP headers without them being overwritten I think. Noticed we do have similar logic for user agent and basic authentication middlewares.

I'll go ahead and approve this.

Copy link
Member

@marefr marefr left a comment

Choose a reason for hiding this comment

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

LGTM and agree bugfix and not breaking and should only affect core plugins (I believe)

@aangelisc
Copy link
Contributor Author

Thanks for the review comments all @andresmgot @wbrowne @marefr!

@aangelisc aangelisc merged commit f26ad88 into main Nov 30, 2023
14 checks passed
@aangelisc aangelisc deleted the andreas/fix-plugin-headers branch November 30, 2023 11:51
@aangelisc aangelisc modified the milestones: 10.3.x, 10.2.3 Dec 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Plugins: New headers being overwritten by initial request headers
4 participants