Skip to content

client: define a "dummy" hostname to use for local connections#45942

Merged
thaJeztah merged 4 commits intomoby:masterfrom
thaJeztah:fix_host_header
Jul 14, 2023
Merged

client: define a "dummy" hostname to use for local connections#45942
thaJeztah merged 4 commits intomoby:masterfrom
thaJeztah:fix_host_header

Conversation

@thaJeztah
Copy link
Copy Markdown
Member

For local communications (npipe://, unix://), the hostname is not used, but we need valid and meaningful hostname.

The current code used the client's addr as hostname in some cases, which could contain the path for the unix-socket (/var/run/docker.sock), which gets rejected by go1.20.6 and go1.19.11 because of a security fix for CVE-2023-29406 , which was implemented in https://go.dev/issue/60374.

Prior versions go Go would clean the host header, and strip slashes in the process, but go1.20.6 and go1.19.11 no longer do, and reject the host header.

This patch introduces a DummyHost const, and uses this dummy host for cases where we don't need an actual hostname.

Before this patch (using go1.20.6):

make GO_VERSION=1.20.6 TEST_FILTER=TestAttach test-integration
=== RUN   TestAttachWithTTY
    attach_test.go:46: assertion failed: error is not nil: http: invalid Host header
--- FAIL: TestAttachWithTTY (0.11s)
=== RUN   TestAttachWithoutTTy
    attach_test.go:46: assertion failed: error is not nil: http: invalid Host header
--- FAIL: TestAttachWithoutTTy (0.02s)
FAIL

With this patch applied:

make GO_VERSION=1.20.6 TEST_FILTER=TestAttach test-integration
INFO: Testing against a local daemon
=== RUN   TestAttachWithTTY
--- PASS: TestAttachWithTTY (0.12s)
=== RUN   TestAttachWithoutTTy
--- PASS: TestAttachWithoutTTy (0.02s)
PASS

- What I did

- How I did it

- How to verify it

- Description for the changelog

- A picture of a cute animal (not mandatory but encouraged)

@thaJeztah
Copy link
Copy Markdown
Member Author

I also opened #45943 to verify the combination of this patch with go1.20.6.

@thaJeztah
Copy link
Copy Markdown
Member Author

Ah, looks like I overlooked a test;

=== FAIL: client TestSetHostHeader (0.00s)
    request_test.go:79: assertion failed: error is not nil: error during connect: Get "//%2Fvar%2Frun%2Fdocker.sock/test": Test Case #0: Expected host "docker", got "api.moby.localhost"

@thaJeztah
Copy link
Copy Markdown
Member Author

Looks like we need more code updated;

[2023-07-12T12:54:46.838Z] === Failed
[2023-07-12T12:54:46.838Z] === FAIL: pkg/authorization TestAuthZRequestPluginError (15.01s)
[2023-07-12T12:54:46.838Z] time="2023-07-12T12:53:30Z" level=warning msg="Unable to connect to plugin: //tmp/authz4264769183/authz-test-plugin.sock/AuthZPlugin.AuthZReq: Post \"http://%2F%2Ftmp%2Fauthz4264769183%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZReq\": http: invalid Host header, retrying in 1s"
[2023-07-12T12:54:46.838Z] time="2023-07-12T12:53:31Z" level=warning msg="Unable to connect to plugin: //tmp/authz4264769183/authz-test-plugin.sock/AuthZPlugin.AuthZReq: Post \"http://%2F%2Ftmp%2Fauthz4264769183%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZReq\": http: invalid Host header, retrying in 2s"
[2023-07-12T12:54:46.838Z] time="2023-07-12T12:53:33Z" level=warning msg="Unable to connect to plugin: //tmp/authz4264769183/authz-test-plugin.sock/AuthZPlugin.AuthZReq: Post \"http://%2F%2Ftmp%2Fauthz4264769183%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZReq\": http: invalid Host header, retrying in 4s"
[2023-07-12T12:54:46.838Z] time="2023-07-12T12:53:37Z" level=warning msg="Unable to connect to plugin: //tmp/authz4264769183/authz-test-plugin.sock/AuthZPlugin.AuthZReq: Post \"http://%2F%2Ftmp%2Fauthz4264769183%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZReq\": http: invalid Host header, retrying in 8s"
[2023-07-12T12:54:46.838Z]     authz_unix_test.go:50: Failed to authorize request Post "http://%2F%2Ftmp%2Fauthz4264769183%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZReq": http: invalid Host header
[2023-07-12T12:54:46.838Z] 
[2023-07-12T12:54:46.838Z] === FAIL: pkg/authorization TestAuthZRequestPlugin (15.01s)
[2023-07-12T12:54:46.838Z] time="2023-07-12T12:53:45Z" level=warning msg="Unable to connect to plugin: //tmp/authz2422457390/authz-test-plugin.sock/AuthZPlugin.AuthZReq: Post \"http://%2F%2Ftmp%2Fauthz2422457390%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZReq\": http: invalid Host header, retrying in 1s"
[2023-07-12T12:54:46.838Z] time="2023-07-12T12:53:46Z" level=warning msg="Unable to connect to plugin: //tmp/authz2422457390/authz-test-plugin.sock/AuthZPlugin.AuthZReq: Post \"http://%2F%2Ftmp%2Fauthz2422457390%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZReq\": http: invalid Host header, retrying in 2s"
[2023-07-12T12:54:46.838Z] time="2023-07-12T12:53:48Z" level=warning msg="Unable to connect to plugin: //tmp/authz2422457390/authz-test-plugin.sock/AuthZPlugin.AuthZReq: Post \"http://%2F%2Ftmp%2Fauthz2422457390%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZReq\": http: invalid Host header, retrying in 4s"
[2023-07-12T12:54:46.838Z] time="2023-07-12T12:53:52Z" level=warning msg="Unable to connect to plugin: //tmp/authz2422457390/authz-test-plugin.sock/AuthZPlugin.AuthZReq: Post \"http://%2F%2Ftmp%2Fauthz2422457390%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZReq\": http: invalid Host header, retrying in 8s"
[2023-07-12T12:54:46.838Z]     authz_unix_test.go:82: Failed to authorize request Post "http://%2F%2Ftmp%2Fauthz2422457390%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZReq": http: invalid Host header
[2023-07-12T12:54:46.838Z] 
[2023-07-12T12:54:46.838Z] === FAIL: pkg/authorization TestAuthZResponsePlugin (15.01s)
[2023-07-12T12:54:46.838Z] time="2023-07-12T12:54:00Z" level=warning msg="Unable to connect to plugin: //tmp/authz3990016376/authz-test-plugin.sock/AuthZPlugin.AuthZRes: Post \"http://%2F%2Ftmp%2Fauthz3990016376%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZRes\": http: invalid Host header, retrying in 1s"
[2023-07-12T12:54:46.838Z] time="2023-07-12T12:54:01Z" level=warning msg="Unable to connect to plugin: //tmp/authz3990016376/authz-test-plugin.sock/AuthZPlugin.AuthZRes: Post \"http://%2F%2Ftmp%2Fauthz3990016376%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZRes\": http: invalid Host header, retrying in 2s"
[2023-07-12T12:54:46.838Z] time="2023-07-12T12:54:03Z" level=warning msg="Unable to connect to plugin: //tmp/authz3990016376/authz-test-plugin.sock/AuthZPlugin.AuthZRes: Post \"http://%2F%2Ftmp%2Fauthz3990016376%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZRes\": http: invalid Host header, retrying in 4s"
[2023-07-12T12:54:46.838Z] time="2023-07-12T12:54:07Z" level=warning msg="Unable to connect to plugin: //tmp/authz3990016376/authz-test-plugin.sock/AuthZPlugin.AuthZRes: Post \"http://%2F%2Ftmp%2Fauthz3990016376%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZRes\": http: invalid Host header, retrying in 8s"
[2023-07-12T12:54:46.838Z]     authz_unix_test.go:112: Failed to authorize request Post "http://%2F%2Ftmp%2Fauthz3990016376%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZRes": http: invalid Host header
[2023-07-12T12:54:46.838Z] 
[2023-07-12T12:54:46.838Z] === FAIL: pkg/authorization TestMiddlewareWrapHandler/Positive_Test_Case_: (15.01s)
[2023-07-12T12:54:46.838Z] time="2023-07-12T12:54:30Z" level=warning msg="Unable to connect to plugin: //tmp/authz1534243050/authz-test-plugin.sock/AuthZPlugin.AuthZReq: Post \"http://%2F%2Ftmp%2Fauthz1534243050%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZReq\": http: invalid Host header, retrying in 1s"
[2023-07-12T12:54:46.838Z] time="2023-07-12T12:54:31Z" level=warning msg="Unable to connect to plugin: //tmp/authz1534243050/authz-test-plugin.sock/AuthZPlugin.AuthZReq: Post \"http://%2F%2Ftmp%2Fauthz1534243050%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZReq\": http: invalid Host header, retrying in 2s"
[2023-07-12T12:54:46.838Z] time="2023-07-12T12:54:33Z" level=warning msg="Unable to connect to plugin: //tmp/authz1534243050/authz-test-plugin.sock/AuthZPlugin.AuthZReq: Post \"http://%2F%2Ftmp%2Fauthz1534243050%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZReq\": http: invalid Host header, retrying in 4s"
[2023-07-12T12:54:46.838Z] time="2023-07-12T12:54:37Z" level=warning msg="Unable to connect to plugin: //tmp/authz1534243050/authz-test-plugin.sock/AuthZPlugin.AuthZReq: Post \"http://%2F%2Ftmp%2Fauthz1534243050%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZReq\": http: invalid Host header, retrying in 8s"
[2023-07-12T12:54:46.838Z] time="2023-07-12T12:54:45Z" level=error msg="AuthZRequest for GET www.example.com/auth returned error: plugin plugin failed with error: Post \"http://%2F%2Ftmp%2Fauthz1534243050%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZReq\": http: invalid Host header"
[2023-07-12T12:54:46.838Z]     middleware_unix_test.go:60: assertion failed: error is not nil: plugin plugin failed with error: Post "http://%2F%2Ftmp%2Fauthz1534243050%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZReq": http: invalid Host header
[2023-07-12T12:54:46.838Z] 
[2023-07-12T12:54:46.838Z] === FAIL: pkg/authorization TestMiddlewareWrapHandler (30.02s)

From #45943

Comment on lines +48 to +54
return transport.NewHTTPTransport(tr, scheme, socket), nil
return transport.NewHTTPTransport(tr, scheme, dummyHost), nil
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Arf.. this needs more work;

=== FAIL: pkg/plugins TestFailOnce (15.02s)
time="2023-07-12T13:13:54Z" level=warning msg="Unable to connect to plugin: plugin.moby.localhost/Test.FailOnce: Post \"http://plugin.moby.localhost/Test.FailOnce\": dial tcp: lookup plugin.moby.localhost on 10.100.0.2:53: no such host, retrying in 1s"
time="2023-07-12T13:13:55Z" level=warning msg="Unable to connect to plugin: plugin.moby.localhost/Test.FailOnce: Post \"http://plugin.moby.localhost/Test.FailOnce\": dial tcp: lookup plugin.moby.localhost on 10.100.0.2:53: no such host, retrying in 2s"
time="2023-07-12T13:13:57Z" level=warning msg="Unable to connect to plugin: plugin.moby.localhost/Test.FailOnce: Post \"http://plugin.moby.localhost/Test.FailOnce\": dial tcp: lookup plugin.moby.localhost on 10.100.0.2:53: no such host, retrying in 4s"
time="2023-07-12T13:14:01Z" level=warning msg="Unable to connect to plugin: plugin.moby.localhost/Test.FailOnce: Post \"http://plugin.moby.localhost/Test.FailOnce\": dial tcp: lookup plugin.moby.localhost on 10.100.0.2:53: no such host, retrying in 8s"
    client_test.go:62: Post "http://plugin.moby.localhost/Test.FailOnce": dial tcp: lookup plugin.moby.localhost on 10.100.0.2:53: no such host

@thaJeztah
Copy link
Copy Markdown
Member Author

And more to fix;

=== RUN   TestContainerInvalidJSON/exec/foobar/start/invalid_content_type
    container_test.go:43: assertion failed: error is not nil: Post "http://%2Fgo%2Fsrc%2Fgithub.com%2Fdocker%2Fdocker%2Fbundles%2Ftest-integration%2Fdocker.sock/exec/foobar/start": http: invalid Host header
        --- FAIL: TestContainerInvalidJSON/exec/foobar/start/invalid_content_type (0.00s)

@thaJeztah
Copy link
Copy Markdown
Member Author

Some more;

=== FAIL: amd64.integration-cli TestDockerAPISuite/TestExecResizeImmediatelyAfterExecStart (0.34s)
    docker_api_exec_resize_test.go:111: failed to start the exec: client.Do: Post "http://%2Fgo%2Fsrc%2Fgithub.com%2Fdocker%2Fdocker%2Fbundles%2Ftest-integration%2Fdocker.sock/exec/ed61291b66b21a6d870e48d4956c03d6c79cb98e15097e4cadbbffc6f428e0e0/start": http: invalid Host header
    --- FAIL: TestDockerAPISuite/TestExecResizeImmediatelyAfterExecStart (0.34s)

=== FAIL: amd64.integration-cli TestDockerAPISuite/TestPostContainersAttach (0.37s)
    docker_api_attach_test.go:141: assertion failed: error is not nil: client.Do: Post "http://%2Fgo%2Fsrc%2Fgithub.com%2Fdocker%2Fdocker%2Fbundles%2Ftest-integration%2Fdocker.sock/containers/88656cbe3c6df1756854a082bee57b69b60044a4d1ebd877b02d7670df066947/attach?stream=1&stdin=1&stdout=1": http: invalid Host header
    --- FAIL: TestDockerAPISuite/TestPostContainersAttach (0.37s)

Copy link
Copy Markdown
Contributor

@corhere corhere left a comment

Choose a reason for hiding this comment

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

There is a more standards-compliant choice of Host header value for local communications: the empty string.

client/client.go Outdated
Comment on lines +61 to +62
// For local communications (npipe://, unix://), the hostname is not used,
// but we need valid and meaningful hostname.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If the authority component is missing or undefined for the target URI, then a client MUST send a Host header field with an empty field-value.

RFC 7230, Section 5.4

The authority component is undefined for the unix scheme, therefore the empty string is the valid and meaningful host name to use.

Copy link
Copy Markdown
Contributor

@corhere corhere left a comment

Choose a reason for hiding this comment

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

Getting Go's HTTP client infrastructure to cooperate with sending an empty Host request header is going to be a big uphill battle which likely would require substituting a non-trivial amount of the machinery with custom implementations. Let's just stick with the *.localhost dummy strings for now. localhost is a reserved TLD, and UNIX domain sockets are only accessible on the local host, so it is a logical, future-proof and fairly self-documenting choice.

@thaJeztah thaJeztah force-pushed the fix_host_header branch 3 times, most recently from 2df6195 to c025300 Compare July 13, 2023 11:53
paralin added a commit to skiffos/buildroot that referenced this pull request Jul 18, 2023
Go 1.20.6 and 1.19.11 include a security check of the http Host header:

  golang/go#60374

docker-cli does not satisfy this check:

  $ docker exec -it ctr bash
  http: invalid Host header

This is a backported patch to fix this issue:

Issue: moby/moby#45935
Upstream PR: moby/moby#45942

The upstream PR has been merged and will be included in v24.0.5.

Signed-off-by: Christian Stewart <christian@aperture.us>
dongsupark added a commit to flatcar/scripts that referenced this pull request Jul 18, 2023
Docker daemon started to fail at handling most local connections when
being compiled with Go 1.19.11, which addresses CVE-2023-29406 by
blocking invalid host headers of HTTP/1. As a workaround, Docker started
to define a dummy host header, and to use it for local connections.

Backport the fixes to Flatcar to avoid failures.

See also moby/moby#45935,
moby/moby#45942.
dongsupark added a commit to flatcar/scripts that referenced this pull request Jul 18, 2023
Docker daemon started to fail at handling most local connections when
being compiled with Go 1.19.11, which addresses CVE-2023-29406 by
blocking invalid host headers of HTTP/1. As a workaround, Docker started
to define a dummy host header, and to use it for local connections.

Backport the fixes to Flatcar to avoid failures.

See also moby/moby#45935,
moby/moby#45942.
paralin added a commit to skiffos/buildroot that referenced this pull request Jul 19, 2023
Go 1.20.6 and 1.19.11 include a security check of the http Host header:

  golang/go#60374

docker-cli does not satisfy this check:

  $ docker exec -it ctr bash
  http: invalid Host header

This is a backported patch to fix this issue:

Issue: moby/moby#45935
Upstream PR: moby/moby#45942

The upstream PR has been merged and will be included in v24.0.5.

Signed-off-by: Christian Stewart <christian@aperture.us>
paralin added a commit to skiffos/buildroot that referenced this pull request Jul 19, 2023
Go 1.20.6 and 1.19.11 include a security check of the http Host header:

  golang/go#60374

docker-cli does not satisfy this check:

  $ docker exec -it ctr bash
  http: invalid Host header

This is a backported patch to fix this issue:

Issue: moby/moby#45935
Upstream PR: moby/moby#45942

The upstream PR has been merged and will be included in v24.0.5.

Signed-off-by: Christian Stewart <christian@aperture.us>
dongsupark added a commit to flatcar/scripts that referenced this pull request Jul 20, 2023
Docker client and daemon started to fail at sending or handling most
local connections when being compiled with Go 1.19.11, which addresses
CVE-2023-29406 by blocking invalid host headers of HTTP/1. As a
workaround, Docker started to define a dummy host header, and to use
it for local connections.

Backport the fixes to Flatcar to fix the runtime failures.

See also moby/moby#45935,
moby/moby#45942.
paralin added a commit to skiffos/buildroot that referenced this pull request Jul 23, 2023
Go 1.20.6 and 1.19.11 include a security check of the http Host header:

  golang/go#60374

docker-cli does not satisfy this check:

  $ docker exec -it ctr bash
  http: invalid Host header

This is a backported patch to fix this issue:

Issue: moby/moby#45935
Upstream PR: moby/moby#45942

The upstream PR has been merged and will be included in v24.0.5.

Signed-off-by: Christian Stewart <christian@aperture.us>
paralin added a commit to skiffos/buildroot that referenced this pull request Jul 23, 2023
Go 1.20.6 and 1.19.11 include a security check of the http Host header:

  golang/go#60374

docker-cli does not satisfy this check:

  $ docker exec -it ctr bash
  http: invalid Host header

This is a backported patch to fix this issue:

Issue: moby/moby#45935
Upstream PR: moby/moby#45942

The upstream PR has been merged and will be included in v24.0.5.

Signed-off-by: Christian Stewart <christian@aperture.us>
paralin added a commit to skiffos/buildroot that referenced this pull request Jul 24, 2023
Go 1.20.6 and 1.19.11 include a security check of the http Host header:

  golang/go#60374

docker-cli does not satisfy this check:

  $ docker exec -it ctr bash
  http: invalid Host header

This is a backported patch to fix this issue:

Issue: moby/moby#45935
Upstream PR: moby/moby#45942

The upstream PR has been merged and will be included in v24.0.5.

Signed-off-by: Christian Stewart <christian@aperture.us>
paralin added a commit to skiffos/buildroot that referenced this pull request Jul 24, 2023
Go 1.20.6 and 1.19.11 include a security check of the http Host header:

  golang/go#60374

docker-cli does not satisfy this check:

  $ docker exec -it ctr bash
  http: invalid Host header

This is a backported patch to fix this issue:

Issue: moby/moby#45935
Upstream PR: moby/moby#45942

The upstream PR has been merged and will be included in v24.0.5.

Signed-off-by: Christian Stewart <christian@aperture.us>
paralin added a commit to skiffos/buildroot that referenced this pull request Jul 24, 2023
Go 1.20.6 and 1.19.11 include a security check of the http Host header:

  golang/go#60374

docker-cli does not satisfy this check:

  $ docker exec -it ctr bash
  http: invalid Host header

This is a backported patch to fix this issue:

Issue: moby/moby#45935
Upstream PR: moby/moby#45942

The upstream PR has been merged and will be included in v24.0.5.

Signed-off-by: Christian Stewart <christian@aperture.us>
paralin added a commit to skiffos/buildroot that referenced this pull request Jul 24, 2023
Go 1.20.6 and 1.19.11 include a security check of the http Host header:

  golang/go#60374

docker-cli does not satisfy this check:

  $ docker exec -it ctr bash
  http: invalid Host header

This is a backported patch to fix this issue:

Issue: moby/moby#45935
Upstream PR: moby/moby#45942

The upstream PR has been merged and will be included in v24.0.5.

Signed-off-by: Christian Stewart <christian@aperture.us>
paralin added a commit to skiffos/buildroot that referenced this pull request Jul 24, 2023
Go 1.20.6 and 1.19.11 include a security check of the http Host header:

  golang/go#60374

docker-cli does not satisfy this check:

  $ docker exec -it ctr bash
  http: invalid Host header

This is a backported patch to fix this issue:

Issue: moby/moby#45935
Upstream PR: moby/moby#45942

The upstream PR has been merged and will be included in v24.0.5.

Signed-off-by: Christian Stewart <christian@aperture.us>
paralin added a commit to skiffos/buildroot that referenced this pull request Jul 24, 2023
Go 1.20.6 and 1.19.11 include a security check of the http Host header:

  golang/go#60374

docker-cli does not satisfy this check:

  $ docker exec -it ctr bash
  http: invalid Host header

This is a backported patch to fix this issue:

Issue: moby/moby#45935
Upstream PR: moby/moby#45942

The upstream PR has been merged and will be included in v24.0.5.

Signed-off-by: Christian Stewart <christian@aperture.us>
julianbrost added a commit to Icinga/icingadb that referenced this pull request Jul 24, 2023
As a security fix, Go implemented stricter checks for the Host header in the
http package. This breaks the Go Docker client library [1] resulting in "http:
invalid Host header" errors in our integration tests.

A fix [2] was merged to the 24.0 branch, but is not yet included in a release.
Therefore, this commit updates the dependency to a specific commit
(`go get -u github.com/docker/docker@24.0`). Once it's included in a release,
this can be switched back to using a release version.

[1] moby/moby#45935
[2] moby/moby#45942
DavSanchez added a commit to newrelic/nri-statsd that referenced this pull request Jul 25, 2023
DavSanchez added a commit to newrelic/nri-statsd that referenced this pull request Jul 25, 2023
* NR-100933 chore: upgrade to Go 1.20

* ci: set high severity threshold for snyk (#40)

* fix: pin to 1.20.5 for test image
see testcontainers/testcontainers-go#1359 and moby/moby#45942

---------

Co-authored-by: Roger Coll <rogercoll@protonmail.com>
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.

Golang client fails to attach to streams with "http: invalid Host header" with go1.20.6, go1.19.11

5 participants