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

Fix incorrect use of format strings with the conditions package. #1529

Merged
merged 3 commits into from
Jul 5, 2024

Conversation

octo
Copy link
Contributor

@octo octo commented Jun 26, 2024

Many of the functions in the conditions package accept a format string and (optional) arguments, just like fmt.Printf and friends.

In many places, the code passed an error message as the format string, causing it to be interpreted by the fmt package. This leads to issues when the message contains percent signs, e.g. URL-encoded values.

Consider the following code:

// internal/controller/ocirepository_controller.go
revision, err := r.getRevision(ref, opts)
if err != nil {
	e := serror.NewGeneric(
		fmt.Errorf("failed to determine artifact digest: %w", err),
		ociv1.OCIPullFailedReason,
	)
	conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
	//                                                                ^^^^^^^^^^^^^
	return sreconcile.ResultEmpty, e
}

Since getRevision() includes the URL in the error message and the error message is used as a format string, the resulting condition reads:

failed to determine artifact digest: GET https://gitlab.com/jwt/auth?scope=repository%!A(MISSING)fforster%!F(MISSING)<REDACTED>%!F(MISSING)k8s-resource-manifests%!A(MISSING)pull&service=container_registry: DENIED: access forbidden

This PR adds an explicit format string and shortens e.Error() and e.Err.Error() to e, which yields the same output.

To the best of my knowledge, Go is safe from format string attacks. I don't think this is a security vulnerability, but I'm also not a security expert.

Copy link
Contributor

@darkowlzz darkowlzz left a comment

Choose a reason for hiding this comment

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

Thanks for the findings.
The proposed solution seems good to me. I tried the following to understand it better:

func main() {
    msg := "hello %s %A\n"
    foo(msg, nil)
    foo("%s", msg)
}

func foo(format string, args ...interface{}) {
    fmt.Printf(format, args...)
}

Output:

hello %!s(<nil>) %!A(MISSING)
hello %s %A

Adding a simple string verb should be enough.
I've left a few inline comments about the usage of %v which can be replaced with %s as we are mostly dealing with message strings.

internal/controller/gitrepository_controller.go Outdated Show resolved Hide resolved
internal/controller/gitrepository_controller.go Outdated Show resolved Hide resolved
@octo octo force-pushed the fix-conditions-usage branch 2 times, most recently from dffa64a to 4493237 Compare July 4, 2024 07:29
Copy link
Contributor

@darkowlzz darkowlzz left a comment

Choose a reason for hiding this comment

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

LGTM! Thanks.
Please rebase.

octo added 3 commits July 5, 2024 15:55
Many of the functions in the `conditions` package accept a format string and
(optional) arguments, just like `fmt.Printf` and friends.

In many places, the code passed an error message as the format string, causing
it to be interpreted by the `fmt` package. This leads to issues when the
message contains percent signs, e.g. URL-encoded values.

Consider the following code:

```go
// internal/controller/ocirepository_controller.go
revision, err := r.getRevision(ref, opts)
if err != nil {
	e := serror.NewGeneric(
		fmt.Errorf("failed to determine artifact digest: %w", err),
		ociv1.OCIPullFailedReason,
	)
	conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
	return sreconcile.ResultEmpty, e
}
```

Since `getRevision()` includes the URL in the error message and the error
message is used as a format string, the resulting condition reads:

```
failed to determine artifact digest: GET https://gitlab.com/jwt/auth?scope=repository%!A(MISSING)fforster%!F(MISSING)<REDACTED>%!F(MISSING)k8s-resource-manifests%!A(MISSING)pull&service=container_registry: DENIED: access forbidden
```

This adds an explicit format string and shortens `e.Error()` and
`e.Err.Error()` to `e`, which yields the same output.

To the best of my knowledge, Go is safe from format string attacks. I **don't**
think this is a security vulnerability, but I'm also not a security expert.

Signed-off-by: Florian Forster <[email protected]>
The `String()` method is only defined for the pointer receiver.

Signed-off-by: Florian Forster <[email protected]>
@octo
Copy link
Contributor Author

octo commented Jul 5, 2024

LGTM! Thanks. Please rebase.

Thank you so much for the review!

✅ rebased onto main

@darkowlzz darkowlzz requested a review from a team July 5, 2024 13:58
@stefanprodan stefanprodan added the backport:release/v1.3.x To be backported to release/v1.3.x label Jul 5, 2024
Copy link
Member

@stefanprodan stefanprodan left a comment

Choose a reason for hiding this comment

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

LGTM

Thanks @octo 🥇

PS. This issue is present in all controllers. It would be great If you have time to help us fixing this everywhere. URLs are logged in many places, for example image-reflector-controller.

@stefanprodan stefanprodan merged commit 8d8e7cc into fluxcd:main Jul 5, 2024
10 checks passed
@fluxcdbot
Copy link
Member

Backport failed for release/v1.3.x, because it was unable to cherry-pick the commit(s).

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin release/v1.3.x
git worktree add -d .worktree/backport-1529-to-release/v1.3.x origin/release/v1.3.x
cd .worktree/backport-1529-to-release/v1.3.x
git switch --create backport-1529-to-release/v1.3.x
git cherry-pick -x 8be37ef1d2dc6655143e6499073643e08ca0b9ba fa3022443ce5aa91aaf959be66a988b0bc93fac0 277e5c1d55b1d430ce5ef4e2c80f1ef45e05ea7b

octo added a commit to octo/flux-kustomize-controller that referenced this pull request Jul 8, 2024
The `Mark…` functions in the `conditions` package accept a format string and
(optional) arguments, just like `fmt.Printf` and friends.

In many places, the code passed an error message as the format string, causing
it to be interpreted as a format string by the `fmt` package. This leads to
issues when the message contains percent signs, e.g. URL-encoded values.

This PR adds a format string and shortens `err.Error()` to `err`, which yields
the same output.

This change is identical in principle to
fluxcd/source-controller#1529.

Signed-off-by: Florian Forster <[email protected]>
github-actions bot pushed a commit to fluxcd/kustomize-controller that referenced this pull request Jul 8, 2024
The `Mark…` functions in the `conditions` package accept a format string and
(optional) arguments, just like `fmt.Printf` and friends.

In many places, the code passed an error message as the format string, causing
it to be interpreted as a format string by the `fmt` package. This leads to
issues when the message contains percent signs, e.g. URL-encoded values.

This PR adds a format string and shortens `err.Error()` to `err`, which yields
the same output.

This change is identical in principle to
fluxcd/source-controller#1529.

Signed-off-by: Florian Forster <[email protected]>
(cherry picked from commit ad38b1c)
octo added a commit to octo/flux-helm-controller that referenced this pull request Jul 12, 2024
The `Mark…` functions in the `conditions` package accept a format string and
(optional) arguments, just like `fmt.Printf` and friends.

In many places, the code passed an error message as the format string, causing
it to be interpreted as a format string by the `fmt` package. This leads to
issues when the message contains percent signs, e.g. URL-encoded values.

This PR adds a format string and shortens `err.Error()` to `err`, which yields
the same output.

This change is identical in principle to
fluxcd/source-controller#1529.

Signed-off-by: Florian Forster <[email protected]>
octo added a commit to octo/flux-notification-controller that referenced this pull request Jul 12, 2024
The `Mark…` functions in the `conditions` package accept a format string and
(optional) arguments, just like `fmt.Printf` and friends.

In many places, the code passed an error message as the format string, causing
it to be interpreted as a format string by the `fmt` package. This leads to
issues when the message contains percent signs, e.g. URL-encoded values.

This PR adds a format string and shortens `err.Error()` to `err`, which yields
the same output.

This change is identical in principle to fluxcd/source-controller#1529.

Signed-off-by: Florian Forster <[email protected]>
octo added a commit to octo/flux-image-automation-controller that referenced this pull request Jul 12, 2024
The `Mark…` functions in the `conditions` package accept a format string and
(optional) arguments, just like `fmt.Printf` and friends.

In many places, the code passed an error message as the format string, causing
it to be interpreted as a format string by the `fmt` package. This leads to
issues when the message contains percent signs, e.g. URL-encoded values.

This PR adds a format string and shortens `err.Error()` to `err`, which yields
the same output.

This change is identical in principle to fluxcd/source-controller#1529.

Signed-off-by: Florian Forster <[email protected]>
octo added a commit to octo/flux-image-reflector-controller that referenced this pull request Jul 12, 2024
The `Mark…` functions in the `conditions` package accept a format string and
(optional) arguments, just like `fmt.Printf` and friends.

In many places, the code passed an error message as the format string, causing
it to be interpreted as a format string by the `fmt` package. This leads to
issues when the message contains percent signs, e.g. URL-encoded values.

This PR adds a format string and shortens `err.Error()` to `err`, which yields
the same output.

This change is identical in principle to fluxcd/source-controller#1529.

Signed-off-by: Florian Forster <[email protected]>
@octo
Copy link
Contributor Author

octo commented Jul 12, 2024

This issue is present in all controllers. It would be great If you have time to help us fixing this everywhere. URLs are logged in many places, for example image-reflector-controller.

@stefanprodan I have opened PRs for:

Already merged:

Did I miss any controllers that might need some TLC?

@stefanprodan
Copy link
Member

@octo only helm-controller left. Thanks a lot for all the help!

@octo
Copy link
Contributor Author

octo commented Jul 12, 2024

@octo only helm-controller left. Thanks a lot for all the help!

Only missed that in my listing. PR is here: fluxcd/helm-controller#1025

@octo octo deleted the fix-conditions-usage branch July 12, 2024 07:36
octo added a commit to octo/flux-helm-controller that referenced this pull request Jul 12, 2024
The `Mark…` functions in the `conditions` package accept a format string and
(optional) arguments, just like `fmt.Printf` and friends.

In many places, the code passed an error message as the format string, causing
it to be interpreted as a format string by the `fmt` package. This leads to
issues when the message contains percent signs, e.g. URL-encoded values.

This PR adds a format string and shortens `err.Error()` to `err`, which yields
the same output.

This change is identical in principle to
fluxcd/source-controller#1529.

Signed-off-by: Florian Forster <[email protected]>
octo added a commit to octo/flux-helm-controller that referenced this pull request Jul 12, 2024
The `Mark…` functions in the `conditions` package accept a format string and
(optional) arguments, just like `fmt.Printf` and friends.

In many places, the code passed an error message as the format string, causing
it to be interpreted as a format string by the `fmt` package. This leads to
issues when the message contains percent signs, e.g. URL-encoded values.

This PR adds a format string and shortens `err.Error()` to `err`, which yields
the same output.

This change is identical in principle to
fluxcd/source-controller#1529.

Signed-off-by: Florian Forster <[email protected]>
github-actions bot pushed a commit to fluxcd/notification-controller that referenced this pull request Jul 12, 2024
The `Mark…` functions in the `conditions` package accept a format string and
(optional) arguments, just like `fmt.Printf` and friends.

In many places, the code passed an error message as the format string, causing
it to be interpreted as a format string by the `fmt` package. This leads to
issues when the message contains percent signs, e.g. URL-encoded values.

This PR adds a format string and shortens `err.Error()` to `err`, which yields
the same output.

This change is identical in principle to fluxcd/source-controller#1529.

Signed-off-by: Florian Forster <[email protected]>
(cherry picked from commit 1f4cdff)
github-actions bot pushed a commit to fluxcd/helm-controller that referenced this pull request Jul 12, 2024
The `Mark…` functions in the `conditions` package accept a format string and
(optional) arguments, just like `fmt.Printf` and friends.

In many places, the code passed an error message as the format string, causing
it to be interpreted as a format string by the `fmt` package. This leads to
issues when the message contains percent signs, e.g. URL-encoded values.

This PR adds a format string and shortens `err.Error()` to `err`, which yields
the same output.

This change is identical in principle to
fluxcd/source-controller#1529.

Signed-off-by: Florian Forster <[email protected]>
(cherry picked from commit c94eb8e)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:release/v1.3.x To be backported to release/v1.3.x
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants