CVE-2024-34079 (Go, published 2024-05-14T15:38Z)
Description: value: octo-sts is a GitHub App that acts like a Security Token Service (STS) for the Github API. This vulnerability can spike the resource utilization of the STS service, and combined with a significant traffic volume could potentially lead to a denial of service. This vulnerability is fixed in 0.1.0
Severity: nan (CVSS v3 base score: )
Weakness: NVD-CWE-noinfo \u2014 Insufficient Information
There is insufficient information about the issue to classify it; details are unkown or unspecified.
Repository: https://github.com/octo-sts/app
Files changed:
pkg/maxsize/maxsize.go
pkg/maxsize/maxsize_test.go
pkg/provider/provider.go
Commit message: Merge pull request from GHSA-75r6-6jg8-pfcq

This change adds some logic to limit the size of the HTTP responses allowed when performing OIDC discovery on a new provider.

Prior to this, Octo STS could have been manipulated into reading arbitrary amounts of data from the provided issuer endpoint.

Signed-off-by: Matt Moore <mattmoor@chainguard.dev>

Vulnerable code:

Fixed code:
// Copyright 2024 Chainguard, Inc.
// SPDX-License-Identifier: Apache-2.0

package maxsize

import (
	"io"
	"net/http"
)

// NewRoundTripper creates a new http.RoundTripper that wraps the given
// http.RoundTripper and limits the size of the response body to maxSize bytes.
func NewRoundTripper(maxSize int64, inner http.RoundTripper) http.RoundTripper {
	return &ms{
		base:        inner,
		maxBodySize: maxSize,
	}
}

type ms struct {
	base        http.RoundTripper // The underlying RoundTripper
	maxBodySize int64             // Maximum allowed response body size in bytes
}

// RoundTrip implements http.RoundTripper
func (rt *ms) RoundTrip(req *http.Request) (*http.Response, error) {
	resp, err := rt.base.RoundTrip(req)
	if err != nil {
		return nil, err
	}

	resp.Body = &lr{
		LimitedReader: io.LimitedReader{
			R: resp.Body,
			N: rt.maxBodySize,
		},
		close: resp.Body.Close,
	}
	return resp, nil
}

type lr struct {
	io.LimitedReader
	close func() error
}

// Close implements io.Closer
func (r *lr) Close() error {
	return r.close()
}
// Copyright 2024 Chainguard, Inc.
// SPDX-License-Identifier: Apache-2.0

package maxsize

import (
	"context"
	"net/http"
	"testing"

	"github.com/coreos/go-oidc/v3/oidc"
)

func TestCompile(t *testing.T) {
	tests := []struct {
		name    string
		size    int64
		wantErr bool
	}{{
		name:    "large size",
		size:    1000000, // 1M bytes
		wantErr: false,
	}, {
		name:    "medium size",
		size:    10000, // 10000 bytes
		wantErr: false,
	}, {
		name:    "tiny size",
		size:    10, // 10 bytes
		wantErr: true,
	}}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			ctx := oidc.ClientContext(context.Background(), &http.Client{
				Transport: NewRoundTripper(tt.size, http.DefaultTransport),
			})
			for _, issuer := range []string{
				"https://accounts.google.com",
				"https://token.actions.githubusercontent.com",
				"https://issuer.enforce.dev",
			} {
				if _, err := oidc.NewProvider(ctx, issuer); (err != nil) != tt.wantErr {
					t.Errorf("constructing %q provider: %v", issuer, err)
				}
			}
		})
	}
}
	"net/http"
	"github.com/chainguard-dev/terraform-infra-common/pkg/httpmetrics"
	"github.com/octo-sts/app/pkg/maxsize"
// MaximumResponseSize is the maximum size of allowed responses from
// OIDC providers.  Some anecdata
//   - Google: needs around 1KiB
//   - GitHub: needs around 5KiB
//   - Chainguard: needs around 2KiB
const MaximumResponseSize = 100 * 1024 // 100KiB

	ctx = oidc.ClientContext(ctx, &http.Client{
		Transport: maxsize.NewRoundTripper(MaximumResponseSize, httpmetrics.Transport),
	})