Remove raw cert escape in PassTLSClientCert middleware

This commit is contained in:
Romain 2022-10-13 15:08:08 +02:00 committed by GitHub
parent 87815586be
commit 2c550c284d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 17 additions and 19 deletions

View file

@ -16,10 +16,10 @@ PassTLSClientCert adds the selected data from the passed client TLS certificate
## Configuration Examples ## Configuration Examples
Pass the escaped pem in the `X-Forwarded-Tls-Client-Cert` header. Pass the pem in the `X-Forwarded-Tls-Client-Cert` header.
```yaml tab="Docker" ```yaml tab="Docker"
# Pass the escaped pem in the `X-Forwarded-Tls-Client-Cert` header. # Pass the pem in the `X-Forwarded-Tls-Client-Cert` header.
labels: labels:
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.pem=true" - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.pem=true"
``` ```
@ -35,7 +35,7 @@ spec:
``` ```
```yaml tab="Consul Catalog" ```yaml tab="Consul Catalog"
# Pass the escaped pem in the `X-Forwarded-Tls-Client-Cert` header # Pass the pem in the `X-Forwarded-Tls-Client-Cert` header
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.pem=true" - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.pem=true"
``` ```
@ -46,13 +46,13 @@ spec:
``` ```
```yaml tab="Rancher" ```yaml tab="Rancher"
# Pass the escaped pem in the `X-Forwarded-Tls-Client-Cert` header. # Pass the pem in the `X-Forwarded-Tls-Client-Cert` header.
labels: labels:
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.pem=true" - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.pem=true"
``` ```
```yaml tab="File (YAML)" ```yaml tab="File (YAML)"
# Pass the escaped pem in the `X-Forwarded-Tls-Client-Cert` header. # Pass the pem in the `X-Forwarded-Tls-Client-Cert` header.
http: http:
middlewares: middlewares:
test-passtlsclientcert: test-passtlsclientcert:
@ -61,13 +61,13 @@ http:
``` ```
```toml tab="File (TOML)" ```toml tab="File (TOML)"
# Pass the escaped pem in the `X-Forwarded-Tls-Client-Cert` header. # Pass the pem in the `X-Forwarded-Tls-Client-Cert` header.
[http.middlewares] [http.middlewares]
[http.middlewares.test-passtlsclientcert.passTLSClientCert] [http.middlewares.test-passtlsclientcert.passTLSClientCert]
pem = true pem = true
``` ```
??? example "Pass the escaped pem in the `X-Forwarded-Tls-Client-Cert` header" ??? example "Pass the pem in the `X-Forwarded-Tls-Client-Cert` header"
```yaml tab="Docker" ```yaml tab="Docker"
# Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header # Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header
@ -254,12 +254,12 @@ http:
PassTLSClientCert can add two headers to the request: PassTLSClientCert can add two headers to the request:
- `X-Forwarded-Tls-Client-Cert` that contains the escaped pem. - `X-Forwarded-Tls-Client-Cert` that contains the pem.
- `X-Forwarded-Tls-Client-Cert-Info` that contains all the selected certificate information in an escaped string. - `X-Forwarded-Tls-Client-Cert-Info` that contains all the selected certificate information in an escaped string.
!!! info !!! info
* Each header value is a string that has been escaped in order to be a valid URL query. * `X-Forwarded-Tls-Client-Cert-Info` header value is a string that has been escaped in order to be a valid URL query.
* These options only work accordingly to the [MutualTLS configuration](../../https/tls.md#client-authentication-mtls). * These options only work accordingly to the [MutualTLS configuration](../../https/tls.md#client-authentication-mtls).
That is to say, only the certificates that match the `clientAuth.clientAuthType` policy are passed. That is to say, only the certificates that match the `clientAuth.clientAuthType` policy are passed.
@ -371,7 +371,7 @@ The following example shows a complete certificate and explains each of the midd
### `pem` ### `pem`
The `pem` option sets the `X-Forwarded-Tls-Client-Cert` header with the escaped certificate. The `pem` option sets the `X-Forwarded-Tls-Client-Cert` header with the certificate.
In the example, it is the part between `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----` delimiters: In the example, it is the part between `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----` delimiters:

View file

@ -1300,7 +1300,7 @@ spec:
type: object type: object
pem: pem:
description: PEM sets the X-Forwarded-Tls-Client-Cert header with description: PEM sets the X-Forwarded-Tls-Client-Cert header with
the escaped certificate. the certificate.
type: boolean type: boolean
type: object type: object
plugin: plugin:

View file

@ -723,7 +723,7 @@ spec:
type: object type: object
pem: pem:
description: PEM sets the X-Forwarded-Tls-Client-Cert header with description: PEM sets the X-Forwarded-Tls-Client-Cert header with
the escaped certificate. the certificate.
type: boolean type: boolean
type: object type: object
plugin: plugin:

View file

@ -1300,7 +1300,7 @@ spec:
type: object type: object
pem: pem:
description: PEM sets the X-Forwarded-Tls-Client-Cert header with description: PEM sets the X-Forwarded-Tls-Client-Cert header with
the escaped certificate. the certificate.
type: boolean type: boolean
type: object type: object
plugin: plugin:

View file

@ -65,6 +65,6 @@ func (s *TLSClientHeadersSuite) TestTLSClientHeaders(c *check.C) {
}, },
} }
err = try.RequestWithTransport(request, 2*time.Second, tr, try.BodyContains("Forwarded-Tls-Client-Cert: MIIDNTCCAh0CFD0QQcHXUJuKwMBYDA%2BbBExVSP26MA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIDAZGcmFuY2UxFTATBgNVBAoMDFRyYWVmaWsgTGFiczEQMA4GA1UECwwHdHJhZWZpazENMAsGA1UEAwwEcm9vdDAeFw0yMTAxMDgxNzQ0MjRaFw0zMTAxMDYxNzQ0MjRaMFgxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIDAZGcmFuY2UxFTATBgNVBAoMDFRyYWVmaWsgTGFiczEQMA4GA1UECwwHdHJhZWZpazEPMA0GA1UEAwwGc2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvYK2z8gLPOfFLgXNWP2460aeJ9vrH47x%2FlhKLlv4amSDHDx8Cmz%2F6blOUM8XOfMRW1xx%2B%2BAgChWN9dx%2Fkf7G2xlA5grZxRvUQ6xj7AvFG9TQUA3muNh2hvm9c3IjaZBNKH27bRKuDIBvZBvXdX4NL%2FaaFy7w7v7IKxk8j4WkfB23sgyH43g4b7NqKHJugZiedFu5GALmtLbShVOFbjWcre7Wvatdw8dIBmiFJqZQT3UjIuGAgqczIShtLxo4V%2BXyVkIPmzfPrRV%2B4zoMFIFOIaj3syyxb4krPBtxhe7nz2cWvvq0wePB2y4YbAAoVY8NYpd5JsMFwZtG6Uk59ygv4QIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQDaPg69wNeFNFisfBJTrscqVCTW%2BB80gMhpLdxXD%2BKO0%2FWgc5xpB%2FwLSirNtRQyxAa3%2BEEcIwJv%2Fwdh8EyjlDLSpFm%2F8ghntrKhkOfIOPDFE41M5HNfx%2FFuh5btKEenOL%2FXdapqtNUt2ZE4RrsfbL79sPYepa9kDUVi2mCbeH5ollZ0MDU68HpB2YwHbCEuQNk5W3pjYK2NaDkVnxTkfEDM1k%2B3QydO1lqB5JJmcrs59BEveTqaJ3eeh%2F0I4OOab6OkTTZ0JNjJp1573oxO%2Bfce%2FbfGud8xHY5gSN9huU7U6RsgvO7Dhmal%2FsDNl8XC8oU90hVDVXZdA7ewh4jjaoIv")) err = try.RequestWithTransport(request, 2*time.Second, tr, try.BodyContains("Forwarded-Tls-Client-Cert: MIIDNTCCAh0CFD0QQcHXUJuKwMBYDA+bBExVSP26MA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIDAZGcmFuY2UxFTATBgNVBAoMDFRyYWVmaWsgTGFiczEQMA4GA1UECwwHdHJhZWZpazENMAsGA1UEAwwEcm9vdDAeFw0yMTAxMDgxNzQ0MjRaFw0zMTAxMDYxNzQ0MjRaMFgxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIDAZGcmFuY2UxFTATBgNVBAoMDFRyYWVmaWsgTGFiczEQMA4GA1UECwwHdHJhZWZpazEPMA0GA1UEAwwGc2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvYK2z8gLPOfFLgXNWP2460aeJ9vrH47x/lhKLlv4amSDHDx8Cmz/6blOUM8XOfMRW1xx++AgChWN9dx/kf7G2xlA5grZxRvUQ6xj7AvFG9TQUA3muNh2hvm9c3IjaZBNKH27bRKuDIBvZBvXdX4NL/aaFy7w7v7IKxk8j4WkfB23sgyH43g4b7NqKHJugZiedFu5GALmtLbShVOFbjWcre7Wvatdw8dIBmiFJqZQT3UjIuGAgqczIShtLxo4V+XyVkIPmzfPrRV+4zoMFIFOIaj3syyxb4krPBtxhe7nz2cWvvq0wePB2y4YbAAoVY8NYpd5JsMFwZtG6Uk59ygv4QIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQDaPg69wNeFNFisfBJTrscqVCTW+B80gMhpLdxXD+KO0/Wgc5xpB/wLSirNtRQyxAa3+EEcIwJv/wdh8EyjlDLSpFm/8ghntrKhkOfIOPDFE41M5HNfx/Fuh5btKEenOL/XdapqtNUt2ZE4RrsfbL79sPYepa9kDUVi2mCbeH5ollZ0MDU68HpB2YwHbCEuQNk5W3pjYK2NaDkVnxTkfEDM1k+3QydO1lqB5JJmcrs59BEveTqaJ3eeh/0I4OOab6OkTTZ0JNjJp1573oxO+fce/bfGud8xHY5gSN9huU7U6RsgvO7Dhmal/sDNl8XC8oU90hVDVXZdA7ewh4jjaoIv"))
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
} }

View file

@ -416,7 +416,7 @@ type InFlightReq struct {
// This middleware adds the selected data from the passed client TLS certificate to a header. // This middleware adds the selected data from the passed client TLS certificate to a header.
// More info: https://doc.traefik.io/traefik/v2.9/middlewares/http/passtlsclientcert/ // More info: https://doc.traefik.io/traefik/v2.9/middlewares/http/passtlsclientcert/
type PassTLSClientCert struct { type PassTLSClientCert struct {
// PEM sets the X-Forwarded-Tls-Client-Cert header with the escaped certificate. // PEM sets the X-Forwarded-Tls-Client-Cert header with the certificate.
PEM bool `json:"pem,omitempty" toml:"pem,omitempty" yaml:"pem,omitempty" export:"true"` PEM bool `json:"pem,omitempty" toml:"pem,omitempty" yaml:"pem,omitempty" export:"true"`
// Info selects the specific client certificate details you want to add to the X-Forwarded-Tls-Client-Cert-Info header. // Info selects the specific client certificate details you want to add to the X-Forwarded-Tls-Client-Cert-Info header.
Info *TLSClientCertificateInfo `json:"info,omitempty" toml:"info,omitempty" yaml:"info,omitempty" export:"true"` Info *TLSClientCertificateInfo `json:"info,omitempty" toml:"info,omitempty" yaml:"info,omitempty" export:"true"`

View file

@ -325,13 +325,11 @@ func writePart(ctx context.Context, content io.StringWriter, entry, prefix strin
// sanitize As we pass the raw certificates, remove the useless data and make it http request compliant. // sanitize As we pass the raw certificates, remove the useless data and make it http request compliant.
func sanitize(cert []byte) string { func sanitize(cert []byte) string {
cleaned := strings.NewReplacer( return strings.NewReplacer(
"-----BEGIN CERTIFICATE-----", "", "-----BEGIN CERTIFICATE-----", "",
"-----END CERTIFICATE-----", "", "-----END CERTIFICATE-----", "",
"\n", "", "\n", "",
).Replace(string(cert)) ).Replace(string(cert))
return url.QueryEscape(cleaned)
} }
// getCertificates Build a string with the client certificates. // getCertificates Build a string with the client certificates.

View file

@ -610,7 +610,7 @@ WqeUSNGYV//RunTeuRDAf5OxehERb1srzBXhRZ3cZdzXbgR/`,
content := sanitize(test.toSanitize) content := sanitize(test.toSanitize)
expected := url.QueryEscape(strings.ReplaceAll(test.expected, "\n", "")) expected := strings.ReplaceAll(test.expected, "\n", "")
assert.Equal(t, expected, content, "The sanitized certificates should be equal") assert.Equal(t, expected, content, "The sanitized certificates should be equal")
}) })
} }