goharbor / terraform-provider-harbor

A Terraform provider for Harbor. To configure and manage all aspects of your Harbor Container Registry with Terraform Infrastructure as Code.
https://registry.terraform.io/providers/goharbor/harbor
MIT License
118 stars 93 forks source link

GET requests blocked by AWS Application Load Balancer #467

Closed BlueIce closed 4 weeks ago

BlueIce commented 3 months ago

Describe the bug

When accessing a harbor instance which is behind a AWS Application Load Balancers, GET requests get blocked if "Desync mitigation mode" is set to strictest.

I think the reason it that for GET (and maybe also HEAD) requests, the payload passed to the client is nil. And when the payload is processed by the json encoder, the byte buffer b will contain a literal null and a newline: https://github.com/goharbor/terraform-provider-harbor/blob/33fc0494c50265a23c15ff91e8b11a1c78b47c5a/client/client.go#L42-L43

Which in turn has the effect, that the request will also have a content-length header and a non-empty body. The request gets classified as Ambiguous (which means accordings to AWS docs: "Request does not comply with RFC 7230 but poses a risk, as various web servers and proxies could handle it differently."), which is blocked at strictest mode. The classification reason is UndefinedContentLengthSemantics, meaning:

There is a Content-Length header defined for a GET or HEAD request.

To Reproduce

The json encoding part can be reproduced by

package main

import (
    "bytes"
    "fmt"
    "encoding/json"
)

func main() {
    b := new(bytes.Buffer)
    err := json.NewEncoder(b).Encode(nil)
    if err != nil {
        fmt.Println("Error encoding:", err)
        return
    }

    fmt.Printf("buffer |%s|", b)
}

This will print:

buffer |null
|

To reproduce the blocked requests, a AWS Application Load Balancer has to be setup with "Desync mitigation mode" set to strictest.

Expected behavior Request don't get blocked by AWS Application Load Balancer in strictest mode.

Additional context

Idea to fix the problem: Do not use the json encoder if the payload is nil so that the byte buffer will stay empty.

flbla commented 1 month ago

Hi @BlueIce , Thank you for the bug report. I created a PR : https://github.com/goharbor/terraform-provider-harbor/pull/472 But I don't have an ALB to test it... So let me know if you can test it before I merge it

BlueIce commented 1 month ago

I managed to build the provider manually and use it in a local test setup. Using the code from the PR, I was able to successfully run terraform and create some harbor resources (while the loadbalancer was set to strictest)! :rocket:

And I also cross-checked, that it failed using the code from the main branch (as expected).

flbla commented 4 weeks ago

hi @BlueIce thanks, I merged it I'll build soon a new release