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

baggage module fails to accept baggage produced by itself #4241

Closed
Lim3nius opened this issue Jun 20, 2023 · 4 comments · Fixed by #4755
Closed

baggage module fails to accept baggage produced by itself #4241

Lim3nius opened this issue Jun 20, 2023 · 4 comments · Fixed by #4755
Assignees
Labels
area:baggage Part of OpenTelemetry baggage bug Something isn't working
Milestone

Comments

@Lim3nius
Copy link

Description

In current implementation (otel@v1.16.0) of baggage propagation and parsing it is possible to pass value into baggage member, which is accepted, then inject given baggage into HeaderCarrier and then extract baggage from HeaderCarrier to find out, that baggage hasn't been successfully parsed.

Steps To Reproduce

Or

  • Try to propagate baggage.NewMember("ok-key", url.QueryEscape("messed,up%key")) through HeaderCarrier

Expected behavior

Parsed baggage contains member with key "ok-key" and value "messed,up%key"

Other issues dealing with same problem

Problem

In baggage.parseMember() value of baggage is first unescaped and then is checked whether it contains "forbidden values" by W3C Baggage wire restriction.

Solution

Most obvious solution to me is to move check that value conforms to W3C Baggage right before unescaping that value, or completely remove that check.

@Lim3nius Lim3nius added the bug Something isn't working label Jun 20, 2023
@Lim3nius
Copy link
Author

@MrAlias could you take a look at this and lets finally resolve this baggage problem? Also addressing more deep problem with OpenTelemetry baggage implementation described here would be nice.

@pellared
Copy link
Member

pellared commented Dec 6, 2023

In current implementation (otel@v1.16.0) of baggage propagation and parsing it is possible to pass value into baggage member, which is accepted, then inject given baggage into HeaderCarrier and then extract baggage from HeaderCarrier to find out, that baggage hasn't been successfully parsed.

On parsing see https://www.w3.org/TR/baggage/#value:

Any characters outside of the baggage-octet range of characters MUST be percent-encoded. Characters which are not required to be percent-encoded MAY be percent-encoded.

Why do you expect hc.Get() to return "unecaped" value? This would be wrong.

The "semantical type" of Parse input and hc.Get() output is different. Bboth are string but they have different formatting. The first expect an "encoded value", the second returns a "decoded value".

I think that the current behavior is OK and conforms with the Baggage Specification.

@pellared pellared added invalid This doesn't seem right question Further information is requested and removed question Further information is requested labels Dec 6, 2023
@Lim3nius
Copy link
Author

@pellared Thanks for your interest in this issue, I'd like to point out, that main problem was demonstrated in lines 24-46, that given baggage was not succefully propagated through http.Header, i.e. no baggage members were found after extract.

The part with Parse is basically to demonstrate what happens in code of Baggage.Extract()

I.e. still there is problem, that I can encode some value which is accepted by baggage, transfer it via http headers and then all baggage is lost during extraction. That part seems completely missed!

Side note: If I double url.QueryEscape baggage on line 26, then baggage is succesfuly parsed...

@pellared
Copy link
Member

pellared commented Dec 12, 2023

@Lim3nius

Sorry, you are correct. I needed more time to understand it.

Most obvious solution to me is to move check that value conforms to W3C Baggage right before unescaping that value

Here you are correct as well.

I will try to make a PR which fixes it on Thursday or Monday next week.

Let me know what do you think of these tests (added to propagation/baggage_test.go):

func TestBaggageInjectExtractRoundtrip(t *testing.T) {
	propagator := propagation.Baggage{}
	tests := []struct {
		name string
		mems members
	}{
		{
			name: "two simple values",
			mems: members{
				{Key: "key1", Value: "val1"},
				{Key: "key2", Value: "val2"},
			},
		},
		{
			name: "values with escaped chars",
			mems: members{
				{Key: "key1", Value: "val3=4"},
				{Key: "key2", Value: "mess,me%up"},
			},
		},
		{
			name: "with properties",
			mems: members{
				{Key: "key1", Value: "val1"},
				{
					Key:   "key2",
					Value: "val2",
					Properties: []property{
						{Key: "prop", Value: "1"},
					},
				},
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			b := tt.mems.Baggage(t)
			req, _ := http.NewRequest("GET", "http://example.com", nil)
			ctx := baggage.ContextWithBaggage(context.Background(), b)
			propagator.Inject(ctx, propagation.HeaderCarrier(req.Header))

			ctx = propagator.Extract(context.Background(), propagation.HeaderCarrier(req.Header))
			got := baggage.FromContext(ctx)

			assert.Equal(t, b, got)
		})
	}
}

If you want you can do the PR yourself then I will review it 😉

@pellared pellared removed the invalid This doesn't seem right label Dec 12, 2023
@pellared pellared self-assigned this Dec 12, 2023
@MrAlias MrAlias added this to the v1.22.0 milestone Jan 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:baggage Part of OpenTelemetry baggage bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants