Compare commits

..

49 Commits

Author SHA1 Message Date
Dan Garfield
1cd24e0bd3 Add additional release dates
Signed-off-by: Dan Garfield <dan.garfield@octopus.com>
2025-11-19 08:23:44 -07:00
github-actions[bot]
c79f17167c [Bot] docs: Update Snyk report (#25299)
Signed-off-by: CI <ci@argoproj.com>
Co-authored-by: CI <ci@argoproj.com>
2025-11-17 00:23:38 +00:00
Bryan Horstmann
ef6a27fdfc docs: Document the correct sync option to disable client side migration (#25288)
Signed-off-by: Bryan Horstmann <bhorstmann@gmail.com>
2025-11-14 00:46:25 -10:00
dependabot[bot]
61a89dc23e chore(deps): bump gitlab.com/gitlab-org/api/client-go from 0.159.0 to 0.160.0 (#25281)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-14 10:12:06 +00:00
Mike Cutsail
5c6aa59ed3 feat: oidc background token refresh (#23727)
Signed-off-by: Mike Cutsail <mcutsail15@apple.com>
2025-11-13 11:37:53 -05:00
Ivan Pedersen
60f2ff5f77 fix: return empty list instead of nil to prevent panic. Fixes #25189 (#25192)
Signed-off-by: Ivan Pedersen <ivan.pedersen@volvocars.com>
2025-11-13 10:49:18 -05:00
Atif Ali
98d0e8451a docs: add user content for managed-by-url annotation (#25055)
Signed-off-by: Atif Ali <atali@redhat.com>
Co-authored-by: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com>
2025-11-12 11:38:41 -05:00
dependabot[bot]
d8a86f4ccb chore(deps): bump golang.org/x/oauth2 from 0.32.0 to 0.33.0 (#25234)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-12 14:51:58 +00:00
dependabot[bot]
f618adb93e chore(deps): bump golang.org/x/net from 0.46.0 to 0.47.0 (#25264)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-12 09:15:36 -05:00
dependabot[bot]
b829cd29c8 chore(deps): bump github.com/go-openapi/runtime from 0.29.0 to 0.29.2 (#25255)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-12 14:04:00 +01:00
dependabot[bot]
b6bf931fe4 chore(deps): bump github.com/olekukonko/tablewriter from 1.1.0 to 1.1.1 (#25232)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-12 14:03:02 +01:00
dependabot[bot]
6d303b9b3f chore(deps): bump golang.org/x/sync from 0.17.0 to 0.18.0 (#25231)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-11 15:33:25 +00:00
dependabot[bot]
fd2fc0abf9 chore(deps): bump github.com/Azure/azure-sdk-for-go/sdk/azidentity from 1.13.0 to 1.13.1 (#25254)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-11 09:44:08 -05:00
dependabot[bot]
2a4734c54c chore(deps): bump renovatebot/github-action from 43.0.20 to 44.0.2 (#25256)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-11 09:43:17 -05:00
Jonathan Dale
43828a7770 docs: Add IQVIA to the USERS.md list (#25253)
Signed-off-by: Jonathan Dale <47530196+jonathan-dale@users.noreply.github.com>
2025-11-10 22:11:01 -05:00
Manali
be31558b41 docs: Add Expedia to USERS.md (#25251)
Signed-off-by: msathe_expedia <msathe@expediagroup.com>
Co-authored-by: msathe_expedia <msathe@expediagroup.com>
2025-11-10 21:38:15 +01:00
Jeremy Johnson
b3dfab5f6d docs: Add Collins Aerospace to USERS.md (#25247) 2025-11-10 11:27:05 -05:00
Sakib Jalal
54f9b8c9b5 docs: add MongoDB to users.md (#25248)
Signed-off-by: Sakib Jalal <sakib.jalal@gmail.com>
2025-11-10 11:26:23 -05:00
J. Gavin Ray
2ab3b0ddaf docs: Adding Arcadia to USERS.md (#25242)
Signed-off-by: J. Gavin Ray <git@jgavinray.com>
2025-11-10 11:26:01 -05:00
Jeff Tougas
be2b7da724 docs(users): Add Dematic to USERS.md (#25246)
Signed-off-by: Jeff Tougas <jeff.tougas@kiongroup.com>
Co-authored-by: Jeff Tougas <jeff.tougas@kiongroup.com>
Co-authored-by: Dan Garfield <dan@codefresh.io>
2025-11-10 15:02:34 +00:00
dependabot[bot]
13895feb99 chore(deps): bump golangci/golangci-lint-action from 8.0.0 to 9.0.0 (#25236)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-10 10:00:03 -05:00
Matt McLane
991ede4764 Update USERS.md (#25243)
Signed-off-by: Matt McLane <mmclane@docnetwork.org>
2025-11-10 09:52:04 -05:00
dependabot[bot]
6bf276f675 chore(deps): bump softprops/action-gh-release from 2.4.1 to 2.4.2 (#25235)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-09 21:23:39 -10:00
github-actions[bot]
dbe0a0c1d3 [Bot] docs: Update Snyk report (#25227)
Signed-off-by: CI <ci@argoproj.com>
Co-authored-by: CI <ci@argoproj.com>
2025-11-09 19:24:57 +00:00
Yuval_
19ca5dfad7 chore(deps): bump github.com/cyphar/filepath-securejoin from 0.4.1 to 0.6.0 (#25228)
Signed-off-by: yuvalshi0 <yuvalshi0@gmail.com>
2025-11-09 14:10:06 -05:00
Peter Jiang
728f2e7436 fix: regression on creationTimestamp with server-side diff (#25210)
Signed-off-by: Peter Jiang <peterjiang823@gmail.com>
2025-11-08 17:44:53 -05:00
dependabot[bot]
6638dd67a6 chore(deps): bump github.com/Azure/azure-sdk-for-go/sdk/azcore from 1.19.1 to 1.20.0 (#25212)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-08 20:31:31 +01:00
dependabot[bot]
10f991d674 chore(deps): bump min-document from 2.19.0 to 2.19.1 in /ui (#25223)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-08 20:30:31 +01:00
Afzal Ansari
45462175c9 chore: upgrade the notification engine deps (#25219)
Signed-off-by: Afzal Ansari <afzal442@gmail.com>
2025-11-07 22:23:54 +01:00
Sverre Boschman
ce627702dc docs(users): add Topicus.Education to adopters list (#25215)
Signed-off-by: Sverre Boschman <1142569+sboschman@users.noreply.github.com>
2025-11-07 12:09:32 -05:00
Michael Crenshaw
d6f25a169e chore: remove unused struct (#25186)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-11-07 04:56:06 +00:00
jwinters01
81073bdb1f fix:(ui) don't render ApplicationSelector unless the panel is showing (#25201)
Signed-off-by: Jonathan Winters <wintersjonathan0@gmail.com>
2025-11-06 17:45:12 -05:00
Kanika Rana
6cfef6bf02 docs: promote ApplicationSet's Progressive Sync to beta (#25122)
Signed-off-by: Kanika Rana <krana@redhat.com>
2025-11-06 09:42:02 -07:00
dependabot[bot]
6df6b7a355 chore(deps): bump code.gitea.io/sdk/gitea from 0.22.0 to 0.22.1 (#25057)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-06 10:59:28 -05:00
dependabot[bot]
c7b47c3cd2 chore(deps): bump gitlab.com/gitlab-org/api/client-go from 0.157.1 to 0.159.0 (#25175)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-06 09:34:37 -05:00
argoproj-renovate[bot]
b4c7467cf3 chore(deps): update docker.io/library/golang:1.25.3 docker digest to 6d4e5e7 (#25187)
Signed-off-by: renovate[bot] <renovate[bot]@users.noreply.github.com>
Co-authored-by: argoproj-renovate[bot] <161757507+argoproj-renovate[bot]@users.noreply.github.com>
2025-11-05 11:21:05 -05:00
Michael Crenshaw
e6152b827b docs: more thorough release instructions (#25173)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-11-05 11:20:38 -05:00
jwinters01
1ae13b2896 feat(ui): conditionally render app view extensions (#25132)
Signed-off-by: Jonathan Winters <wintersjonathan0@gmail.com>
2025-11-05 09:34:29 -05:00
argoproj-renovate[bot]
8d0e5b9408 chore(deps): update docker.io/library/golang:1.25.3 docker digest to b2663ef (#25172)
Signed-off-by: renovate[bot] <renovate[bot]@users.noreply.github.com>
Co-authored-by: argoproj-renovate[bot] <161757507+argoproj-renovate[bot]@users.noreply.github.com>
2025-11-05 09:21:11 -05:00
Jaewoo Choi
0b40e3bc78 fix(ui): refactor tooltip, align action btns in app tile view (#25098)
Signed-off-by: choejwoo <jaewoo45@gmail.com>
2025-11-05 09:08:35 -05:00
dependabot[bot]
1389f0c032 chore(deps): bump github.com/casbin/casbin/v2 from 2.131.0 to 2.132.0 (#25177)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-05 11:46:29 +00:00
dependabot[bot]
59b6b0e2b8 chore(deps): bump github.com/grpc-ecosystem/go-grpc-middleware/v2 from 2.3.2 to 2.3.3 (#25176)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-05 11:43:48 +00:00
Jaewoo Choi
27a503aa59 fix(ui): add null-safe handling for assignedWindows in status panel (#25128)
Signed-off-by: choejwoo <jaewoo45@gmail.com>
2025-11-05 00:51:07 -10:00
Julian
943936a909 docs: clarify default hook deletion policy (#25170)
Signed-off-by: Globulard <julian.amoedo13@gmail.com>
2025-11-05 11:33:28 +02:00
Atif Ali
8d40fa3b5c docs: update user content for deleting applications (#25124)
Signed-off-by: Atif Ali <atali@redhat.com>
Co-authored-by: Dan Garfield <dan@codefresh.io>
2025-11-04 15:19:13 -07:00
argoproj-renovate[bot]
2d71941dd0 chore(deps): update docker.io/library/golang:1.25.3 docker digest to 0afe9b5 (#25168)
Signed-off-by: renovate[bot] <renovate[bot]@users.noreply.github.com>
Co-authored-by: argoproj-renovate[bot] <161757507+argoproj-renovate[bot]@users.noreply.github.com>
2025-11-04 13:52:07 -05:00
Codey Jenkins
49f5c03622 chore(tilt): add deps for build and ui packages (#25165)
Signed-off-by: Codey Jenkins <FourFifthsCode@users.noreply.github.com>
2025-11-04 13:07:42 -05:00
Nitish Kumar
ebca0521ad docs: add git concurrency issue in upgrade instruction (#25167)
Signed-off-by: nitishfy <justnitish06@gmail.com>
2025-11-04 22:37:58 +05:30
argoproj-renovate[bot]
4c57962cf4 chore(deps): update docker.io/library/golang:1.25.3 docker digest to 7e3cbcd (#25158)
Signed-off-by: renovate[bot] <renovate[bot]@users.noreply.github.com>
Co-authored-by: argoproj-renovate[bot] <161757507+argoproj-renovate[bot]@users.noreply.github.com>
2025-11-04 11:20:46 -05:00
97 changed files with 3838 additions and 4461 deletions

View File

@@ -9,19 +9,76 @@ assignees: ''
Target RC1 date: ___. __, ____
Target GA date: ___. __, ____
- [ ] 1wk before feature freeze post in #argo-contributors that PRs must be merged by DD-MM-YYYY to be included in the release - ask approvers to drop items from milestone they cant merge
## RC1 Release Checklist
- [ ] 1wk before feature freeze post in #argo-contributors that PRs must be merged by DD-MM-YYYY to be included in the release - ask approvers to drop items from milestone they can't merge
- [ ] At least two days before RC1 date, draft RC blog post and submit it for review (or delegate this task)
- [ ] Cut RC1 (or delegate this task to an Approver and coordinate timing)
- [ ] Create new release branch
- [ ] Create new release branch (or delegate this task to an Approver)
- [ ] Add the release branch to ReadTheDocs
- [ ] Confirm that tweet and blog post are ready
- [ ] Trigger the release
- [ ] After the release is finished, publish tweet and blog post
- [ ] Post in #argo-cd and #argo-announcements with lots of emojis announcing the release and requesting help testing
- [ ] Monitor support channels for issues, cherry-picking bugfixes and docs fixes as appropriate (or delegate this task to an Approver and coordinate timing)
- [ ] At release date, evaluate if any bugs justify delaying the release. If not, cut the release (or delegate this task to an Approver and coordinate timing)
- [ ] If unreleased changes are on the release branch for {current minor version minus 3}, cut a final patch release for that series (or delegate this task to an Approver and coordinate timing)
- [ ] After the release, post in #argo-cd that the {current minor version minus 3} has reached EOL (example: https://cloud-native.slack.com/archives/C01TSERG0KZ/p1667336234059729)
- [ ] Update the last patch release of the EOL minor release series to say that the version is EOL
- [ ] Cut RC1 (or delegate this task to an Approver and coordinate timing)
- [ ] Run the [Init ArgoCD Release workflow](https://github.com/argoproj/argo-cd/actions/workflows/init-release.yaml) from the release branch
- [ ] Review and merge the generated version bump PR
- [ ] Run `./hack/trigger-release.sh` to push the release tag
- [ ] Monitor the [Publish ArgoCD Release workflow](https://github.com/argoproj/argo-cd/actions/workflows/release.yaml)
- [ ] Verify the release on [GitHub releases](https://github.com/argoproj/argo-cd/releases)
- [ ] Verify the container image on [Quay.io](https://quay.io/repository/argoproj/argocd?tab=tags)
- [ ] Confirm the new version appears in [Read the Docs](https://argo-cd.readthedocs.io/)
- [ ] Announce RC1 release
- [ ] Confirm that tweet and blog post are ready
- [ ] Publish tweet and blog post
- [ ] Post in #argo-cd and #argo-announcements requesting help testing:
```
:mega: Argo CD v{MAJOR}.{MINOR}.{PATCH}-rc{RC_NUMBER} is OUT NOW! :argocd::tada:
Please go through the following resources to know more about the release:
Release notes: https://github.com/argoproj/argo-cd/releases/tag/v{VERSION}
Blog: {BLOG_POST_URL}
We'd love your help testing this release candidate! Please try it out in your environments and report any issues you find. This helps us ensure a stable GA release.
Thanks to all the folks who spent their time contributing to this release in any way possible!
```
- [ ] Monitor support channels for issues, cherry-picking bugfixes and docs fixes as appropriate during the RC period (or delegate this task to an Approver and coordinate timing)
## GA Release Checklist
- [ ] At GA release date, evaluate if any bugs justify delaying the release
- [ ] Prepare for EOL version (version that is 3 releases old)
- [ ] If unreleased changes are on the release branch for {current minor version minus 3}, cut a final patch release for that series (or delegate this task to an Approver and coordinate timing)
- [ ] Edit the final patch release on GitHub and add the following notice at the top:
```markdown
> [!IMPORTANT]
> **END OF LIFE NOTICE**
>
> This is the final release of the {EOL_SERIES} release series. As of {GA_DATE}, this version has reached end of life and will no longer receive bug fixes or security updates.
>
> **Action Required**: Please upgrade to a [supported version](https://argo-cd.readthedocs.io/en/stable/operator-manual/upgrading/overview/) (v{SUPPORTED_VERSION_1}, v{SUPPORTED_VERSION_2}, or v{NEW_VERSION}).
```
- [ ] Cut GA release (or delegate this task to an Approver and coordinate timing)
- [ ] Run the [Init ArgoCD Release workflow](https://github.com/argoproj/argo-cd/actions/workflows/init-release.yaml) from the release branch
- [ ] Review and merge the generated version bump PR
- [ ] Run `./hack/trigger-release.sh` to push the release tag
- [ ] Monitor the [Publish ArgoCD Release workflow](https://github.com/argoproj/argo-cd/actions/workflows/release.yaml)
- [ ] Verify the release on [GitHub releases](https://github.com/argoproj/argo-cd/releases)
- [ ] Verify the container image on [Quay.io](https://quay.io/repository/argoproj/argocd?tab=tags)
- [ ] Verify the `stable` tag has been updated
- [ ] Confirm the new version appears in [Read the Docs](https://argo-cd.readthedocs.io/)
- [ ] Announce GA release with EOL notice
- [ ] Confirm that tweet and blog post are ready
- [ ] Publish tweet and blog post
- [ ] Post in #argo-cd and #argo-announcements announcing the release and EOL:
```
:mega: Argo CD v{MAJOR}.{MINOR} is OUT NOW! :argocd::tada:
Please go through the following resources to know more about the release:
Upgrade instructions: https://argo-cd.readthedocs.io/en/latest/operator-manual/upgrading/{PREV_MINOR}-{MAJOR}.{MINOR}/
Blog: {BLOG_POST_URL}
:warning: IMPORTANT: With the release of Argo CD v{MAJOR}.{MINOR}, support for Argo CD v{EOL_VERSION} has officially reached End of Life (EOL).
Thanks to all the folks who spent their time contributing to this release in any way possible!
```
- [ ] (For the next release champion) Review the [items scheduled for the next release](https://github.com/orgs/argoproj/projects/25). If any item does not have an assignee who can commit to finish the feature, move it to the next release.
- [ ] (For the next release champion) Schedule a time mid-way through the release cycle to review items again.
- [ ] (For the next release champion) Schedule a time mid-way through the release cycle to review items again.

View File

@@ -108,7 +108,7 @@ jobs:
with:
go-version: ${{ env.GOLANG_VERSION }}
- name: Run golangci-lint
uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0
uses: golangci/golangci-lint-action@0a35821d5c230e903fcfe077583637dea1b27b47 # v9.0.0
with:
# renovate: datasource=go packageName=github.com/golangci/golangci-lint versioning=regex:^v(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)?$
version: v2.5.0

View File

@@ -236,7 +236,7 @@ jobs:
echo "hashes=$(sha256sum /tmp/sbom.tar.gz | base64 -w0)" >> "$GITHUB_OUTPUT"
- name: Upload SBOM
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
uses: softprops/action-gh-release@5be0e66d93ac7ed76da52eca8bb058f665c3a5fe # v2.4.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:

View File

@@ -30,7 +30,7 @@ jobs:
go-version: 1.25.3
- name: Self-hosted Renovate
uses: renovatebot/github-action@ea850436a5fe75c0925d583c7a02c60a5865461d #43.0.20
uses: renovatebot/github-action@c5fdc9f98fdf9e9bb16b5760f7e560256eb79326 #44.0.2
with:
configurationFile: .github/configs/renovate-config.js
token: '${{ steps.get_token.outputs.token }}'

View File

@@ -4,7 +4,7 @@ ARG BASE_IMAGE=docker.io/library/ubuntu:25.04@sha256:27771fb7b40a58237c98e8d3e6b
# Initial stage which pulls prepares build dependencies and CLI tooling we need for our final image
# Also used as the image in CI jobs so needs all dependencies
####################################################################################################
FROM docker.io/library/golang:1.25.3@sha256:6bac879c5b77e0fc9c556a5ed8920e89dab1709bd510a854903509c828f67f96 AS builder
FROM docker.io/library/golang:1.25.3@sha256:6d4e5e74f47db00f7f24da5f53c1b4198ae46862a47395e30477365458347bf2 AS builder
WORKDIR /tmp
@@ -103,7 +103,7 @@ RUN HOST_ARCH=$TARGETARCH NODE_ENV='production' NODE_ONLINE_ENV='online' NODE_OP
####################################################################################################
# Argo CD Build stage which performs the actual build of Argo CD binaries
####################################################################################################
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.25.3@sha256:6bac879c5b77e0fc9c556a5ed8920e89dab1709bd510a854903509c828f67f96 AS argocd-build
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.25.3@sha256:6d4e5e74f47db00f7f24da5f53c1b4198ae46862a47395e30477365458347bf2 AS argocd-build
WORKDIR /go/src/github.com/argoproj/argo-cd

View File

@@ -1,4 +1,4 @@
FROM docker.io/library/golang:1.25.3@sha256:6bac879c5b77e0fc9c556a5ed8920e89dab1709bd510a854903509c828f67f96
FROM docker.io/library/golang:1.25.3@sha256:6d4e5e74f47db00f7f24da5f53c1b4198ae46862a47395e30477365458347bf2
ENV DEBIAN_FRONTEND=noninteractive

View File

@@ -123,6 +123,7 @@ k8s_resource(
'9345:2345',
'8083:8083'
],
resource_deps=['build']
)
# track crds
@@ -148,6 +149,7 @@ k8s_resource(
'9346:2345',
'8084:8084'
],
resource_deps=['build']
)
# track argocd-redis resources and port forward
@@ -162,6 +164,7 @@ k8s_resource(
port_forwards=[
'6379:6379',
],
resource_deps=['build']
)
# track argocd-applicationset-controller resources
@@ -180,6 +183,7 @@ k8s_resource(
'8085:8080',
'7000:7000'
],
resource_deps=['build']
)
# track argocd-application-controller resources
@@ -197,6 +201,7 @@ k8s_resource(
'9348:2345',
'8086:8082',
],
resource_deps=['build']
)
# track argocd-notifications-controller resources
@@ -214,6 +219,7 @@ k8s_resource(
'9349:2345',
'8087:9001',
],
resource_deps=['build']
)
# track argocd-dex-server resources
@@ -225,6 +231,7 @@ k8s_resource(
'argocd-dex-server:role',
'argocd-dex-server:rolebinding',
],
resource_deps=['build']
)
# track argocd-commit-server resources
@@ -239,6 +246,19 @@ k8s_resource(
'8088:8087',
'8089:8086',
],
resource_deps=['build']
)
# ui dependencies
local_resource(
'node-modules',
'yarn',
dir='ui',
deps = [
'ui/package.json',
'ui/yarn.lock',
],
allow_parallel=True,
)
# docker for ui
@@ -260,6 +280,7 @@ k8s_resource(
port_forwards=[
'4000:4000',
],
resource_deps=['node-modules'],
)
# linting
@@ -278,6 +299,7 @@ local_resource(
'ui',
],
allow_parallel=True,
resource_deps=['node-modules'],
)
local_resource(
@@ -287,5 +309,6 @@ local_resource(
'go.mod',
'go.sum',
],
allow_parallel=True,
)

View File

@@ -31,6 +31,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [ANSTO - Australian Synchrotron](https://www.synchrotron.org.au/)
1. [Ant Group](https://www.antgroup.com/)
1. [AppDirect](https://www.appdirect.com)
1. [Arcadia](https://www.arcadia.io)
1. [Arctiq Inc.](https://www.arctiq.ca)
1. [Artemis Health by Nomi Health](https://www.artemishealth.com/)
1. [Arturia](https://www.arturia.com)
@@ -86,6 +87,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Codefresh](https://www.codefresh.io/)
1. [Codility](https://www.codility.com/)
1. [Cognizant](https://www.cognizant.com/)
1. [Collins Aerospace](https://www.collinsaerospace.com/)
1. [Commonbond](https://commonbond.co/)
1. [Compatio.AI](https://compatio.ai/)
1. [Contlo](https://contlo.com/)
@@ -99,6 +101,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Datarisk](https://www.datarisk.io/)
1. [Daydream](https://daydream.ing)
1. [Deloitte](https://www.deloitte.com/)
1. [Dematic](https://www.dematic.com)
1. [Deutsche Telekom AG](https://telekom.com)
1. [Deutsche Bank AG](https://www.deutsche-bank.de/)
1. [Devopsi - Poland Software/DevOps Consulting](https://devopsi.pl/)
@@ -107,6 +110,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [DigitalOcean](https://www.digitalocean.com)
1. [Divar](https://divar.ir)
1. [Divistant](https://divistant.com)
2. [DocNetwork](https://docnetwork.org/)
1. [Dott](https://ridedott.com)
1. [Doubble](https://www.doubble.app)
1. [Doximity](https://www.doximity.com/)
@@ -121,6 +125,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [enigmo](https://enigmo.co.jp/)
1. [Envoy](https://envoy.com/)
1. [eSave](https://esave.es/)
1. [Expedia](https://www.expedia.com)
1. [Factorial](https://factorialhr.com/)
1. [Farfetch](https://www.farfetch.com)
1. [Faro](https://www.faro.com/)
@@ -181,6 +186,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Instruqt](https://www.instruqt.com)
1. [Intel](https://www.intel.com)
1. [Intuit](https://www.intuit.com/)
1. [IQVIA](https://www.iqvia.com/)
1. [Jellysmack](https://www.jellysmack.com)
1. [Joblift](https://joblift.com/)
1. [JovianX](https://www.jovianx.com/)
@@ -232,6 +238,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [mixi Group](https://mixi.co.jp/)
1. [Moengage](https://www.moengage.com/)
1. [Money Forward](https://corp.moneyforward.com/en/)
1. [MongoDB](https://www.mongodb.com/)
1. [MOO Print](https://www.moo.com/)
1. [Mozilla](https://www.mozilla.org)
1. [MTN Group](https://www.mtn.com/)
@@ -377,6 +384,7 @@ Currently, the following organizations are **officially** using Argo CD:
1. [Ticketmaster](https://ticketmaster.com)
1. [Tiger Analytics](https://www.tigeranalytics.com/)
1. [Tigera](https://www.tigera.io/)
1. [Topicus.Education](https://topicus.nl/en/sectors/education)
1. [Toss](https://toss.im/en)
1. [Trendyol](https://www.trendyol.com/)
1. [tru.ID](https://tru.id)

View File

@@ -232,6 +232,7 @@ registerAppViewExtension(
component: ExtensionComponent, // the component to be rendered
title: string, // the title of the page once the component is rendered
icon: string, // the favicon classname for the icon tab
shouldDisplay?: (app: Application): boolean // returns true if the view should be available
)
```
@@ -249,7 +250,10 @@ Below is an example of a simple extension:
window.extensionsAPI.registerAppViewExtension(
component,
"My Extension",
"fa-question-circle"
"fa-question-circle",
(app) =>
application.metadata?.labels?.["application.environmentLabelKey"] ===
"prd"
);
})(window);
```

View File

@@ -4,8 +4,6 @@
### Schedule
These are the upcoming releases dates:
| Release | Release Candidate 1 | General Availability | Release Champion | Release Approver | Checklist |
|---------|-----------------------|----------------------|---------------------------------------------------------|-------------------------------------------------------|---------------------------------------------------------------|
| v2.6 | Monday, Dec. 19, 2022 | Monday, Feb. 6, 2023 | [William Tam](https://github.com/wtam2018) | [William Tam](https://github.com/wtam2018) | [checklist](https://github.com/argoproj/argo-cd/issues/11563) |
@@ -17,10 +15,11 @@ These are the upcoming releases dates:
| v2.12 | Monday, Jun. 17, 2024 | Monday, Aug. 5, 2024 | [Ishita Sequeira](https://github.com/ishitasequeira) | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [checklist](https://github.com/argoproj/argo-cd/issues/19063) |
| v2.13 | Monday, Sep. 16, 2024 | Monday, Nov. 4, 2024 | [Regina Voloshin](https://github.com/reggie-k) | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [checklist](https://github.com/argoproj/argo-cd/issues/19513) |
| v2.14 | Monday, Dec. 16, 2024 | Monday, Feb. 3, 2025 | [Ryan Umstead](https://github.com/rumstead) | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [checklist](https://github.com/argoproj/argo-cd/issues/20869) |
| v3.0 | Monday, Mar. 17, 2025 | Tuesday, May 6, 2025 | [Regina Voloshin](https://github.com/reggie-k) | | [checklist](https://github.com/argoproj/argo-cd/issues/21735) |
| v3.0 | Monday, Mar. 17, 2025 | Tuesday, May 6, 2025 | [Regina Voloshin](https://github.com/reggie-k) | [Regina Voloshin](https://github.com/reggie-k) | [checklist](https://github.com/argoproj/argo-cd/issues/21735) |
| v3.1 | Monday, Jun. 16, 2025 | Monday, Aug. 4, 2025 | [Christian Hernandez](https://github.com/christianh814) | [Alexandre Gaudreault](https://github.com/agaudreault) | [checklist](#) |
| v3.2 | Monday, Sep. 15, 2025 | Monday, Nov. 3, 2025 | [Nitish Kumar](https://github.com/nitishfy) | | [checklist](#) |
| v3.3 | Monday, Dec. 15, 2025 | Monday, Feb. 2, 2026 | | |
| v3.4 | Monday, Apr. 6, 2026 | Monday, Jun. 1, 2026 | | |
Actual release dates might differ from the plan by a few days.

View File

@@ -1,12 +1,12 @@
# Progressive Syncs
> [!WARNING]
> **Alpha Feature (Since v2.6.0)**
> **Beta Feature (Since v2.6.0)**
>
This is an experimental, [alpha-quality](https://github.com/argoproj/argoproj/blob/main/community/feature-status.md#alpha)
feature that allows you to control the order in which the ApplicationSet controller will create or update the Applications
owned by an ApplicationSet resource. It may be removed in future releases or modified in backwards-incompatible ways.
This feature is in the [Beta](https://github.com/argoproj/argoproj/blob/main/community/feature-status.md#beta) stage. It is generally considered stable, but there may be unhandled edge cases.
This feature allows you to control the order in which the ApplicationSet controller will create or update the Applications
owned by an ApplicationSet resource.
## Use Cases

View File

@@ -123,6 +123,18 @@ spec:
...
```
### Deleting child applications
When working with the App of Apps pattern, you may need to delete individual child applications. Starting in 3.2, Argo CD provides consistent deletion behaviour whether you delete from the Applications List or from the parent application's Resource Tree.
For detailed information about deletion options and behaviour, including:
- Consistent deletion across UI views
- Non-cascading (orphan) deletion to preserve managed resources
- Child application detection and improved dialog messages
- Best practices and example scenarios
See [Deleting Applications in the UI](../user-guide/app_deletion.md#deleting-applications-in-the-ui).
### Ignoring differences in child applications
To allow changes in child apps without triggering an out-of-sync status, or modification for debugging etc, the app of apps pattern works with [diff customization](../user-guide/diffing/). The example below shows how to ignore changes to syncPolicy and other common values.

View File

@@ -17,7 +17,7 @@ to indicate their stability and maturity. These are the statuses of non-stable f
| Feature | Introduced | Status |
|-------------------------------------------|------------|--------|
| [AppSet Progressive Syncs][2] | v2.6.0 | Alpha |
| [AppSet Progressive Syncs][2] | v2.6.0 | Beta |
| [Proxy Extensions][3] | v2.7.0 | Beta |
| [Skip Application Reconcile][4] | v2.7.0 | Alpha |
| [AppSets in any Namespace][5] | v2.8.0 | Beta |

View File

@@ -0,0 +1,200 @@
# Managed By URL Annotation
## Overview
The `argocd.argoproj.io/managed-by-url` annotation allows an Application resource to specify which Argo CD instance manages it. This is useful when you have multiple Argo CD instances and need application links in the UI to point to the correct managing instance.
## Use Case
When using multiple Argo CD instances with the [app-of-apps pattern](cluster-bootstrapping.md):
- A primary Argo CD instance creates a parent Application
- The parent Application deploys child Applications that are managed by a secondary Argo CD instance
- Without the annotation, clicking on child Applications in the primary instance's UI tries to open them in the primary instance (incorrect)
- With the annotation, child Applications correctly open in the secondary instance
The `managed-by-url` annotation ensures application links redirect to the correct Argo CD instance.
> [!NOTE]
> This annotation is particularly useful in multi-tenant setups where different teams have their own Argo CD instances, or in hub-and-spoke architectures where a central instance manages multiple edge instances.
## Example
This example demonstrates the [app-of-apps pattern](cluster-bootstrapping.md) where a parent Application deploys child Applications from a Git repository.
### Step 1: Create Parent Application
Create a parent Application in your primary Argo CD instance:
```yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: parent-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/YOUR-ORG/my-apps-repo.git
targetRevision: main
path: path-to-child-app
destination:
server: https://kubernetes.default.svc
namespace: namespace-b
syncPolicy:
automated:
selfHeal: true
prune: true
```
### Step 2: Create Child Application in Git Repository
In your Git repository at `apps/child-apps/child-app.yaml`, add the `managed-by-url` annotation:
```yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: child-app
namespace: namespace-b
annotations:
argocd.argoproj.io/managed-by-url: "http://localhost:8081" # replace with actual secondary ArgoCD URL in real setup
spec:
project: default
source:
repoURL: https://github.com/YOUR-ORG/my-apps-repo.git
targetRevision: HEAD
path: path-to-child-app
destination:
server: https://kubernetes.default.svc
namespace: namespace-b
syncPolicy:
automated:
selfHeal: true
prune: true
```
### Result
When viewing the parent Application in the primary instance's UI:
- The parent Application syncs from Git and deploys the child Application
- Clicking on `child-app` in the resource tree navigates to `https://secondary-argocd.example.com/applications/namespace-b/child-app`
- The link opens the child Application in the correct Argo CD instance that actually manages it
## Configuration
### Annotation Format
| Field | Value |
|-------|-------|
| **Annotation** | `argocd.argoproj.io/managed-by-url` |
| **Target** | Application |
| **Value** | Valid HTTP(S) URL |
| **Required** | No |
### URL Validation
The annotation value **must** be a valid HTTP(S) URL:
-`https://argocd.example.com`
-`https://argocd.example.com:8080`
-`http://localhost:8080` (for development)
-`argocd.example.com` (missing protocol)
-`javascript:alert(1)` (invalid protocol)
Invalid URLs will prevent the Application from being created or updated.
### Behavior
When generating application links, Argo CD:
- **Without annotation**: Uses the current instance's base URL
- **With annotation**: Uses the URL from the annotation
- **Invalid annotation**: Falls back to the current instance's base URL and logs a warning
> [!WARNING]
> Ensure the URL in the annotation is accessible from users' browsers. For internal deployments, use internal DNS names or configure appropriate network access.
## Testing Locally
To test the annotation with two local Argo CD instances:
```bash
# Install primary instance
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Install secondary instance
kubectl create namespace namespace-b
kubectl apply -n namespace-b -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Port forward both instances
kubectl port-forward -n argocd svc/argocd-server 8080:443 &
kubectl port-forward -n namespace-b svc/argocd-server 8081:443 &
# Wait for Argo CD to be ready
kubectl wait --for=condition=available --timeout=300s deployment/argocd-server -n argocd
# Get the admin password for primary instance
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d && echo
```
Then:
1. Open `http://localhost:8080` in your browser
2. Login with username `admin` and the password from the command above
3. Navigate to the `parent-app` Application
4. Click on the `child-app` in the resource tree
5. It should redirect to `http://localhost:8081/applications/namespace-b/child-app`
You will need to repeat the command to get the password for the secondary instance to login and access the child-app
```bash
# Get the admin password for secondary instance
kubectl -n namespace-b get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d && echo
```
## Troubleshooting
### Links Still Point to Wrong Instance
**Check if the annotation is present:**
```bash
kubectl get application child-app -n instance-b -o jsonpath='{.metadata.annotations.argocd\.argoproj\.io/managed-by-url}'
```
Expected output: A complete URL like `http://localhost:8081` or the url that has been set
i.e `https://secondary-argocd.example.com`
**If the annotation is present but links still don't work:**
- Verify the URL is accessible from your browser
- Check browser console for errors
- Ensure the URL format is correct (includes `http://` or `https://`)
### Application Creation Fails
If Application creation fails with "invalid managed-by URL" error:
- ✅ URL includes protocol (`https://` or `http://`)
- ✅ URL contains no typos
- ✅ URL uses only valid characters
- ✅ URL is not a potentially malicious scheme (e.g., `javascript:`)
### Nested Applications Not Working
For app-of-apps patterns, ensure:
1. The child Application YAML in Git includes the annotation
2. The parent Application has synced successfully
3. The child Application has been created in the cluster
Verify the child Application exists:
```bash
kubectl get application CHILD-APP-NAME -n NAMESPACE
```
## See Also
- [Application Annotations](../user-guide/annotations-and-labels.md)
- [App of Apps Pattern](cluster-bootstrapping.md)
- [Deep Links](deep_links.md)

View File

@@ -11,6 +11,10 @@ The notification service is used to push events to [Alertmanager](https://github
* `basicAuth` - optional, server auth
* `bearerToken` - optional, server auth
* `timeout` - optional, the timeout in seconds used when sending alerts, default is "3 seconds"
* `maxIdleConns` - optional, maximum number of idle (keep-alive) connections across all hosts.
* `maxIdleConnsPerHost` - optional, maximum number of idle (keep-alive) connections per host.
* `maxConnsPerHost` - optional, maximum total connections per host.
* `idleConnTimeout` - optional, maximum amount of time an idle (keep-alive) connection will remain open before closing.
`basicAuth` or `bearerToken` is used for authentication, you can choose one. If the two are set at the same time, `basicAuth` takes precedence over `bearerToken`.

View File

@@ -8,6 +8,10 @@ The GitHub notification service changes commit status using [GitHub Apps](https:
- `installationID` - the app installation id
- `privateKey` - the app private key
- `enterpriseBaseURL` - optional URL, e.g. https://git.example.com/api/v3
- `maxIdleConns` - optional, maximum number of idle (keep-alive) connections across all hosts.
- `maxIdleConnsPerHost` - optional, maximum number of idle (keep-alive) connections per host.
- `maxConnsPerHost` - optional, maximum total connections per host.
- `idleConnTimeout` - optional, maximum amount of time an idle (keep-alive) connection will remain open before closing.
> ⚠️ _NOTE:_ Specifying `/api/v3` in the `enterpriseBaseURL` is required until [argoproj/notifications-engine#205](https://github.com/argoproj/notifications-engine/issues/205) is resolved.

View File

@@ -9,6 +9,10 @@ Available parameters :
* `apiURL` - the server url, e.g. https://grafana.example.com
* `apiKey` - the API key for the serviceaccount
* `insecureSkipVerify` - optional bool, true or false
* `maxIdleConns` - optional, maximum number of idle (keep-alive) connections across all hosts.
* `maxIdleConnsPerHost` - optional, maximum number of idle (keep-alive) connections per host.
* `maxConnsPerHost` - optional, maximum total connections per host.
* `idleConnTimeout` - optional, maximum amount of time an idle (keep-alive) connection will remain open before closing.
1. Login to your Grafana instance as `admin`
2. On the left menu, go to Configuration / API Keys

View File

@@ -5,6 +5,10 @@
* `apiURL` - the server url, e.g. https://mattermost.example.com
* `token` - the bot token
* `insecureSkipVerify` - optional bool, true or false
* `maxIdleConns` - optional, maximum number of idle (keep-alive) connections across all hosts.
* `maxIdleConnsPerHost` - optional, maximum number of idle (keep-alive) connections per host.
* `maxConnsPerHost` - optional, maximum total connections per host.
* `idleConnTimeout` - optional, maximum amount of time an idle (keep-alive) connection will remain open before closing, e.g. '90s'.
## Configuration

View File

@@ -4,6 +4,10 @@
* `apiURL` - the api server url, e.g. https://api.newrelic.com
* `apiKey` - a [NewRelic ApiKey](https://docs.newrelic.com/docs/apis/rest-api-v2/get-started/introduction-new-relic-rest-api-v2/#api_key)
* `maxIdleConns` - optional, maximum number of idle (keep-alive) connections across all hosts.
* `maxIdleConnsPerHost` - optional, maximum number of idle (keep-alive) connections per host.
* `maxConnsPerHost` - optional, maximum total connections per host.
* `idleConnTimeout` - optional, maximum amount of time an idle (keep-alive) connection will remain open before closing, e.g. '90s'.
## Configuration

View File

@@ -16,6 +16,11 @@ The Slack notification service configuration includes following settings:
| `token` | **True** | `string` | The app's OAuth access token. | `xoxb-1234567890-1234567890123-5n38u5ed63fgzqlvuyxvxcx6` |
| `username` | False | `string` | The app username. | `argocd` |
| `disableUnfurl` | False | `bool` | Disable slack unfurling links in messages | `true` |
| `maxIdleConns` | False | `int` | Maximum number of idle (keep-alive) connections across all hosts. | — |
| `maxIdleConnsPerHost` | False | `int` | Maximum number of idle (keep-alive) connections per host. | — |
| `maxConnsPerHost` | False | `int` | Maximum total connections per host. | — |
| `idleConnTimeout` | False | `string` | Maximum amount of time an idle (keep-alive) connection will remain open before closing (e.g., `90s`). | — |
## Configuration

View File

@@ -14,6 +14,10 @@ The Webhook notification service configuration includes following settings:
- `retryWaitMin` - Optional, the minimum wait time between retries. Default value: 1s.
- `retryWaitMax` - Optional, the maximum wait time between retries. Default value: 5s.
- `retryMax` - Optional, the maximum number of retries. Default value: 3.
- `maxIdleConns` - optional, maximum number of idle (keep-alive) connections across all hosts.
- `maxIdleConnsPerHost` - optional, maximum number of idle (keep-alive) connections per host.
- `maxConnsPerHost` - optional, maximum total connections per host.
- `idleConnTimeout` - optional, maximum amount of time an idle (keep-alive) connection will remain open before closing, e.g. '90s'.
## Retry Behavior

View File

@@ -1,5 +1,7 @@
# v3.1 to 3.2
> Users operating large monorepos may encounter repo-server lock contention requiring pod restarts. A [fix](https://github.com/argoproj/argo-cd/pull/25127) is under review and will be included in the next patch release.
## Breaking Changes
### Hydration paths must now be non-root

View File

@@ -67,6 +67,7 @@ data:
issuer: https://keycloak.example.com/realms/master
clientID: argocd
clientSecret: $oidc.keycloak.clientSecret
refreshTokenThreshold: 2m
requestedScopes: ["openid", "profile", "email", "groups"]
```
@@ -77,6 +78,7 @@ Make sure that:
- __clientID__ is set to the Client ID you configured in Keycloak
- __clientSecret__ points to the right key you created in the _argocd-secret_ Secret
- __requestedScopes__ contains the _groups_ claim if you didn't add it to the Default scopes
- __refreshTokenThreshold__ is less than the client token lifetime. If this setting is not less than the token lifetime, a new token will be obtained for every request. Keycloak sets the client token lifetime to 5 minutes by default.
## Keycloak and ArgoCD with PKCE
@@ -135,6 +137,7 @@ data:
issuer: https://keycloak.example.com/realms/master
clientID: argocd
enablePKCEAuthentication: true
refreshTokenThreshold: 2m
requestedScopes: ["openid", "profile", "email", "groups"]
```
@@ -145,6 +148,7 @@ Make sure that:
- __clientID__ is set to the Client ID you configured in Keycloak
- __enablePKCEAuthentication__ must be set to true to enable correct ArgoCD behaviour with PKCE
- __requestedScopes__ contains the _groups_ claim if you didn't add it to the Default scopes
- __refreshTokenThreshold__ is less than the client token lifetime. If this setting is not less than the token lifetime, a new token will be obtained for every request. Keycloak sets the client token lifetime to 5 minutes by default.
## Configuring the groups claim

View File

@@ -18,7 +18,7 @@ recent minor releases.
| [dex:v2.43.0](master/ghcr.io_dexidp_dex_v2.43.0.html) | 0 | 0 | 0 | 3 |
| [haproxy:3.0.8-alpine](master/public.ecr.aws_docker_library_haproxy_3.0.8-alpine.html) | 0 | 0 | 0 | 3 |
| [redis:8.2.1-alpine](master/public.ecr.aws_docker_library_redis_8.2.1-alpine.html) | 0 | 0 | 0 | 3 |
| [argocd:latest](master/quay.io_argoproj_argocd_latest.html) | 0 | 0 | 3 | 9 |
| [argocd:latest](master/quay.io_argoproj_argocd_latest.html) | 0 | 0 | 4 | 9 |
| [install.yaml](master/argocd-iac-install.html) | - | - | - | - |
| [namespace-install.yaml](master/argocd-iac-namespace-install.html) | - | - | - | - |
@@ -27,11 +27,11 @@ recent minor releases.
| | Critical | High | Medium | Low |
|---:|:--------:|:----:|:------:|:---:|
| [go.mod](v3.2.0-rc4/argocd-test.html) | 0 | 1 | 5 | 0 |
| [ui/yarn.lock](v3.2.0-rc4/argocd-test.html) | 0 | 0 | 2 | 2 |
| [ui/yarn.lock](v3.2.0-rc4/argocd-test.html) | 0 | 0 | 3 | 2 |
| [dex:v2.43.0](v3.2.0-rc4/ghcr.io_dexidp_dex_v2.43.0.html) | 0 | 0 | 0 | 3 |
| [haproxy:3.0.8-alpine](v3.2.0-rc4/public.ecr.aws_docker_library_haproxy_3.0.8-alpine.html) | 0 | 0 | 0 | 3 |
| [redis:8.2.2-alpine](v3.2.0-rc4/public.ecr.aws_docker_library_redis_8.2.2-alpine.html) | 0 | 0 | 0 | 0 |
| [argocd:v3.2.0-rc4](v3.2.0-rc4/quay.io_argoproj_argocd_v3.2.0-rc4.html) | 0 | 0 | 3 | 9 |
| [argocd:v3.2.0-rc4](v3.2.0-rc4/quay.io_argoproj_argocd_v3.2.0-rc4.html) | 0 | 0 | 4 | 9 |
| [install.yaml](v3.2.0-rc4/argocd-iac-install.html) | - | - | - | - |
| [namespace-install.yaml](v3.2.0-rc4/argocd-iac-namespace-install.html) | - | - | - | - |
@@ -40,7 +40,7 @@ recent minor releases.
| | Critical | High | Medium | Low |
|---:|:--------:|:----:|:------:|:---:|
| [go.mod](v3.1.9/argocd-test.html) | 0 | 1 | 5 | 0 |
| [ui/yarn.lock](v3.1.9/argocd-test.html) | 1 | 0 | 2 | 2 |
| [ui/yarn.lock](v3.1.9/argocd-test.html) | 1 | 0 | 3 | 2 |
| [dex:v2.43.0](v3.1.9/ghcr.io_dexidp_dex_v2.43.0.html) | 0 | 0 | 0 | 3 |
| [haproxy:3.0.8-alpine](v3.1.9/public.ecr.aws_docker_library_haproxy_3.0.8-alpine.html) | 0 | 0 | 0 | 3 |
| [redis:7.2.11-alpine](v3.1.9/public.ecr.aws_docker_library_redis_7.2.11-alpine.html) | 0 | 0 | 0 | 0 |
@@ -53,7 +53,7 @@ recent minor releases.
| | Critical | High | Medium | Low |
|---:|:--------:|:----:|:------:|:---:|
| [go.mod](v3.0.20/argocd-test.html) | 0 | 4 | 5 | 0 |
| [ui/yarn.lock](v3.0.20/argocd-test.html) | 1 | 1 | 3 | 4 |
| [ui/yarn.lock](v3.0.20/argocd-test.html) | 1 | 1 | 4 | 4 |
| [dex:v2.41.1](v3.0.20/ghcr.io_dexidp_dex_v2.41.1.html) | 0 | 1 | 0 | 7 |
| [haproxy:3.0.8-alpine](v3.0.20/public.ecr.aws_docker_library_haproxy_3.0.8-alpine.html) | 0 | 0 | 0 | 3 |
| [redis:7.2.11-alpine](v3.0.20/public.ecr.aws_docker_library_redis_7.2.11-alpine.html) | 0 | 0 | 0 | 0 |
@@ -62,16 +62,16 @@ recent minor releases.
| [install.yaml](v3.0.20/argocd-iac-install.html) | - | - | - | - |
| [namespace-install.yaml](v3.0.20/argocd-iac-namespace-install.html) | - | - | - | - |
### v2.14.20
### v2.14.21
| | Critical | High | Medium | Low |
|---:|:--------:|:----:|:------:|:---:|
| [go.mod](v2.14.20/argocd-test.html) | 0 | 2 | 8 | 0 |
| [ui/yarn.lock](v2.14.20/argocd-test.html) | 1 | 0 | 3 | 3 |
| [dex:v2.41.1](v2.14.20/ghcr.io_dexidp_dex_v2.41.1.html) | 0 | 1 | 0 | 7 |
| [haproxy:2.6.17-alpine](v2.14.20/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html) | 0 | 1 | 2 | 9 |
| [redis:7.0.15-alpine](v2.14.20/public.ecr.aws_docker_library_redis_7.0.15-alpine.html) | 0 | 0 | 0 | 7 |
| [argocd:v2.14.20](v2.14.20/quay.io_argoproj_argocd_v2.14.20.html) | 0 | 0 | 4 | 12 |
| [redis:7.0.15-alpine](v2.14.20/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 7 |
| [install.yaml](v2.14.20/argocd-iac-install.html) | - | - | - | - |
| [namespace-install.yaml](v2.14.20/argocd-iac-namespace-install.html) | - | - | - | - |
| [go.mod](v2.14.21/argocd-test.html) | 0 | 2 | 8 | 0 |
| [ui/yarn.lock](v2.14.21/argocd-test.html) | 1 | 0 | 4 | 3 |
| [dex:v2.41.1](v2.14.21/ghcr.io_dexidp_dex_v2.41.1.html) | 0 | 1 | 0 | 7 |
| [haproxy:2.6.17-alpine](v2.14.21/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html) | 0 | 1 | 2 | 9 |
| [redis:7.2.11-alpine](v2.14.21/public.ecr.aws_docker_library_redis_7.2.11-alpine.html) | 0 | 0 | 0 | 0 |
| [argocd:v2.14.21](v2.14.21/quay.io_argoproj_argocd_v2.14.21.html) | 0 | 0 | 3 | 11 |
| [redis:7.2.11-alpine](v2.14.21/redis_7.2.11-alpine.html) | 0 | 0 | 0 | 0 |
| [install.yaml](v2.14.21/argocd-iac-install.html) | - | - | - | - |
| [namespace-install.yaml](v2.14.21/argocd-iac-namespace-install.html) | - | - | - | - |

View File

@@ -456,7 +456,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:24:10 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:24:51 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following path:</span>

View File

@@ -456,7 +456,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:24:21 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:25:01 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following path:</span>

View File

@@ -7,7 +7,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Snyk test report</title>
<meta name="description" content="9 known vulnerabilities found in 29 vulnerable dependency paths.">
<meta name="description" content="9 known vulnerabilities found in 30 vulnerable dependency paths.">
<base target="_blank">
<link rel="icon" type="image/png" href="https://res.cloudinary.com/snyk/image/upload/v1468845142/favicon/favicon.png"
sizes="194x194">
@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:22:06 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:22:41 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following paths:</span>
@@ -501,8 +501,8 @@
<div class="meta-counts">
<div class="meta-count"><span>9</span> <span>known vulnerabilities</span></div>
<div class="meta-count"><span>29 vulnerable dependency paths</span></div>
<div class="meta-count"><span>2854</span> <span>dependencies</span></div>
<div class="meta-count"><span>30 vulnerable dependency paths</span></div>
<div class="meta-count"><span>2868</span> <span>dependencies</span></div>
</div><!-- .meta-counts -->
</div><!-- .layout-container--short -->
</header><!-- .project__header -->
@@ -532,13 +532,13 @@
<li class="card__meta__item">
Vulnerable module:
min-document
js-yaml
</li>
<li class="card__meta__item">Introduced through:
argo-cd-ui@1.0.0 and js-yaml@4.1.0
argo-cd-ui@1.0.0, react-hot-loader@3.1.3 and others
</li>
</ul>
@@ -552,11 +552,20 @@
<span class="list-paths__item__introduced"><em>Introduced through</em>:
argo-cd-ui@1.0.0
<span class="list-paths__item__arrow"></span>
react-hot-loader@3.1.3
js-yaml@4.1.0
</span>
</li>
<li>
<span class="list-paths__item__introduced"><em>Introduced through</em>:
argo-cd-ui@1.0.0
<span class="list-paths__item__arrow"></span>
global@4.4.0
redoc@2.4.0
<span class="list-paths__item__arrow"></span>
min-document@2.19.0
@redocly/openapi-core@1.30.0
<span class="list-paths__item__arrow"></span>
js-yaml@4.1.0
</span>
@@ -568,9 +577,10 @@
<hr/>
<!-- Overview -->
<h2 id="overview">Overview</h2>
<p>Affected versions of this package are vulnerable to Prototype Pollution via the <code>removeAttributeNS</code> function. An attacker can manipulate the prototype chain of JavaScript objects, potentially causing a denial-of-service attack by supplying malicious input that targets the <code>__proto__</code> property during namespace attribute removal.</p>
<p><strong>Notes</strong>:</p>
<p>This vulnerability is only exploitable if user input is passed without sanitization to the affected functions. The PoC has been validated as a theoretical vector, and a fixed version has been released.</p>
<p><a href="https://www.npmjs.com/package/js-yaml">js-yaml</a> is a human-friendly data serialization language.</p>
<p>Affected versions of this package are vulnerable to Prototype Pollution via the <code>merge</code> function. An attacker can alter object prototypes by supplying specially crafted YAML documents containing <code>__proto__</code> properties. This can lead to unexpected behavior or security issues in applications that process untrusted YAML input.</p>
<h2 id="workaround">Workaround</h2>
<p>This vulnerability can be mitigated by running the server with <code>node --disable-proto=delete</code> or by using Deno, which has pollution protection enabled by default.</p>
<h2 id="details">Details</h2>
<p>Prototype Pollution is a vulnerability affecting JavaScript. Prototype Pollution refers to the ability to inject properties into existing JavaScript language construct prototypes, such as objects. JavaScript allows all Object attributes to be altered, including their magical attributes such as <code>__proto__</code>, <code>constructor</code> and <code>prototype</code>. An attacker manipulates these attributes to overwrite, or pollute, a JavaScript application object prototype of the base object by injecting other values. Properties on the <code>Object.prototype</code> are then inherited by all the JavaScript objects through the prototype chain. When that happens, this leads to either denial of service by triggering JavaScript exceptions, or it tampers with the application source code to force the code path that the attacker injects, thereby leading to remote code execution.</p>
<p>There are two main ways in which the pollution of prototypes occurs:</p>
@@ -654,19 +664,16 @@
<h3 id="for-more-information-on-this-vulnerability-type">For more information on this vulnerability type:</h3>
<p><a href="https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript_prototype_pollution_attack_in_NodeJS.pdf">Arteau, Oliver. “JavaScript prototype pollution attack in NodeJS application.” GitHub, 26 May 2018</a></p>
<h2 id="remediation">Remediation</h2>
<p>There is no fixed version for <code>min-document</code>.</p>
<p>Upgrade <code>js-yaml</code> to version 4.1.1 or higher.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="https://github.com/Raynos/min-document/pull/55/commits/0d4e8192ef723fb869645256102a56ed922efd68">Github Commit</a></li>
<li><a href="https://github.com/Raynos/min-document/issues/54">GitHub Issue</a></li>
<li><a href="https://github.com/OrangeShieldInfos/PoCs/tree/main/JavaScript/prototype-pollution/CVE-2025-57352">POC</a></li>
<li><a href="https://github.com/Raynos/min-document/blob/bf7b69130a364b5c6fcb8e623bffe43054994c65/dom-element.js#L129">Vulnerable Code</a></li>
<li><a href="https://github.com/nodeca/js-yaml/commit/383665ff4248ec2192d1274e934462bb30426879">GitHub Commit</a></li>
</ul>
<hr/>
<div class="cta card__cta">
<p><a href="https://snyk.io/vuln/SNYK-JS-MINDOCUMENT-13045385">More about this vulnerability</a></p>
<p><a href="https://snyk.io/vuln/SNYK-JS-JSYAML-13961110">More about this vulnerability</a></p>
</div>
</div><!-- .card -->
@@ -760,7 +767,7 @@
<li class="card__meta__item">Introduced through:
github.com/argoproj/argo-cd/v3@0.0.0, code.gitea.io/sdk/gitea@0.22.0 and others
github.com/argoproj/argo-cd/v3@0.0.0, code.gitea.io/sdk/gitea@0.22.1 and others
</li>
</ul>
@@ -774,7 +781,7 @@
<span class="list-paths__item__introduced"><em>Introduced through</em>:
github.com/argoproj/argo-cd/v3@0.0.0
<span class="list-paths__item__arrow"></span>
code.gitea.io/sdk/gitea@0.22.0
code.gitea.io/sdk/gitea@0.22.1
<span class="list-paths__item__arrow"></span>
github.com/hashicorp/go-version@1.7.0
@@ -847,7 +854,7 @@
<span class="list-paths__item__introduced"><em>Introduced through</em>:
github.com/argoproj/argo-cd/v3@0.0.0
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/services@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/services@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/hashicorp/go-retryablehttp@0.7.8
@@ -858,7 +865,7 @@
<span class="list-paths__item__introduced"><em>Introduced through</em>:
github.com/argoproj/argo-cd/v3@0.0.0
<span class="list-paths__item__arrow"></span>
gitlab.com/gitlab-org/api/client-go@0.157.1
gitlab.com/gitlab-org/api/client-go@0.160.0
<span class="list-paths__item__arrow"></span>
github.com/hashicorp/go-retryablehttp@0.7.8
@@ -869,9 +876,9 @@
<span class="list-paths__item__introduced"><em>Introduced through</em>:
github.com/argoproj/argo-cd/v3@0.0.0
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/subscriptions@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/subscriptions@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/services@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/services@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/hashicorp/go-retryablehttp@0.7.8
@@ -882,9 +889,9 @@
<span class="list-paths__item__introduced"><em>Introduced through</em>:
github.com/argoproj/argo-cd/v3@0.0.0
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/cmd@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/cmd@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/services@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/services@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/hashicorp/go-retryablehttp@0.7.8
@@ -895,7 +902,7 @@
<span class="list-paths__item__introduced"><em>Introduced through</em>:
github.com/argoproj/argo-cd/v3@0.0.0
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/services@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/services@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/opsgenie/opsgenie-go-sdk-v2/client@1.2.23
<span class="list-paths__item__arrow"></span>
@@ -908,11 +915,11 @@
<span class="list-paths__item__introduced"><em>Introduced through</em>:
github.com/argoproj/argo-cd/v3@0.0.0
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/api@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/api@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/subscriptions@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/subscriptions@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/services@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/services@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/hashicorp/go-retryablehttp@0.7.8
@@ -923,11 +930,11 @@
<span class="list-paths__item__introduced"><em>Introduced through</em>:
github.com/argoproj/argo-cd/v3@0.0.0
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/controller@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/controller@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/subscriptions@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/subscriptions@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/services@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/services@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/hashicorp/go-retryablehttp@0.7.8
@@ -938,9 +945,9 @@
<span class="list-paths__item__introduced"><em>Introduced through</em>:
github.com/argoproj/argo-cd/v3@0.0.0
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/subscriptions@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/subscriptions@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/services@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/services@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/opsgenie/opsgenie-go-sdk-v2/client@1.2.23
<span class="list-paths__item__arrow"></span>
@@ -953,9 +960,9 @@
<span class="list-paths__item__introduced"><em>Introduced through</em>:
github.com/argoproj/argo-cd/v3@0.0.0
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/cmd@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/cmd@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/services@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/services@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/opsgenie/opsgenie-go-sdk-v2/client@1.2.23
<span class="list-paths__item__arrow"></span>
@@ -968,11 +975,11 @@
<span class="list-paths__item__introduced"><em>Introduced through</em>:
github.com/argoproj/argo-cd/v3@0.0.0
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/api@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/api@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/subscriptions@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/subscriptions@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/services@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/services@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/opsgenie/opsgenie-go-sdk-v2/client@1.2.23
<span class="list-paths__item__arrow"></span>
@@ -985,11 +992,11 @@
<span class="list-paths__item__introduced"><em>Introduced through</em>:
github.com/argoproj/argo-cd/v3@0.0.0
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/controller@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/controller@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/subscriptions@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/subscriptions@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/services@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/services@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/opsgenie/opsgenie-go-sdk-v2/client@1.2.23
<span class="list-paths__item__arrow"></span>
@@ -1066,7 +1073,7 @@
<span class="list-paths__item__introduced"><em>Introduced through</em>:
github.com/argoproj/argo-cd/v3@0.0.0
<span class="list-paths__item__arrow"></span>
gitlab.com/gitlab-org/api/client-go@0.157.1
gitlab.com/gitlab-org/api/client-go@0.160.0
<span class="list-paths__item__arrow"></span>
github.com/hashicorp/go-cleanhttp@0.5.2
@@ -1077,7 +1084,7 @@
<span class="list-paths__item__introduced"><em>Introduced through</em>:
github.com/argoproj/argo-cd/v3@0.0.0
<span class="list-paths__item__arrow"></span>
gitlab.com/gitlab-org/api/client-go@0.157.1
gitlab.com/gitlab-org/api/client-go@0.160.0
<span class="list-paths__item__arrow"></span>
github.com/hashicorp/go-retryablehttp@0.7.8
<span class="list-paths__item__arrow"></span>
@@ -1090,7 +1097,7 @@
<span class="list-paths__item__introduced"><em>Introduced through</em>:
github.com/argoproj/argo-cd/v3@0.0.0
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/services@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/services@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/opsgenie/opsgenie-go-sdk-v2/client@1.2.23
<span class="list-paths__item__arrow"></span>
@@ -1105,9 +1112,9 @@
<span class="list-paths__item__introduced"><em>Introduced through</em>:
github.com/argoproj/argo-cd/v3@0.0.0
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/subscriptions@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/subscriptions@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/services@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/services@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/opsgenie/opsgenie-go-sdk-v2/client@1.2.23
<span class="list-paths__item__arrow"></span>
@@ -1122,9 +1129,9 @@
<span class="list-paths__item__introduced"><em>Introduced through</em>:
github.com/argoproj/argo-cd/v3@0.0.0
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/cmd@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/cmd@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/services@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/services@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/opsgenie/opsgenie-go-sdk-v2/client@1.2.23
<span class="list-paths__item__arrow"></span>
@@ -1139,11 +1146,11 @@
<span class="list-paths__item__introduced"><em>Introduced through</em>:
github.com/argoproj/argo-cd/v3@0.0.0
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/api@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/api@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/subscriptions@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/subscriptions@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/services@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/services@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/opsgenie/opsgenie-go-sdk-v2/client@1.2.23
<span class="list-paths__item__arrow"></span>
@@ -1158,11 +1165,11 @@
<span class="list-paths__item__introduced"><em>Introduced through</em>:
github.com/argoproj/argo-cd/v3@0.0.0
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/controller@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/controller@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/subscriptions@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/subscriptions@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/argoproj/notifications-engine/pkg/services@#58cdc54685b4
github.com/argoproj/notifications-engine/pkg/services@#783b97d496ca
<span class="list-paths__item__arrow"></span>
github.com/opsgenie/opsgenie-go-sdk-v2/client@1.2.23
<span class="list-paths__item__arrow"></span>

View File

@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:22:16 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:22:53 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following paths:</span>
@@ -2429,6 +2429,8 @@
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/c2b96348bfa662f25f4fabf81958ae822063dae3">https://github.openssl.org/openssl/extended-releases/commit/c2b96348bfa662f25f4fabf81958ae822063dae3</a></li>
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/dfbaf161d8dafc1132dd88cd48ad990ed9b4c8ba">https://github.openssl.org/openssl/extended-releases/commit/dfbaf161d8dafc1132dd88cd48ad990ed9b4c8ba</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2025/10/msg00001.html">https://lists.debian.org/debian-lts-announce/2025/10/msg00001.html</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -2581,6 +2583,7 @@
<li><a href="https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4">https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4</a></li>
<li><a href="https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2">https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -2738,6 +2741,7 @@
<li><a href="https://github.com/openssl/openssl/commit/89e790ac431125a4849992858490bed6b225eadf">https://github.com/openssl/openssl/commit/89e790ac431125a4849992858490bed6b225eadf</a></li>
<li><a href="https://github.com/openssl/openssl/commit/bbf38c034cdabd0a13330abcc4855c866f53d2e0">https://github.com/openssl/openssl/commit/bbf38c034cdabd0a13330abcc4855c866f53d2e0</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>

View File

@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:22:22 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:23:04 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following path:</span>
@@ -694,6 +694,8 @@
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/c2b96348bfa662f25f4fabf81958ae822063dae3">https://github.openssl.org/openssl/extended-releases/commit/c2b96348bfa662f25f4fabf81958ae822063dae3</a></li>
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/dfbaf161d8dafc1132dd88cd48ad990ed9b4c8ba">https://github.openssl.org/openssl/extended-releases/commit/dfbaf161d8dafc1132dd88cd48ad990ed9b4c8ba</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2025/10/msg00001.html">https://lists.debian.org/debian-lts-announce/2025/10/msg00001.html</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -879,6 +881,7 @@
<li><a href="https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4">https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4</a></li>
<li><a href="https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2">https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -1069,6 +1072,7 @@
<li><a href="https://github.com/openssl/openssl/commit/89e790ac431125a4849992858490bed6b225eadf">https://github.com/openssl/openssl/commit/89e790ac431125a4849992858490bed6b225eadf</a></li>
<li><a href="https://github.com/openssl/openssl/commit/bbf38c034cdabd0a13330abcc4855c866f53d2e0">https://github.com/openssl/openssl/commit/bbf38c034cdabd0a13330abcc4855c866f53d2e0</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>

View File

@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:22:29 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:23:11 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following path:</span>
@@ -701,6 +701,7 @@
<li><a href="https://github.com/openssl/openssl/commit/89e790ac431125a4849992858490bed6b225eadf">https://github.com/openssl/openssl/commit/89e790ac431125a4849992858490bed6b225eadf</a></li>
<li><a href="https://github.com/openssl/openssl/commit/bbf38c034cdabd0a13330abcc4855c866f53d2e0">https://github.com/openssl/openssl/commit/bbf38c034cdabd0a13330abcc4855c866f53d2e0</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -892,6 +893,8 @@
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/c2b96348bfa662f25f4fabf81958ae822063dae3">https://github.openssl.org/openssl/extended-releases/commit/c2b96348bfa662f25f4fabf81958ae822063dae3</a></li>
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/dfbaf161d8dafc1132dd88cd48ad990ed9b4c8ba">https://github.openssl.org/openssl/extended-releases/commit/dfbaf161d8dafc1132dd88cd48ad990ed9b4c8ba</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2025/10/msg00001.html">https://lists.debian.org/debian-lts-announce/2025/10/msg00001.html</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -1081,6 +1084,7 @@
<li><a href="https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4">https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4</a></li>
<li><a href="https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2">https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>

View File

@@ -7,7 +7,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Snyk test report</title>
<meta name="description" content="18 known vulnerabilities found in 54 vulnerable dependency paths.">
<meta name="description" content="19 known vulnerabilities found in 55 vulnerable dependency paths.">
<base target="_blank">
<link rel="icon" type="image/png" href="https://res.cloudinary.com/snyk/image/upload/v1468845142/favicon/favicon.png"
sizes="194x194">
@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:22:51 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:23:32 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following paths:</span>
@@ -501,9 +501,9 @@
</div>
<div class="meta-counts">
<div class="meta-count"><span>18</span> <span>known vulnerabilities</span></div>
<div class="meta-count"><span>54 vulnerable dependency paths</span></div>
<div class="meta-count"><span>2312</span> <span>dependencies</span></div>
<div class="meta-count"><span>19</span> <span>known vulnerabilities</span></div>
<div class="meta-count"><span>55 vulnerable dependency paths</span></div>
<div class="meta-count"><span>2318</span> <span>dependencies</span></div>
</div><!-- .meta-counts -->
</div><!-- .layout-container--short -->
</header><!-- .project__header -->
@@ -589,6 +589,7 @@
<li><a href="https://lists.gnu.org/archive/html/bug-tar/2025-08/msg00012.html">https://lists.gnu.org/archive/html/bug-tar/2025-08/msg00012.html</a></li>
<li><a href="https://www.gnu.org/software/tar/manual/html_node/Integrity.html">https://www.gnu.org/software/tar/manual/html_node/Integrity.html</a></li>
<li><a href="https://www.gnu.org/software/tar/manual/html_node/Security-rules-of-thumb.html">https://www.gnu.org/software/tar/manual/html_node/Security-rules-of-thumb.html</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/11/01/6">http://www.openwall.com/lists/oss-security/2025/11/01/6</a></li>
</ul>
<hr/>
@@ -864,6 +865,7 @@
<li><a href="https://access.redhat.com/errata/RHSA-2025:15827">https://access.redhat.com/errata/RHSA-2025:15827</a></li>
<li><a href="https://access.redhat.com/errata/RHSA-2025:16524">https://access.redhat.com/errata/RHSA-2025:16524</a></li>
<li><a href="https://access.redhat.com/errata/RHSA-2025:18219">https://access.redhat.com/errata/RHSA-2025:18219</a></li>
<li><a href="https://access.redhat.com/errata/RHSA-2025:17181">https://access.redhat.com/errata/RHSA-2025:17181</a></li>
</ul>
<hr/>
@@ -1339,6 +1341,77 @@
<p><a href="https://snyk.io/vuln/SNYK-UBUNTU2504-GIT-9792199">More about this vulnerability</a></p>
</div>
</div><!-- .card -->
<div class="card card--vuln disclosure--not-new severity--medium" data-snyk-test="medium">
<h2 class="card__title">CVE-2025-11563</h2>
<div class="card__section">
<div class="card__labels">
<div class="label label--medium">
<span class="label__text">medium severity</span>
</div>
</div>
<hr/>
<ul class="card__meta">
<li class="card__meta__item">
Manifest file: quay.io/argoproj/argocd:latest/argoproj/argocd <span class="list-paths__item__arrow"></span> Dockerfile
</li>
<li class="card__meta__item">
Package Manager: ubuntu:25.04
</li>
<li class="card__meta__item">
Vulnerable module:
curl/libcurl3t64-gnutls
</li>
<li class="card__meta__item">Introduced through:
docker-image|quay.io/argoproj/argocd@latest, git@1:2.48.1-0ubuntu1.1 and others
</li>
</ul>
<hr/>
<h3 class="card__section__title">Detailed paths</h3>
<ul class="card__meta__paths">
<li>
<span class="list-paths__item__introduced"><em>Introduced through</em>:
docker-image|quay.io/argoproj/argocd@latest
<span class="list-paths__item__arrow"></span>
git@1:2.48.1-0ubuntu1.1
<span class="list-paths__item__arrow"></span>
curl/libcurl3t64-gnutls@8.12.1-3ubuntu1
</span>
</li>
</ul><!-- .list-paths -->
</div><!-- .card__section -->
<hr/>
<!-- Overview -->
<h2 id="nvd-description">NVD Description</h2>
<p><em>This vulnerability has not been analyzed by NVD yet.</em></p>
<h2 id="remediation">Remediation</h2>
<p>There is no fixed version for <code>Ubuntu:25.04</code> <code>curl</code>.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="http://people.ubuntu.com/~ubuntu-security/cve/CVE-2025-11563">http://people.ubuntu.com/~ubuntu-security/cve/CVE-2025-11563</a></li>
</ul>
<hr/>
<div class="cta card__cta">
<p><a href="https://snyk.io/vuln/SNYK-UBUNTU2504-CURL-13842495">More about this vulnerability</a></p>
</div>
</div><!-- .card -->
<div class="card card--vuln disclosure--not-new severity--low" data-snyk-test="low">
<h2 class="card__title">CVE-2024-56433</h2>
@@ -2071,6 +2144,7 @@
<li><a href="https://curl.se/docs/CVE-2025-9086.html">https://curl.se/docs/CVE-2025-9086.html</a></li>
<li><a href="https://curl.se/docs/CVE-2025-9086.json">https://curl.se/docs/CVE-2025-9086.json</a></li>
<li><a href="https://hackerone.com/reports/3294999">https://hackerone.com/reports/3294999</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/10/1">http://www.openwall.com/lists/oss-security/2025/09/10/1</a></li>
</ul>
<hr/>
@@ -2154,6 +2228,8 @@
<li><a href="https://curl.se/docs/CVE-2025-10148.html">https://curl.se/docs/CVE-2025-10148.html</a></li>
<li><a href="https://curl.se/docs/CVE-2025-10148.json">https://curl.se/docs/CVE-2025-10148.json</a></li>
<li><a href="https://hackerone.com/reports/3330839">https://hackerone.com/reports/3330839</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/10/2">http://www.openwall.com/lists/oss-security/2025/09/10/2</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/10/3">http://www.openwall.com/lists/oss-security/2025/09/10/3</a></li>
</ul>
<hr/>

File diff suppressed because it is too large Load Diff

View File

@@ -456,7 +456,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:34:18 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:35:15 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following path:</span>

View File

@@ -456,7 +456,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:34:28 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:35:25 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following path:</span>

View File

@@ -7,7 +7,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Snyk test report</title>
<meta name="description" content="17 known vulnerabilities found in 65 vulnerable dependency paths.">
<meta name="description" content="18 known vulnerabilities found in 67 vulnerable dependency paths.">
<base target="_blank">
<link rel="icon" type="image/png" href="https://res.cloudinary.com/snyk/image/upload/v1468845142/favicon/favicon.png"
sizes="194x194">
@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:32:11 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:32:49 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following paths:</span>
@@ -499,8 +499,8 @@
</div>
<div class="meta-counts">
<div class="meta-count"><span>17</span> <span>known vulnerabilities</span></div>
<div class="meta-count"><span>65 vulnerable dependency paths</span></div>
<div class="meta-count"><span>18</span> <span>known vulnerabilities</span></div>
<div class="meta-count"><span>67 vulnerable dependency paths</span></div>
<div class="meta-count"><span>2092</span> <span>dependencies</span></div>
</div><!-- .meta-counts -->
</div><!-- .layout-container--short -->
@@ -1189,9 +1189,10 @@
<h3 id="for-more-information-on-this-vulnerability-type">For more information on this vulnerability type:</h3>
<p><a href="https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript_prototype_pollution_attack_in_NodeJS.pdf">Arteau, Oliver. “JavaScript prototype pollution attack in NodeJS application.” GitHub, 26 May 2018</a></p>
<h2 id="remediation">Remediation</h2>
<p>There is no fixed version for <code>min-document</code>.</p>
<p>Upgrade <code>min-document</code> to version 2.19.1 or higher.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="https://github.com/Raynos/min-document/commit/6c5f31aa57e2122fcedd4c7eae58b82f477e09f5">Github Commit</a></li>
<li><a href="https://github.com/Raynos/min-document/pull/55/commits/0d4e8192ef723fb869645256102a56ed922efd68">Github Commit</a></li>
<li><a href="https://github.com/Raynos/min-document/issues/54">GitHub Issue</a></li>
<li><a href="https://github.com/OrangeShieldInfos/PoCs/tree/main/JavaScript/prototype-pollution/CVE-2025-57352">POC</a></li>
@@ -1204,6 +1205,173 @@
<p><a href="https://snyk.io/vuln/SNYK-JS-MINDOCUMENT-13045385">More about this vulnerability</a></p>
</div>
</div><!-- .card -->
<div class="card card--vuln disclosure--not-new severity--medium" data-snyk-test="medium">
<h2 class="card__title">Prototype Pollution</h2>
<div class="card__section">
<div class="card__labels">
<div class="label label--medium">
<span class="label__text">medium severity</span>
</div>
</div>
<hr/>
<ul class="card__meta">
<li class="card__meta__item">
Manifest file: /argo-cd <span class="list-paths__item__arrow"></span> ui/yarn.lock
</li>
<li class="card__meta__item">
Package Manager: npm
</li>
<li class="card__meta__item">
Vulnerable module:
js-yaml
</li>
<li class="card__meta__item">Introduced through:
argo-cd-ui@1.0.0 and js-yaml@4.1.0
</li>
</ul>
<hr/>
<h3 class="card__section__title">Detailed paths</h3>
<ul class="card__meta__paths">
<li>
<span class="list-paths__item__introduced"><em>Introduced through</em>:
argo-cd-ui@1.0.0
<span class="list-paths__item__arrow"></span>
js-yaml@4.1.0
</span>
</li>
<li>
<span class="list-paths__item__introduced"><em>Introduced through</em>:
argo-cd-ui@1.0.0
<span class="list-paths__item__arrow"></span>
redoc@2.4.0
<span class="list-paths__item__arrow"></span>
@redocly/openapi-core@1.30.0
<span class="list-paths__item__arrow"></span>
js-yaml@4.1.0
</span>
</li>
</ul><!-- .list-paths -->
</div><!-- .card__section -->
<hr/>
<!-- Overview -->
<h2 id="overview">Overview</h2>
<p><a href="https://www.npmjs.com/package/js-yaml">js-yaml</a> is a human-friendly data serialization language.</p>
<p>Affected versions of this package are vulnerable to Prototype Pollution via the <code>merge</code> function. An attacker can alter object prototypes by supplying specially crafted YAML documents containing <code>__proto__</code> properties. This can lead to unexpected behavior or security issues in applications that process untrusted YAML input.</p>
<h2 id="workaround">Workaround</h2>
<p>This vulnerability can be mitigated by running the server with <code>node --disable-proto=delete</code> or by using Deno, which has pollution protection enabled by default.</p>
<h2 id="details">Details</h2>
<p>Prototype Pollution is a vulnerability affecting JavaScript. Prototype Pollution refers to the ability to inject properties into existing JavaScript language construct prototypes, such as objects. JavaScript allows all Object attributes to be altered, including their magical attributes such as <code>__proto__</code>, <code>constructor</code> and <code>prototype</code>. An attacker manipulates these attributes to overwrite, or pollute, a JavaScript application object prototype of the base object by injecting other values. Properties on the <code>Object.prototype</code> are then inherited by all the JavaScript objects through the prototype chain. When that happens, this leads to either denial of service by triggering JavaScript exceptions, or it tampers with the application source code to force the code path that the attacker injects, thereby leading to remote code execution.</p>
<p>There are two main ways in which the pollution of prototypes occurs:</p>
<ul>
<li><p>Unsafe <code>Object</code> recursive merge</p>
</li>
<li><p>Property definition by path</p>
</li>
</ul>
<h3 id="unsafe-object-recursive-merge">Unsafe Object recursive merge</h3>
<p>The logic of a vulnerable recursive merge function follows the following high-level model:</p>
<pre><code>merge (target, source)
foreach property of source
if property exists and is an object on both the target and the source
merge(target[property], source[property])
else
target[property] = source[property]
</code></pre>
<br>
<p>When the source object contains a property named <code>__proto__</code> defined with <code>Object.defineProperty()</code> , the condition that checks if the property exists and is an object on both the target and the source passes and the merge recurses with the target, being the prototype of <code>Object</code> and the source of <code>Object</code> as defined by the attacker. Properties are then copied on the <code>Object</code> prototype.</p>
<p>Clone operations are a special sub-class of unsafe recursive merges, which occur when a recursive merge is conducted on an empty object: <code>merge({},source)</code>.</p>
<p><code>lodash</code> and <code>Hoek</code> are examples of libraries susceptible to recursive merge attacks.</p>
<h3 id="property-definition-by-path">Property definition by path</h3>
<p>There are a few JavaScript libraries that use an API to define property values on an object based on a given path. The function that is generally affected contains this signature: <code>theFunction(object, path, value)</code></p>
<p>If the attacker can control the value of “path”, they can set this value to <code>__proto__.myValue</code>. <code>myValue</code> is then assigned to the prototype of the class of the object.</p>
<h2 id="types-of-attacks">Types of attacks</h2>
<p>There are a few methods by which Prototype Pollution can be manipulated:</p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Origin</th>
<th>Short description</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Denial of service (DoS)</strong></td>
<td>Client</td>
<td>This is the most likely attack. <br>DoS occurs when <code>Object</code> holds generic functions that are implicitly called for various operations (for example, <code>toString</code> and <code>valueOf</code>). <br> The attacker pollutes <code>Object.prototype.someattr</code> and alters its state to an unexpected value such as <code>Int</code> or <code>Object</code>. In this case, the code fails and is likely to cause a denial of service. <br><strong>For example:</strong> if an attacker pollutes <code>Object.prototype.toString</code> by defining it as an integer, if the codebase at any point was reliant on <code>someobject.toString()</code> it would fail.</td>
</tr>
<tr>
<td><strong>Remote Code Execution</strong></td>
<td>Client</td>
<td>Remote code execution is generally only possible in cases where the codebase evaluates a specific attribute of an object, and then executes that evaluation.<br><strong>For example:</strong> <code>eval(someobject.someattr)</code>. In this case, if the attacker pollutes <code>Object.prototype.someattr</code> they are likely to be able to leverage this in order to execute code.</td>
</tr>
<tr>
<td><strong>Property Injection</strong></td>
<td>Client</td>
<td>The attacker pollutes properties that the codebase relies on for their informative value, including security properties such as cookies or tokens.<br> <strong>For example:</strong> if a codebase checks privileges for <code>someuser.isAdmin</code>, then when the attacker pollutes <code>Object.prototype.isAdmin</code> and sets it to equal <code>true</code>, they can then achieve admin privileges.</td>
</tr>
</tbody></table>
<h2 id="affected-environments">Affected environments</h2>
<p>The following environments are susceptible to a Prototype Pollution attack:</p>
<ul>
<li><p>Application server</p>
</li>
<li><p>Web server</p>
</li>
<li><p>Web browser</p>
</li>
</ul>
<h2 id="how-to-prevent">How to prevent</h2>
<ol>
<li><p>Freeze the prototype— use <code>Object.freeze (Object.prototype)</code>.</p>
</li>
<li><p>Require schema validation of JSON input.</p>
</li>
<li><p>Avoid using unsafe recursive merge functions.</p>
</li>
<li><p>Consider using objects without prototypes (for example, <code>Object.create(null)</code>), breaking the prototype chain and preventing pollution.</p>
</li>
<li><p>As a best practice use <code>Map</code> instead of <code>Object</code>.</p>
</li>
</ol>
<h3 id="for-more-information-on-this-vulnerability-type">For more information on this vulnerability type:</h3>
<p><a href="https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript_prototype_pollution_attack_in_NodeJS.pdf">Arteau, Oliver. “JavaScript prototype pollution attack in NodeJS application.” GitHub, 26 May 2018</a></p>
<h2 id="remediation">Remediation</h2>
<p>Upgrade <code>js-yaml</code> to version 4.1.1 or higher.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="https://github.com/nodeca/js-yaml/commit/383665ff4248ec2192d1274e934462bb30426879">GitHub Commit</a></li>
</ul>
<hr/>
<div class="cta card__cta">
<p><a href="https://snyk.io/vuln/SNYK-JS-JSYAML-13961110">More about this vulnerability</a></p>
</div>
</div><!-- .card -->
<div class="card card--vuln disclosure--not-new severity--medium" data-snyk-test="medium">
<h2 class="card__title">LGPL-3.0 license</h2>

View File

@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:32:19 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:33:14 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following paths:</span>
@@ -2974,6 +2974,8 @@
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/c2b96348bfa662f25f4fabf81958ae822063dae3">https://github.openssl.org/openssl/extended-releases/commit/c2b96348bfa662f25f4fabf81958ae822063dae3</a></li>
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/dfbaf161d8dafc1132dd88cd48ad990ed9b4c8ba">https://github.openssl.org/openssl/extended-releases/commit/dfbaf161d8dafc1132dd88cd48ad990ed9b4c8ba</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2025/10/msg00001.html">https://lists.debian.org/debian-lts-announce/2025/10/msg00001.html</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -3126,6 +3128,7 @@
<li><a href="https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4">https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4</a></li>
<li><a href="https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2">https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -3283,6 +3286,7 @@
<li><a href="https://github.com/openssl/openssl/commit/89e790ac431125a4849992858490bed6b225eadf">https://github.com/openssl/openssl/commit/89e790ac431125a4849992858490bed6b225eadf</a></li>
<li><a href="https://github.com/openssl/openssl/commit/bbf38c034cdabd0a13330abcc4855c866f53d2e0">https://github.com/openssl/openssl/commit/bbf38c034cdabd0a13330abcc4855c866f53d2e0</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -3448,6 +3452,8 @@
<li><a href="http://www.openwall.com/lists/oss-security/2024/10/23/1">http://www.openwall.com/lists/oss-security/2024/10/23/1</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2024/10/24/1">http://www.openwall.com/lists/oss-security/2024/10/24/1</a></li>
<li><a href="https://security.netapp.com/advisory/ntap-20241101-0001/">https://security.netapp.com/advisory/ntap-20241101-0001/</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2024/10/msg00033.html">https://lists.debian.org/debian-lts-announce/2024/10/msg00033.html</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2024/11/msg00000.html">https://lists.debian.org/debian-lts-announce/2024/11/msg00000.html</a></li>
</ul>
<hr/>
@@ -3606,6 +3612,7 @@
<li><a href="https://security.netapp.com/advisory/ntap-20250124-0005/">https://security.netapp.com/advisory/ntap-20250124-0005/</a></li>
<li><a href="https://security.netapp.com/advisory/ntap-20250418-0010/">https://security.netapp.com/advisory/ntap-20250418-0010/</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2025/05/msg00028.html">https://lists.debian.org/debian-lts-announce/2025/05/msg00028.html</a></li>
<li><a href="https://security.netapp.com/advisory/ntap-20250502-0006/">https://security.netapp.com/advisory/ntap-20250502-0006/</a></li>
</ul>
<hr/>

View File

@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:32:26 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:33:20 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following path:</span>
@@ -820,6 +820,7 @@
<h2 id="references">References</h2>
<ul>
<li><a href="https://bugs.busybox.net/show_bug.cgi?id=15868">https://bugs.busybox.net/show_bug.cgi?id=15868</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2025/01/msg00012.html">https://lists.debian.org/debian-lts-announce/2025/01/msg00012.html</a></li>
</ul>
<hr/>
@@ -941,6 +942,7 @@
<h2 id="references">References</h2>
<ul>
<li><a href="https://bugs.busybox.net/show_bug.cgi?id=15871">https://bugs.busybox.net/show_bug.cgi?id=15871</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2025/01/msg00012.html">https://lists.debian.org/debian-lts-announce/2025/01/msg00012.html</a></li>
</ul>
<hr/>
@@ -1128,6 +1130,8 @@
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/c2b96348bfa662f25f4fabf81958ae822063dae3">https://github.openssl.org/openssl/extended-releases/commit/c2b96348bfa662f25f4fabf81958ae822063dae3</a></li>
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/dfbaf161d8dafc1132dd88cd48ad990ed9b4c8ba">https://github.openssl.org/openssl/extended-releases/commit/dfbaf161d8dafc1132dd88cd48ad990ed9b4c8ba</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2025/10/msg00001.html">https://lists.debian.org/debian-lts-announce/2025/10/msg00001.html</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -1313,6 +1317,7 @@
<li><a href="https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4">https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4</a></li>
<li><a href="https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2">https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -1503,6 +1508,7 @@
<li><a href="https://github.com/openssl/openssl/commit/89e790ac431125a4849992858490bed6b225eadf">https://github.com/openssl/openssl/commit/89e790ac431125a4849992858490bed6b225eadf</a></li>
<li><a href="https://github.com/openssl/openssl/commit/bbf38c034cdabd0a13330abcc4855c866f53d2e0">https://github.com/openssl/openssl/commit/bbf38c034cdabd0a13330abcc4855c866f53d2e0</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -1698,6 +1704,9 @@
<li><a href="https://github.com/openssl/openssl/commit/e5093133c35ca82874ad83697af76f4b0f7e3bd8">https://github.com/openssl/openssl/commit/e5093133c35ca82874ad83697af76f4b0f7e3bd8</a></li>
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/f7a045f3143fc6da2ee66bf52d8df04829590dd4">https://github.openssl.org/openssl/extended-releases/commit/f7a045f3143fc6da2ee66bf52d8df04829590dd4</a></li>
<li><a href="https://www.openssl.org/news/secadv/20240528.txt">https://www.openssl.org/news/secadv/20240528.txt</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2024/10/msg00033.html">https://lists.debian.org/debian-lts-announce/2024/10/msg00033.html</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2024/11/msg00000.html">https://lists.debian.org/debian-lts-announce/2024/11/msg00000.html</a></li>
<li><a href="https://security.netapp.com/advisory/ntap-20240621-0004/">https://security.netapp.com/advisory/ntap-20240621-0004/</a></li>
</ul>
<hr/>
@@ -1928,6 +1937,10 @@
<li><a href="https://github.com/openssl/openssl/commit/e86ac436f0bd54d4517745483e2315650fae7b2c">https://github.com/openssl/openssl/commit/e86ac436f0bd54d4517745483e2315650fae7b2c</a></li>
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/9947251413065a05189a63c9b7a6c1d4e224c21c">https://github.openssl.org/openssl/extended-releases/commit/9947251413065a05189a63c9b7a6c1d4e224c21c</a></li>
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/b78ec0824da857223486660177d3b1f255c65d87">https://github.openssl.org/openssl/extended-releases/commit/b78ec0824da857223486660177d3b1f255c65d87</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2024/10/msg00033.html">https://lists.debian.org/debian-lts-announce/2024/10/msg00033.html</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2024/11/msg00000.html">https://lists.debian.org/debian-lts-announce/2024/11/msg00000.html</a></li>
<li><a href="https://security.netapp.com/advisory/ntap-20241025-0006/">https://security.netapp.com/advisory/ntap-20241025-0006/</a></li>
<li><a href="https://security.netapp.com/advisory/ntap-20241025-0010/">https://security.netapp.com/advisory/ntap-20241025-0010/</a></li>
<li><a href="https://www.openssl.org/news/secadv/20240627.txt">https://www.openssl.org/news/secadv/20240627.txt</a></li>
</ul>
@@ -2127,6 +2140,8 @@
<li><a href="http://www.openwall.com/lists/oss-security/2024/10/23/1">http://www.openwall.com/lists/oss-security/2024/10/23/1</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2024/10/24/1">http://www.openwall.com/lists/oss-security/2024/10/24/1</a></li>
<li><a href="https://security.netapp.com/advisory/ntap-20241101-0001/">https://security.netapp.com/advisory/ntap-20241101-0001/</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2024/10/msg00033.html">https://lists.debian.org/debian-lts-announce/2024/10/msg00033.html</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2024/11/msg00000.html">https://lists.debian.org/debian-lts-announce/2024/11/msg00000.html</a></li>
</ul>
<hr/>
@@ -2318,6 +2333,7 @@
<li><a href="https://security.netapp.com/advisory/ntap-20250124-0005/">https://security.netapp.com/advisory/ntap-20250124-0005/</a></li>
<li><a href="https://security.netapp.com/advisory/ntap-20250418-0010/">https://security.netapp.com/advisory/ntap-20250418-0010/</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2025/05/msg00028.html">https://lists.debian.org/debian-lts-announce/2025/05/msg00028.html</a></li>
<li><a href="https://security.netapp.com/advisory/ntap-20250502-0006/">https://security.netapp.com/advisory/ntap-20250502-0006/</a></li>
</ul>
<hr/>

View File

@@ -0,0 +1,515 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-us">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Snyk test report</title>
<meta name="description" content="0 known vulnerabilities found in 0 vulnerable dependency paths.">
<base target="_blank">
<link rel="icon" type="image/png" href="https://res.cloudinary.com/snyk/image/upload/v1468845142/favicon/favicon.png"
sizes="194x194">
<link rel="shortcut icon" href="https://res.cloudinary.com/snyk/image/upload/v1468845142/favicon/favicon.ico">
<style type="text/css">
body {
-moz-font-feature-settings: "pnum";
-webkit-font-feature-settings: "pnum";
font-variant-numeric: proportional-nums;
display: flex;
flex-direction: column;
font-feature-settings: "pnum";
font-size: 100%;
line-height: 1.5;
min-height: 100vh;
-webkit-text-size-adjust: 100%;
margin: 0;
padding: 0;
background-color: #F5F5F5;
font-family: 'Arial', 'Helvetica', Calibri, sans-serif;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: 500;
}
a,
a:link,
a:visited {
border-bottom: 1px solid #4b45a9;
text-decoration: none;
color: #4b45a9;
}
a:hover,
a:focus,
a:active {
border-bottom: 1px solid #4b45a9;
}
hr {
border: none;
margin: 1em 0;
border-top: 1px solid #c5c5c5;
}
ul {
padding: 0 1em;
margin: 1em 0;
}
code {
background-color: #EEE;
color: #333;
padding: 0.25em 0.5em;
border-radius: 0.25em;
}
pre {
background-color: #333;
font-family: monospace;
padding: 0.5em 1em 0.75em;
border-radius: 0.25em;
font-size: 14px;
}
pre code {
padding: 0;
background-color: transparent;
color: #fff;
}
a code {
border-radius: .125rem .125rem 0 0;
padding-bottom: 0;
color: #4b45a9;
}
a[href^="http://"]:after,
a[href^="https://"]:after {
background-image: linear-gradient(transparent,transparent),url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20112%20109%22%3E%3Cg%20id%3D%22Page-1%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Cg%20id%3D%22link-external%22%3E%3Cg%20id%3D%22arrow%22%3E%3Cpath%20id%3D%22Line%22%20stroke%3D%22%234B45A9%22%20stroke-width%3D%2215%22%20d%3D%22M88.5%2021l-43%2042.5%22%20stroke-linecap%3D%22square%22%2F%3E%3Cpath%20id%3D%22Triangle%22%20fill%3D%22%234B45A9%22%20d%3D%22M111.2%200v50L61%200z%22%2F%3E%3C%2Fg%3E%3Cpath%20id%3D%22square%22%20fill%3D%22%234B45A9%22%20d%3D%22M66%2015H0v94h94V44L79%2059v35H15V30h36z%22%2F%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E");
background-repeat: no-repeat;
background-size: .75rem;
content: "";
display: inline-block;
height: .75rem;
margin-left: .25rem;
width: .75rem;
}
/* Layout */
[class*=layout-container] {
margin: 0 auto;
max-width: 71.25em;
padding: 1.9em 1.3em;
position: relative;
}
.layout-container--short {
padding-top: 0;
padding-bottom: 0;
max-width: 48.75em;
}
.layout-container--short:after {
display: block;
content: "";
clear: both;
}
/* Header */
.header {
padding-bottom: 1px;
}
.paths {
margin-left: 8px;
}
.header-wrap {
display: flex;
flex-direction: row;
justify-content: space-between;
padding-top: 2em;
}
.project__header {
background-color: #030328;
color: #fff;
margin-bottom: -1px;
padding-top: 1em;
padding-bottom: 0.25em;
border-bottom: 2px solid #BBB;
}
.project__header__title {
overflow-wrap: break-word;
word-wrap: break-word;
word-break: break-all;
margin-bottom: .1em;
margin-top: 0;
}
.timestamp {
float: right;
clear: none;
margin-bottom: 0;
}
.meta-counts {
clear: both;
display: block;
flex-wrap: wrap;
justify-content: space-between;
margin: 0 0 1.5em;
color: #fff;
clear: both;
font-size: 1.1em;
}
.meta-count {
display: block;
flex-basis: 100%;
margin: 0 1em 1em 0;
float: left;
padding-right: 1em;
border-right: 2px solid #fff;
}
.meta-count:last-child {
border-right: 0;
padding-right: 0;
margin-right: 0;
}
/* Card */
.card {
background-color: #fff;
border: 1px solid #c5c5c5;
border-radius: .25rem;
margin: 0 0 2em 0;
position: relative;
min-height: 40px;
padding: 1.5em;
}
.card__labels {
position: absolute;
top: 1.1em;
left: 0;
display: flex;
align-items: center;
gap: 8px;
}
.card .label {
background-color: #767676;
border: 2px solid #767676;
color: white;
padding: 0.25rem 0.75rem;
font-size: 0.875rem;
text-transform: uppercase;
display: inline-block;
margin: 0;
border-radius: 0.25rem;
}
.card .label__text {
vertical-align: text-top;
font-weight: bold;
}
.card .label--critical {
background-color: #AB1A1A;
border-color: #AB1A1A;
}
.card .label--high {
background-color: #CE5019;
border-color: #CE5019;
}
.card .label--medium {
background-color: #D68000;
border-color: #D68000;
}
.card .label--low {
background-color: #88879E;
border-color: #88879E;
}
.severity--low {
border-color: #88879E;
}
.severity--medium {
border-color: #D68000;
}
.severity--high {
border-color: #CE5019;
}
.severity--critical {
border-color: #AB1A1A;
}
.card--vuln {
padding-top: 4em;
}
.card--vuln .card__labels > .label:first-child {
padding-left: 1.9em;
padding-right: 1.9em;
border-radius: 0 0.25rem 0.25rem 0;
}
.card--vuln .card__section h2 {
font-size: 22px;
margin-bottom: 0.5em;
}
.card--vuln .card__section p {
margin: 0 0 0.5em 0;
}
.card--vuln .card__meta {
padding: 0 0 0 1em;
margin: 0;
font-size: 1.1em;
}
.card .card__meta__paths {
font-size: 0.9em;
}
.card--vuln .card__title {
font-size: 28px;
margin-top: 0;
margin-right: 100px; /* Ensure space for the risk score */
}
.card--vuln .card__cta p {
margin: 0;
text-align: right;
}
.risk-score-display {
position: absolute;
top: 1.5em;
right: 1.5em;
text-align: right;
z-index: 10;
}
.risk-score-display__label {
font-size: 0.7em;
font-weight: bold;
color: #586069;
text-transform: uppercase;
line-height: 1;
margin-bottom: 3px;
}
.risk-score-display__value {
font-size: 1.9em;
font-weight: 600;
color: #24292e;
line-height: 1;
}
.source-panel {
clear: both;
display: flex;
justify-content: flex-start;
flex-direction: column;
align-items: flex-start;
padding: 0.5em 0;
width: fit-content;
}
</style>
<style type="text/css">
.metatable {
text-size-adjust: 100%;
-webkit-font-smoothing: antialiased;
-webkit-box-direction: normal;
color: inherit;
font-feature-settings: "pnum";
box-sizing: border-box;
background: transparent;
border: 0;
font: inherit;
font-size: 100%;
margin: 0;
outline: none;
padding: 0;
text-align: left;
text-decoration: none;
vertical-align: baseline;
z-index: auto;
margin-top: 12px;
border-collapse: collapse;
border-spacing: 0;
font-variant-numeric: tabular-nums;
max-width: 51.75em;
}
tbody {
text-size-adjust: 100%;
-webkit-font-smoothing: antialiased;
-webkit-box-direction: normal;
color: inherit;
font-feature-settings: "pnum";
border-collapse: collapse;
border-spacing: 0;
box-sizing: border-box;
background: transparent;
border: 0;
font: inherit;
font-size: 100%;
margin: 0;
outline: none;
padding: 0;
text-align: left;
text-decoration: none;
vertical-align: baseline;
z-index: auto;
display: flex;
flex-wrap: wrap;
}
.meta-row {
text-size-adjust: 100%;
-webkit-font-smoothing: antialiased;
-webkit-box-direction: normal;
color: inherit;
font-feature-settings: "pnum";
border-collapse: collapse;
border-spacing: 0;
box-sizing: border-box;
background: transparent;
border: 0;
font: inherit;
font-size: 100%;
outline: none;
text-align: left;
text-decoration: none;
vertical-align: baseline;
z-index: auto;
display: flex;
align-items: start;
border-top: 1px solid #d3d3d9;
padding: 8px 0 0 0;
border-bottom: none;
margin: 8px;
width: 47.75%;
}
.meta-row-label {
text-size-adjust: 100%;
-webkit-font-smoothing: antialiased;
-webkit-box-direction: normal;
font-feature-settings: "pnum";
border-collapse: collapse;
border-spacing: 0;
color: #4c4a73;
box-sizing: border-box;
background: transparent;
border: 0;
font: inherit;
margin: 0;
outline: none;
text-decoration: none;
z-index: auto;
align-self: start;
flex: 1;
font-size: 1rem;
line-height: 1.5rem;
padding: 0;
text-align: left;
vertical-align: top;
text-transform: none;
letter-spacing: 0;
}
.meta-row-value {
text-size-adjust: 100%;
-webkit-font-smoothing: antialiased;
-webkit-box-direction: normal;
color: inherit;
font-feature-settings: "pnum";
border-collapse: collapse;
border-spacing: 0;
word-break: break-word;
box-sizing: border-box;
background: transparent;
border: 0;
font: inherit;
font-size: 100%;
margin: 0;
outline: none;
padding: 0;
text-align: right;
text-decoration: none;
vertical-align: baseline;
z-index: auto;
}
</style>
</head>
<body class="section-projects">
<main class="layout-stacked">
<div class="layout-stacked__header header">
<header class="project__header">
<div class="layout-container">
<a class="brand" href="https://snyk.io" title="Snyk">
<svg width="68px" height="35px" viewBox="0 0 68 35" version="1.1" xmlns="http://www.w3.org/2000/svg" role="img">
<title>Snyk - Open Source Security</title>
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g fill="#fff">
<path d="M5.732,27.278 C3.445,27.278 1.589,26.885 0,26.124 L0.483,22.472 C2.163,23.296 4.056,23.689 5.643,23.689 C6.801,23.689 7.563,23.295 7.563,22.599 C7.563,20.594 0.333,21.076 0.333,15.839 C0.333,12.491 3.407,10.729 7.259,10.729 C9.179,10.729 11.161,11.249 12.444,11.704 L11.924,15.294 C10.577,14.774 8.747,14.291 7.222,14.291 C6.282,14.291 5.518,14.621 5.518,15.231 C5.518,17.208 12.903,16.815 12.903,21.925 C12.903,25.325 9.877,27.277 5.733,27.277 L5.732,27.278 Z M25.726,26.936 L25.726,17.894 C25.726,15.827 24.811,14.85 23.069,14.85 C22.219,14.85 21.329,15.09 20.719,15.46 L20.719,26.936 L15.352,26.936 L15.352,11.262 L20.602,10.83 L20.474,13.392 L20.652,13.392 C21.784,11.87 23.702,10.716 25.992,10.716 C28.736,10.716 31.112,12.416 31.112,16.436 L31.112,26.936 L25.724,26.936 L25.726,26.936 Z M61.175,26.936 L56.879,19.479 L56.446,19.479 L56.446,26.935 L51.082,26.935 L51.082,8.37 L56.447,0 L56.447,17.323 C57.515,16.017 61.112,11.059 61.112,11.059 L67.732,11.059 L61.454,17.689 L67.949,26.95 L61.175,26.95 L61.175,26.938 L61.175,26.936 Z M44.13,11.11 L41.93,18.262 C41.5,19.606 41.08,22.079 41.08,22.079 C41.08,22.079 40.75,19.516 40.292,18.172 L37.94,11.108 L31.928,11.108 L38.462,26.935 C37.572,29.04 36.199,30.815 34.369,30.815 C34.039,30.815 33.709,30.802 33.389,30.765 L31.255,34.061 C31.928,34.441 33.212,34.835 34.737,34.835 C38.703,34.835 41.359,31.627 43.215,26.885 L49.443,11.108 L44.132,11.108 L44.13,11.11 Z"></path>
</g>
</g>
</svg>
</a>
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 16th 2025, 12:33:31 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following paths:</span>
<ul>
<li class="paths">public.ecr.aws/docker/library/redis:7.2.11-alpine/docker/library/redis (apk)</li>
<li class="paths">public.ecr.aws/docker/library/redis:7.2.11-alpine/tianon/gosu//usr/local/bin/gosu (gomodules)</li>
</ul>
</div>
<div class="meta-counts">
<div class="meta-count"><span>0</span> <span>known vulnerabilities</span></div>
<div class="meta-count"><span>0 vulnerable dependency paths</span></div>
<div class="meta-count"><span>19</span> <span>dependencies</span></div>
</div><!-- .meta-counts -->
</div><!-- .layout-container--short -->
</header><!-- .project__header -->
</div><!-- .layout-stacked__header -->
<div class="layout-container" style="padding-top: 35px;">
No known vulnerabilities detected.
</div>
</main><!-- .layout-stacked__content -->
</body>
</html>

View File

@@ -0,0 +1,515 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-us">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Snyk test report</title>
<meta name="description" content="0 known vulnerabilities found in 0 vulnerable dependency paths.">
<base target="_blank">
<link rel="icon" type="image/png" href="https://res.cloudinary.com/snyk/image/upload/v1468845142/favicon/favicon.png"
sizes="194x194">
<link rel="shortcut icon" href="https://res.cloudinary.com/snyk/image/upload/v1468845142/favicon/favicon.ico">
<style type="text/css">
body {
-moz-font-feature-settings: "pnum";
-webkit-font-feature-settings: "pnum";
font-variant-numeric: proportional-nums;
display: flex;
flex-direction: column;
font-feature-settings: "pnum";
font-size: 100%;
line-height: 1.5;
min-height: 100vh;
-webkit-text-size-adjust: 100%;
margin: 0;
padding: 0;
background-color: #F5F5F5;
font-family: 'Arial', 'Helvetica', Calibri, sans-serif;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: 500;
}
a,
a:link,
a:visited {
border-bottom: 1px solid #4b45a9;
text-decoration: none;
color: #4b45a9;
}
a:hover,
a:focus,
a:active {
border-bottom: 1px solid #4b45a9;
}
hr {
border: none;
margin: 1em 0;
border-top: 1px solid #c5c5c5;
}
ul {
padding: 0 1em;
margin: 1em 0;
}
code {
background-color: #EEE;
color: #333;
padding: 0.25em 0.5em;
border-radius: 0.25em;
}
pre {
background-color: #333;
font-family: monospace;
padding: 0.5em 1em 0.75em;
border-radius: 0.25em;
font-size: 14px;
}
pre code {
padding: 0;
background-color: transparent;
color: #fff;
}
a code {
border-radius: .125rem .125rem 0 0;
padding-bottom: 0;
color: #4b45a9;
}
a[href^="http://"]:after,
a[href^="https://"]:after {
background-image: linear-gradient(transparent,transparent),url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20112%20109%22%3E%3Cg%20id%3D%22Page-1%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Cg%20id%3D%22link-external%22%3E%3Cg%20id%3D%22arrow%22%3E%3Cpath%20id%3D%22Line%22%20stroke%3D%22%234B45A9%22%20stroke-width%3D%2215%22%20d%3D%22M88.5%2021l-43%2042.5%22%20stroke-linecap%3D%22square%22%2F%3E%3Cpath%20id%3D%22Triangle%22%20fill%3D%22%234B45A9%22%20d%3D%22M111.2%200v50L61%200z%22%2F%3E%3C%2Fg%3E%3Cpath%20id%3D%22square%22%20fill%3D%22%234B45A9%22%20d%3D%22M66%2015H0v94h94V44L79%2059v35H15V30h36z%22%2F%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E");
background-repeat: no-repeat;
background-size: .75rem;
content: "";
display: inline-block;
height: .75rem;
margin-left: .25rem;
width: .75rem;
}
/* Layout */
[class*=layout-container] {
margin: 0 auto;
max-width: 71.25em;
padding: 1.9em 1.3em;
position: relative;
}
.layout-container--short {
padding-top: 0;
padding-bottom: 0;
max-width: 48.75em;
}
.layout-container--short:after {
display: block;
content: "";
clear: both;
}
/* Header */
.header {
padding-bottom: 1px;
}
.paths {
margin-left: 8px;
}
.header-wrap {
display: flex;
flex-direction: row;
justify-content: space-between;
padding-top: 2em;
}
.project__header {
background-color: #030328;
color: #fff;
margin-bottom: -1px;
padding-top: 1em;
padding-bottom: 0.25em;
border-bottom: 2px solid #BBB;
}
.project__header__title {
overflow-wrap: break-word;
word-wrap: break-word;
word-break: break-all;
margin-bottom: .1em;
margin-top: 0;
}
.timestamp {
float: right;
clear: none;
margin-bottom: 0;
}
.meta-counts {
clear: both;
display: block;
flex-wrap: wrap;
justify-content: space-between;
margin: 0 0 1.5em;
color: #fff;
clear: both;
font-size: 1.1em;
}
.meta-count {
display: block;
flex-basis: 100%;
margin: 0 1em 1em 0;
float: left;
padding-right: 1em;
border-right: 2px solid #fff;
}
.meta-count:last-child {
border-right: 0;
padding-right: 0;
margin-right: 0;
}
/* Card */
.card {
background-color: #fff;
border: 1px solid #c5c5c5;
border-radius: .25rem;
margin: 0 0 2em 0;
position: relative;
min-height: 40px;
padding: 1.5em;
}
.card__labels {
position: absolute;
top: 1.1em;
left: 0;
display: flex;
align-items: center;
gap: 8px;
}
.card .label {
background-color: #767676;
border: 2px solid #767676;
color: white;
padding: 0.25rem 0.75rem;
font-size: 0.875rem;
text-transform: uppercase;
display: inline-block;
margin: 0;
border-radius: 0.25rem;
}
.card .label__text {
vertical-align: text-top;
font-weight: bold;
}
.card .label--critical {
background-color: #AB1A1A;
border-color: #AB1A1A;
}
.card .label--high {
background-color: #CE5019;
border-color: #CE5019;
}
.card .label--medium {
background-color: #D68000;
border-color: #D68000;
}
.card .label--low {
background-color: #88879E;
border-color: #88879E;
}
.severity--low {
border-color: #88879E;
}
.severity--medium {
border-color: #D68000;
}
.severity--high {
border-color: #CE5019;
}
.severity--critical {
border-color: #AB1A1A;
}
.card--vuln {
padding-top: 4em;
}
.card--vuln .card__labels > .label:first-child {
padding-left: 1.9em;
padding-right: 1.9em;
border-radius: 0 0.25rem 0.25rem 0;
}
.card--vuln .card__section h2 {
font-size: 22px;
margin-bottom: 0.5em;
}
.card--vuln .card__section p {
margin: 0 0 0.5em 0;
}
.card--vuln .card__meta {
padding: 0 0 0 1em;
margin: 0;
font-size: 1.1em;
}
.card .card__meta__paths {
font-size: 0.9em;
}
.card--vuln .card__title {
font-size: 28px;
margin-top: 0;
margin-right: 100px; /* Ensure space for the risk score */
}
.card--vuln .card__cta p {
margin: 0;
text-align: right;
}
.risk-score-display {
position: absolute;
top: 1.5em;
right: 1.5em;
text-align: right;
z-index: 10;
}
.risk-score-display__label {
font-size: 0.7em;
font-weight: bold;
color: #586069;
text-transform: uppercase;
line-height: 1;
margin-bottom: 3px;
}
.risk-score-display__value {
font-size: 1.9em;
font-weight: 600;
color: #24292e;
line-height: 1;
}
.source-panel {
clear: both;
display: flex;
justify-content: flex-start;
flex-direction: column;
align-items: flex-start;
padding: 0.5em 0;
width: fit-content;
}
</style>
<style type="text/css">
.metatable {
text-size-adjust: 100%;
-webkit-font-smoothing: antialiased;
-webkit-box-direction: normal;
color: inherit;
font-feature-settings: "pnum";
box-sizing: border-box;
background: transparent;
border: 0;
font: inherit;
font-size: 100%;
margin: 0;
outline: none;
padding: 0;
text-align: left;
text-decoration: none;
vertical-align: baseline;
z-index: auto;
margin-top: 12px;
border-collapse: collapse;
border-spacing: 0;
font-variant-numeric: tabular-nums;
max-width: 51.75em;
}
tbody {
text-size-adjust: 100%;
-webkit-font-smoothing: antialiased;
-webkit-box-direction: normal;
color: inherit;
font-feature-settings: "pnum";
border-collapse: collapse;
border-spacing: 0;
box-sizing: border-box;
background: transparent;
border: 0;
font: inherit;
font-size: 100%;
margin: 0;
outline: none;
padding: 0;
text-align: left;
text-decoration: none;
vertical-align: baseline;
z-index: auto;
display: flex;
flex-wrap: wrap;
}
.meta-row {
text-size-adjust: 100%;
-webkit-font-smoothing: antialiased;
-webkit-box-direction: normal;
color: inherit;
font-feature-settings: "pnum";
border-collapse: collapse;
border-spacing: 0;
box-sizing: border-box;
background: transparent;
border: 0;
font: inherit;
font-size: 100%;
outline: none;
text-align: left;
text-decoration: none;
vertical-align: baseline;
z-index: auto;
display: flex;
align-items: start;
border-top: 1px solid #d3d3d9;
padding: 8px 0 0 0;
border-bottom: none;
margin: 8px;
width: 47.75%;
}
.meta-row-label {
text-size-adjust: 100%;
-webkit-font-smoothing: antialiased;
-webkit-box-direction: normal;
font-feature-settings: "pnum";
border-collapse: collapse;
border-spacing: 0;
color: #4c4a73;
box-sizing: border-box;
background: transparent;
border: 0;
font: inherit;
margin: 0;
outline: none;
text-decoration: none;
z-index: auto;
align-self: start;
flex: 1;
font-size: 1rem;
line-height: 1.5rem;
padding: 0;
text-align: left;
vertical-align: top;
text-transform: none;
letter-spacing: 0;
}
.meta-row-value {
text-size-adjust: 100%;
-webkit-font-smoothing: antialiased;
-webkit-box-direction: normal;
color: inherit;
font-feature-settings: "pnum";
border-collapse: collapse;
border-spacing: 0;
word-break: break-word;
box-sizing: border-box;
background: transparent;
border: 0;
font: inherit;
font-size: 100%;
margin: 0;
outline: none;
padding: 0;
text-align: right;
text-decoration: none;
vertical-align: baseline;
z-index: auto;
}
</style>
</head>
<body class="section-projects">
<main class="layout-stacked">
<div class="layout-stacked__header header">
<header class="project__header">
<div class="layout-container">
<a class="brand" href="https://snyk.io" title="Snyk">
<svg width="68px" height="35px" viewBox="0 0 68 35" version="1.1" xmlns="http://www.w3.org/2000/svg" role="img">
<title>Snyk - Open Source Security</title>
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g fill="#fff">
<path d="M5.732,27.278 C3.445,27.278 1.589,26.885 0,26.124 L0.483,22.472 C2.163,23.296 4.056,23.689 5.643,23.689 C6.801,23.689 7.563,23.295 7.563,22.599 C7.563,20.594 0.333,21.076 0.333,15.839 C0.333,12.491 3.407,10.729 7.259,10.729 C9.179,10.729 11.161,11.249 12.444,11.704 L11.924,15.294 C10.577,14.774 8.747,14.291 7.222,14.291 C6.282,14.291 5.518,14.621 5.518,15.231 C5.518,17.208 12.903,16.815 12.903,21.925 C12.903,25.325 9.877,27.277 5.733,27.277 L5.732,27.278 Z M25.726,26.936 L25.726,17.894 C25.726,15.827 24.811,14.85 23.069,14.85 C22.219,14.85 21.329,15.09 20.719,15.46 L20.719,26.936 L15.352,26.936 L15.352,11.262 L20.602,10.83 L20.474,13.392 L20.652,13.392 C21.784,11.87 23.702,10.716 25.992,10.716 C28.736,10.716 31.112,12.416 31.112,16.436 L31.112,26.936 L25.724,26.936 L25.726,26.936 Z M61.175,26.936 L56.879,19.479 L56.446,19.479 L56.446,26.935 L51.082,26.935 L51.082,8.37 L56.447,0 L56.447,17.323 C57.515,16.017 61.112,11.059 61.112,11.059 L67.732,11.059 L61.454,17.689 L67.949,26.95 L61.175,26.95 L61.175,26.938 L61.175,26.936 Z M44.13,11.11 L41.93,18.262 C41.5,19.606 41.08,22.079 41.08,22.079 C41.08,22.079 40.75,19.516 40.292,18.172 L37.94,11.108 L31.928,11.108 L38.462,26.935 C37.572,29.04 36.199,30.815 34.369,30.815 C34.039,30.815 33.709,30.802 33.389,30.765 L31.255,34.061 C31.928,34.441 33.212,34.835 34.737,34.835 C38.703,34.835 41.359,31.627 43.215,26.885 L49.443,11.108 L44.132,11.108 L44.13,11.11 Z"></path>
</g>
</g>
</svg>
</a>
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 16th 2025, 12:33:59 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following paths:</span>
<ul>
<li class="paths">redis:7.2.11-alpine (apk)</li>
<li class="paths">redis:7.2.11-alpine/tianon/gosu//usr/local/bin/gosu (gomodules)</li>
</ul>
</div>
<div class="meta-counts">
<div class="meta-count"><span>0</span> <span>known vulnerabilities</span></div>
<div class="meta-count"><span>0 vulnerable dependency paths</span></div>
<div class="meta-count"><span>19</span> <span>dependencies</span></div>
</div><!-- .meta-counts -->
</div><!-- .layout-container--short -->
</header><!-- .project__header -->
</div><!-- .layout-stacked__header -->
<div class="layout-container" style="padding-top: 35px;">
No known vulnerabilities detected.
</div>
</main><!-- .layout-stacked__content -->
</body>
</html>

View File

@@ -456,7 +456,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:31:39 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:32:19 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following path:</span>

View File

@@ -456,7 +456,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:31:50 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:32:30 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following path:</span>

View File

@@ -7,7 +7,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Snyk test report</title>
<meta name="description" content="18 known vulnerabilities found in 111 vulnerable dependency paths.">
<meta name="description" content="19 known vulnerabilities found in 113 vulnerable dependency paths.">
<base target="_blank">
<link rel="icon" type="image/png" href="https://res.cloudinary.com/snyk/image/upload/v1468845142/favicon/favicon.png"
sizes="194x194">
@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:29:35 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:30:16 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following paths:</span>
@@ -499,8 +499,8 @@
</div>
<div class="meta-counts">
<div class="meta-count"><span>18</span> <span>known vulnerabilities</span></div>
<div class="meta-count"><span>111 vulnerable dependency paths</span></div>
<div class="meta-count"><span>19</span> <span>known vulnerabilities</span></div>
<div class="meta-count"><span>113 vulnerable dependency paths</span></div>
<div class="meta-count"><span>2085</span> <span>dependencies</span></div>
</div><!-- .meta-counts -->
</div><!-- .layout-container--short -->
@@ -2153,9 +2153,10 @@
<h3 id="for-more-information-on-this-vulnerability-type">For more information on this vulnerability type:</h3>
<p><a href="https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript_prototype_pollution_attack_in_NodeJS.pdf">Arteau, Oliver. “JavaScript prototype pollution attack in NodeJS application.” GitHub, 26 May 2018</a></p>
<h2 id="remediation">Remediation</h2>
<p>There is no fixed version for <code>min-document</code>.</p>
<p>Upgrade <code>min-document</code> to version 2.19.1 or higher.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="https://github.com/Raynos/min-document/commit/6c5f31aa57e2122fcedd4c7eae58b82f477e09f5">Github Commit</a></li>
<li><a href="https://github.com/Raynos/min-document/pull/55/commits/0d4e8192ef723fb869645256102a56ed922efd68">Github Commit</a></li>
<li><a href="https://github.com/Raynos/min-document/issues/54">GitHub Issue</a></li>
<li><a href="https://github.com/OrangeShieldInfos/PoCs/tree/main/JavaScript/prototype-pollution/CVE-2025-57352">POC</a></li>
@@ -2168,6 +2169,173 @@
<p><a href="https://snyk.io/vuln/SNYK-JS-MINDOCUMENT-13045385">More about this vulnerability</a></p>
</div>
</div><!-- .card -->
<div class="card card--vuln disclosure--not-new severity--medium" data-snyk-test="medium">
<h2 class="card__title">Prototype Pollution</h2>
<div class="card__section">
<div class="card__labels">
<div class="label label--medium">
<span class="label__text">medium severity</span>
</div>
</div>
<hr/>
<ul class="card__meta">
<li class="card__meta__item">
Manifest file: /argo-cd <span class="list-paths__item__arrow"></span> ui/yarn.lock
</li>
<li class="card__meta__item">
Package Manager: npm
</li>
<li class="card__meta__item">
Vulnerable module:
js-yaml
</li>
<li class="card__meta__item">Introduced through:
argo-cd-ui@1.0.0 and js-yaml@4.1.0
</li>
</ul>
<hr/>
<h3 class="card__section__title">Detailed paths</h3>
<ul class="card__meta__paths">
<li>
<span class="list-paths__item__introduced"><em>Introduced through</em>:
argo-cd-ui@1.0.0
<span class="list-paths__item__arrow"></span>
js-yaml@4.1.0
</span>
</li>
<li>
<span class="list-paths__item__introduced"><em>Introduced through</em>:
argo-cd-ui@1.0.0
<span class="list-paths__item__arrow"></span>
redoc@2.0.0-rc.64
<span class="list-paths__item__arrow"></span>
@redocly/openapi-core@1.0.0-beta.82
<span class="list-paths__item__arrow"></span>
js-yaml@4.1.0
</span>
</li>
</ul><!-- .list-paths -->
</div><!-- .card__section -->
<hr/>
<!-- Overview -->
<h2 id="overview">Overview</h2>
<p><a href="https://www.npmjs.com/package/js-yaml">js-yaml</a> is a human-friendly data serialization language.</p>
<p>Affected versions of this package are vulnerable to Prototype Pollution via the <code>merge</code> function. An attacker can alter object prototypes by supplying specially crafted YAML documents containing <code>__proto__</code> properties. This can lead to unexpected behavior or security issues in applications that process untrusted YAML input.</p>
<h2 id="workaround">Workaround</h2>
<p>This vulnerability can be mitigated by running the server with <code>node --disable-proto=delete</code> or by using Deno, which has pollution protection enabled by default.</p>
<h2 id="details">Details</h2>
<p>Prototype Pollution is a vulnerability affecting JavaScript. Prototype Pollution refers to the ability to inject properties into existing JavaScript language construct prototypes, such as objects. JavaScript allows all Object attributes to be altered, including their magical attributes such as <code>__proto__</code>, <code>constructor</code> and <code>prototype</code>. An attacker manipulates these attributes to overwrite, or pollute, a JavaScript application object prototype of the base object by injecting other values. Properties on the <code>Object.prototype</code> are then inherited by all the JavaScript objects through the prototype chain. When that happens, this leads to either denial of service by triggering JavaScript exceptions, or it tampers with the application source code to force the code path that the attacker injects, thereby leading to remote code execution.</p>
<p>There are two main ways in which the pollution of prototypes occurs:</p>
<ul>
<li><p>Unsafe <code>Object</code> recursive merge</p>
</li>
<li><p>Property definition by path</p>
</li>
</ul>
<h3 id="unsafe-object-recursive-merge">Unsafe Object recursive merge</h3>
<p>The logic of a vulnerable recursive merge function follows the following high-level model:</p>
<pre><code>merge (target, source)
foreach property of source
if property exists and is an object on both the target and the source
merge(target[property], source[property])
else
target[property] = source[property]
</code></pre>
<br>
<p>When the source object contains a property named <code>__proto__</code> defined with <code>Object.defineProperty()</code> , the condition that checks if the property exists and is an object on both the target and the source passes and the merge recurses with the target, being the prototype of <code>Object</code> and the source of <code>Object</code> as defined by the attacker. Properties are then copied on the <code>Object</code> prototype.</p>
<p>Clone operations are a special sub-class of unsafe recursive merges, which occur when a recursive merge is conducted on an empty object: <code>merge({},source)</code>.</p>
<p><code>lodash</code> and <code>Hoek</code> are examples of libraries susceptible to recursive merge attacks.</p>
<h3 id="property-definition-by-path">Property definition by path</h3>
<p>There are a few JavaScript libraries that use an API to define property values on an object based on a given path. The function that is generally affected contains this signature: <code>theFunction(object, path, value)</code></p>
<p>If the attacker can control the value of “path”, they can set this value to <code>__proto__.myValue</code>. <code>myValue</code> is then assigned to the prototype of the class of the object.</p>
<h2 id="types-of-attacks">Types of attacks</h2>
<p>There are a few methods by which Prototype Pollution can be manipulated:</p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Origin</th>
<th>Short description</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Denial of service (DoS)</strong></td>
<td>Client</td>
<td>This is the most likely attack. <br>DoS occurs when <code>Object</code> holds generic functions that are implicitly called for various operations (for example, <code>toString</code> and <code>valueOf</code>). <br> The attacker pollutes <code>Object.prototype.someattr</code> and alters its state to an unexpected value such as <code>Int</code> or <code>Object</code>. In this case, the code fails and is likely to cause a denial of service. <br><strong>For example:</strong> if an attacker pollutes <code>Object.prototype.toString</code> by defining it as an integer, if the codebase at any point was reliant on <code>someobject.toString()</code> it would fail.</td>
</tr>
<tr>
<td><strong>Remote Code Execution</strong></td>
<td>Client</td>
<td>Remote code execution is generally only possible in cases where the codebase evaluates a specific attribute of an object, and then executes that evaluation.<br><strong>For example:</strong> <code>eval(someobject.someattr)</code>. In this case, if the attacker pollutes <code>Object.prototype.someattr</code> they are likely to be able to leverage this in order to execute code.</td>
</tr>
<tr>
<td><strong>Property Injection</strong></td>
<td>Client</td>
<td>The attacker pollutes properties that the codebase relies on for their informative value, including security properties such as cookies or tokens.<br> <strong>For example:</strong> if a codebase checks privileges for <code>someuser.isAdmin</code>, then when the attacker pollutes <code>Object.prototype.isAdmin</code> and sets it to equal <code>true</code>, they can then achieve admin privileges.</td>
</tr>
</tbody></table>
<h2 id="affected-environments">Affected environments</h2>
<p>The following environments are susceptible to a Prototype Pollution attack:</p>
<ul>
<li><p>Application server</p>
</li>
<li><p>Web server</p>
</li>
<li><p>Web browser</p>
</li>
</ul>
<h2 id="how-to-prevent">How to prevent</h2>
<ol>
<li><p>Freeze the prototype— use <code>Object.freeze (Object.prototype)</code>.</p>
</li>
<li><p>Require schema validation of JSON input.</p>
</li>
<li><p>Avoid using unsafe recursive merge functions.</p>
</li>
<li><p>Consider using objects without prototypes (for example, <code>Object.create(null)</code>), breaking the prototype chain and preventing pollution.</p>
</li>
<li><p>As a best practice use <code>Map</code> instead of <code>Object</code>.</p>
</li>
</ol>
<h3 id="for-more-information-on-this-vulnerability-type">For more information on this vulnerability type:</h3>
<p><a href="https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript_prototype_pollution_attack_in_NodeJS.pdf">Arteau, Oliver. “JavaScript prototype pollution attack in NodeJS application.” GitHub, 26 May 2018</a></p>
<h2 id="remediation">Remediation</h2>
<p>Upgrade <code>js-yaml</code> to version 4.1.1 or higher.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="https://github.com/nodeca/js-yaml/commit/383665ff4248ec2192d1274e934462bb30426879">GitHub Commit</a></li>
</ul>
<hr/>
<div class="cta card__cta">
<p><a href="https://snyk.io/vuln/SNYK-JS-JSYAML-13961110">More about this vulnerability</a></p>
</div>
</div><!-- .card -->
<div class="card card--vuln disclosure--not-new severity--medium" data-snyk-test="medium">
<h2 class="card__title">MPL-2.0 license</h2>

View File

@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:29:44 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:30:24 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following paths:</span>
@@ -2974,6 +2974,8 @@
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/c2b96348bfa662f25f4fabf81958ae822063dae3">https://github.openssl.org/openssl/extended-releases/commit/c2b96348bfa662f25f4fabf81958ae822063dae3</a></li>
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/dfbaf161d8dafc1132dd88cd48ad990ed9b4c8ba">https://github.openssl.org/openssl/extended-releases/commit/dfbaf161d8dafc1132dd88cd48ad990ed9b4c8ba</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2025/10/msg00001.html">https://lists.debian.org/debian-lts-announce/2025/10/msg00001.html</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -3126,6 +3128,7 @@
<li><a href="https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4">https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4</a></li>
<li><a href="https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2">https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -3283,6 +3286,7 @@
<li><a href="https://github.com/openssl/openssl/commit/89e790ac431125a4849992858490bed6b225eadf">https://github.com/openssl/openssl/commit/89e790ac431125a4849992858490bed6b225eadf</a></li>
<li><a href="https://github.com/openssl/openssl/commit/bbf38c034cdabd0a13330abcc4855c866f53d2e0">https://github.com/openssl/openssl/commit/bbf38c034cdabd0a13330abcc4855c866f53d2e0</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -3448,6 +3452,8 @@
<li><a href="http://www.openwall.com/lists/oss-security/2024/10/23/1">http://www.openwall.com/lists/oss-security/2024/10/23/1</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2024/10/24/1">http://www.openwall.com/lists/oss-security/2024/10/24/1</a></li>
<li><a href="https://security.netapp.com/advisory/ntap-20241101-0001/">https://security.netapp.com/advisory/ntap-20241101-0001/</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2024/10/msg00033.html">https://lists.debian.org/debian-lts-announce/2024/10/msg00033.html</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2024/11/msg00000.html">https://lists.debian.org/debian-lts-announce/2024/11/msg00000.html</a></li>
</ul>
<hr/>
@@ -3606,6 +3612,7 @@
<li><a href="https://security.netapp.com/advisory/ntap-20250124-0005/">https://security.netapp.com/advisory/ntap-20250124-0005/</a></li>
<li><a href="https://security.netapp.com/advisory/ntap-20250418-0010/">https://security.netapp.com/advisory/ntap-20250418-0010/</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2025/05/msg00028.html">https://lists.debian.org/debian-lts-announce/2025/05/msg00028.html</a></li>
<li><a href="https://security.netapp.com/advisory/ntap-20250502-0006/">https://security.netapp.com/advisory/ntap-20250502-0006/</a></li>
</ul>
<hr/>

View File

@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:29:48 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:30:29 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following path:</span>
@@ -694,6 +694,8 @@
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/c2b96348bfa662f25f4fabf81958ae822063dae3">https://github.openssl.org/openssl/extended-releases/commit/c2b96348bfa662f25f4fabf81958ae822063dae3</a></li>
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/dfbaf161d8dafc1132dd88cd48ad990ed9b4c8ba">https://github.openssl.org/openssl/extended-releases/commit/dfbaf161d8dafc1132dd88cd48ad990ed9b4c8ba</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2025/10/msg00001.html">https://lists.debian.org/debian-lts-announce/2025/10/msg00001.html</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -879,6 +881,7 @@
<li><a href="https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4">https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4</a></li>
<li><a href="https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2">https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -1069,6 +1072,7 @@
<li><a href="https://github.com/openssl/openssl/commit/89e790ac431125a4849992858490bed6b225eadf">https://github.com/openssl/openssl/commit/89e790ac431125a4849992858490bed6b225eadf</a></li>
<li><a href="https://github.com/openssl/openssl/commit/bbf38c034cdabd0a13330abcc4855c866f53d2e0">https://github.com/openssl/openssl/commit/bbf38c034cdabd0a13330abcc4855c866f53d2e0</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>

View File

@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:29:52 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:30:34 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following paths:</span>

View File

@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:30:15 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:30:56 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following paths:</span>
@@ -889,6 +889,7 @@
<li><a href="https://lists.gnu.org/archive/html/bug-tar/2025-08/msg00012.html">https://lists.gnu.org/archive/html/bug-tar/2025-08/msg00012.html</a></li>
<li><a href="https://www.gnu.org/software/tar/manual/html_node/Integrity.html">https://www.gnu.org/software/tar/manual/html_node/Integrity.html</a></li>
<li><a href="https://www.gnu.org/software/tar/manual/html_node/Security-rules-of-thumb.html">https://www.gnu.org/software/tar/manual/html_node/Security-rules-of-thumb.html</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/11/01/6">http://www.openwall.com/lists/oss-security/2025/11/01/6</a></li>
</ul>
<hr/>
@@ -1142,6 +1143,7 @@
<li><a href="https://access.redhat.com/errata/RHSA-2025:15827">https://access.redhat.com/errata/RHSA-2025:15827</a></li>
<li><a href="https://access.redhat.com/errata/RHSA-2025:16524">https://access.redhat.com/errata/RHSA-2025:16524</a></li>
<li><a href="https://access.redhat.com/errata/RHSA-2025:18219">https://access.redhat.com/errata/RHSA-2025:18219</a></li>
<li><a href="https://access.redhat.com/errata/RHSA-2025:17181">https://access.redhat.com/errata/RHSA-2025:17181</a></li>
</ul>
<hr/>
@@ -2263,7 +2265,7 @@
<em>See <code>How to fix?</code> for <code>Ubuntu:24.04</code> relevant fixed versions and status.</em></p>
<p>A flaw was found in libssh, a library that implements the SSH protocol. When calculating the session ID during the key exchange (KEX) process, an allocation failure in cryptographic functions may lead to a NULL pointer dereference. This issue can cause the client or server to crash.</p>
<h2 id="remediation">Remediation</h2>
<p>There is no fixed version for <code>Ubuntu:24.04</code> <code>libssh</code>.</p>
<p>Upgrade <code>Ubuntu:24.04</code> <code>libssh</code> to version 0.10.6-2ubuntu0.2 or higher.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="http://people.ubuntu.com/~ubuntu-security/cve/CVE-2025-8114">http://people.ubuntu.com/~ubuntu-security/cve/CVE-2025-8114</a></li>
@@ -2759,6 +2761,7 @@
<li><a href="https://curl.se/docs/CVE-2025-9086.html">https://curl.se/docs/CVE-2025-9086.html</a></li>
<li><a href="https://curl.se/docs/CVE-2025-9086.json">https://curl.se/docs/CVE-2025-9086.json</a></li>
<li><a href="https://hackerone.com/reports/3294999">https://hackerone.com/reports/3294999</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/10/1">http://www.openwall.com/lists/oss-security/2025/09/10/1</a></li>
</ul>
<hr/>
@@ -2842,6 +2845,8 @@
<li><a href="https://curl.se/docs/CVE-2025-10148.html">https://curl.se/docs/CVE-2025-10148.html</a></li>
<li><a href="https://curl.se/docs/CVE-2025-10148.json">https://curl.se/docs/CVE-2025-10148.json</a></li>
<li><a href="https://hackerone.com/reports/3330839">https://hackerone.com/reports/3330839</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/10/2">http://www.openwall.com/lists/oss-security/2025/09/10/2</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/10/3">http://www.openwall.com/lists/oss-security/2025/09/10/3</a></li>
</ul>
<hr/>

View File

@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:30:19 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:31:01 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following paths:</span>

View File

@@ -456,7 +456,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:29:03 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:29:38 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following path:</span>

View File

@@ -456,7 +456,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:29:14 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:29:56 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following path:</span>

View File

@@ -7,7 +7,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Snyk test report</title>
<meta name="description" content="11 known vulnerabilities found in 34 vulnerable dependency paths.">
<meta name="description" content="12 known vulnerabilities found in 36 vulnerable dependency paths.">
<base target="_blank">
<link rel="icon" type="image/png" href="https://res.cloudinary.com/snyk/image/upload/v1468845142/favicon/favicon.png"
sizes="194x194">
@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:27:05 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:27:40 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following paths:</span>
@@ -499,8 +499,8 @@
</div>
<div class="meta-counts">
<div class="meta-count"><span>11</span> <span>known vulnerabilities</span></div>
<div class="meta-count"><span>34 vulnerable dependency paths</span></div>
<div class="meta-count"><span>12</span> <span>known vulnerabilities</span></div>
<div class="meta-count"><span>36 vulnerable dependency paths</span></div>
<div class="meta-count"><span>2104</span> <span>dependencies</span></div>
</div><!-- .meta-counts -->
</div><!-- .layout-container--short -->
@@ -857,9 +857,10 @@
<h3 id="for-more-information-on-this-vulnerability-type">For more information on this vulnerability type:</h3>
<p><a href="https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript_prototype_pollution_attack_in_NodeJS.pdf">Arteau, Oliver. “JavaScript prototype pollution attack in NodeJS application.” GitHub, 26 May 2018</a></p>
<h2 id="remediation">Remediation</h2>
<p>There is no fixed version for <code>min-document</code>.</p>
<p>Upgrade <code>min-document</code> to version 2.19.1 or higher.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="https://github.com/Raynos/min-document/commit/6c5f31aa57e2122fcedd4c7eae58b82f477e09f5">Github Commit</a></li>
<li><a href="https://github.com/Raynos/min-document/pull/55/commits/0d4e8192ef723fb869645256102a56ed922efd68">Github Commit</a></li>
<li><a href="https://github.com/Raynos/min-document/issues/54">GitHub Issue</a></li>
<li><a href="https://github.com/OrangeShieldInfos/PoCs/tree/main/JavaScript/prototype-pollution/CVE-2025-57352">POC</a></li>
@@ -872,6 +873,173 @@
<p><a href="https://snyk.io/vuln/SNYK-JS-MINDOCUMENT-13045385">More about this vulnerability</a></p>
</div>
</div><!-- .card -->
<div class="card card--vuln disclosure--not-new severity--medium" data-snyk-test="medium">
<h2 class="card__title">Prototype Pollution</h2>
<div class="card__section">
<div class="card__labels">
<div class="label label--medium">
<span class="label__text">medium severity</span>
</div>
</div>
<hr/>
<ul class="card__meta">
<li class="card__meta__item">
Manifest file: /argo-cd <span class="list-paths__item__arrow"></span> ui/yarn.lock
</li>
<li class="card__meta__item">
Package Manager: npm
</li>
<li class="card__meta__item">
Vulnerable module:
js-yaml
</li>
<li class="card__meta__item">Introduced through:
argo-cd-ui@1.0.0 and js-yaml@4.1.0
</li>
</ul>
<hr/>
<h3 class="card__section__title">Detailed paths</h3>
<ul class="card__meta__paths">
<li>
<span class="list-paths__item__introduced"><em>Introduced through</em>:
argo-cd-ui@1.0.0
<span class="list-paths__item__arrow"></span>
js-yaml@4.1.0
</span>
</li>
<li>
<span class="list-paths__item__introduced"><em>Introduced through</em>:
argo-cd-ui@1.0.0
<span class="list-paths__item__arrow"></span>
redoc@2.4.0
<span class="list-paths__item__arrow"></span>
@redocly/openapi-core@1.30.0
<span class="list-paths__item__arrow"></span>
js-yaml@4.1.0
</span>
</li>
</ul><!-- .list-paths -->
</div><!-- .card__section -->
<hr/>
<!-- Overview -->
<h2 id="overview">Overview</h2>
<p><a href="https://www.npmjs.com/package/js-yaml">js-yaml</a> is a human-friendly data serialization language.</p>
<p>Affected versions of this package are vulnerable to Prototype Pollution via the <code>merge</code> function. An attacker can alter object prototypes by supplying specially crafted YAML documents containing <code>__proto__</code> properties. This can lead to unexpected behavior or security issues in applications that process untrusted YAML input.</p>
<h2 id="workaround">Workaround</h2>
<p>This vulnerability can be mitigated by running the server with <code>node --disable-proto=delete</code> or by using Deno, which has pollution protection enabled by default.</p>
<h2 id="details">Details</h2>
<p>Prototype Pollution is a vulnerability affecting JavaScript. Prototype Pollution refers to the ability to inject properties into existing JavaScript language construct prototypes, such as objects. JavaScript allows all Object attributes to be altered, including their magical attributes such as <code>__proto__</code>, <code>constructor</code> and <code>prototype</code>. An attacker manipulates these attributes to overwrite, or pollute, a JavaScript application object prototype of the base object by injecting other values. Properties on the <code>Object.prototype</code> are then inherited by all the JavaScript objects through the prototype chain. When that happens, this leads to either denial of service by triggering JavaScript exceptions, or it tampers with the application source code to force the code path that the attacker injects, thereby leading to remote code execution.</p>
<p>There are two main ways in which the pollution of prototypes occurs:</p>
<ul>
<li><p>Unsafe <code>Object</code> recursive merge</p>
</li>
<li><p>Property definition by path</p>
</li>
</ul>
<h3 id="unsafe-object-recursive-merge">Unsafe Object recursive merge</h3>
<p>The logic of a vulnerable recursive merge function follows the following high-level model:</p>
<pre><code>merge (target, source)
foreach property of source
if property exists and is an object on both the target and the source
merge(target[property], source[property])
else
target[property] = source[property]
</code></pre>
<br>
<p>When the source object contains a property named <code>__proto__</code> defined with <code>Object.defineProperty()</code> , the condition that checks if the property exists and is an object on both the target and the source passes and the merge recurses with the target, being the prototype of <code>Object</code> and the source of <code>Object</code> as defined by the attacker. Properties are then copied on the <code>Object</code> prototype.</p>
<p>Clone operations are a special sub-class of unsafe recursive merges, which occur when a recursive merge is conducted on an empty object: <code>merge({},source)</code>.</p>
<p><code>lodash</code> and <code>Hoek</code> are examples of libraries susceptible to recursive merge attacks.</p>
<h3 id="property-definition-by-path">Property definition by path</h3>
<p>There are a few JavaScript libraries that use an API to define property values on an object based on a given path. The function that is generally affected contains this signature: <code>theFunction(object, path, value)</code></p>
<p>If the attacker can control the value of “path”, they can set this value to <code>__proto__.myValue</code>. <code>myValue</code> is then assigned to the prototype of the class of the object.</p>
<h2 id="types-of-attacks">Types of attacks</h2>
<p>There are a few methods by which Prototype Pollution can be manipulated:</p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Origin</th>
<th>Short description</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Denial of service (DoS)</strong></td>
<td>Client</td>
<td>This is the most likely attack. <br>DoS occurs when <code>Object</code> holds generic functions that are implicitly called for various operations (for example, <code>toString</code> and <code>valueOf</code>). <br> The attacker pollutes <code>Object.prototype.someattr</code> and alters its state to an unexpected value such as <code>Int</code> or <code>Object</code>. In this case, the code fails and is likely to cause a denial of service. <br><strong>For example:</strong> if an attacker pollutes <code>Object.prototype.toString</code> by defining it as an integer, if the codebase at any point was reliant on <code>someobject.toString()</code> it would fail.</td>
</tr>
<tr>
<td><strong>Remote Code Execution</strong></td>
<td>Client</td>
<td>Remote code execution is generally only possible in cases where the codebase evaluates a specific attribute of an object, and then executes that evaluation.<br><strong>For example:</strong> <code>eval(someobject.someattr)</code>. In this case, if the attacker pollutes <code>Object.prototype.someattr</code> they are likely to be able to leverage this in order to execute code.</td>
</tr>
<tr>
<td><strong>Property Injection</strong></td>
<td>Client</td>
<td>The attacker pollutes properties that the codebase relies on for their informative value, including security properties such as cookies or tokens.<br> <strong>For example:</strong> if a codebase checks privileges for <code>someuser.isAdmin</code>, then when the attacker pollutes <code>Object.prototype.isAdmin</code> and sets it to equal <code>true</code>, they can then achieve admin privileges.</td>
</tr>
</tbody></table>
<h2 id="affected-environments">Affected environments</h2>
<p>The following environments are susceptible to a Prototype Pollution attack:</p>
<ul>
<li><p>Application server</p>
</li>
<li><p>Web server</p>
</li>
<li><p>Web browser</p>
</li>
</ul>
<h2 id="how-to-prevent">How to prevent</h2>
<ol>
<li><p>Freeze the prototype— use <code>Object.freeze (Object.prototype)</code>.</p>
</li>
<li><p>Require schema validation of JSON input.</p>
</li>
<li><p>Avoid using unsafe recursive merge functions.</p>
</li>
<li><p>Consider using objects without prototypes (for example, <code>Object.create(null)</code>), breaking the prototype chain and preventing pollution.</p>
</li>
<li><p>As a best practice use <code>Map</code> instead of <code>Object</code>.</p>
</li>
</ol>
<h3 id="for-more-information-on-this-vulnerability-type">For more information on this vulnerability type:</h3>
<p><a href="https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript_prototype_pollution_attack_in_NodeJS.pdf">Arteau, Oliver. “JavaScript prototype pollution attack in NodeJS application.” GitHub, 26 May 2018</a></p>
<h2 id="remediation">Remediation</h2>
<p>Upgrade <code>js-yaml</code> to version 4.1.1 or higher.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="https://github.com/nodeca/js-yaml/commit/383665ff4248ec2192d1274e934462bb30426879">GitHub Commit</a></li>
</ul>
<hr/>
<div class="cta card__cta">
<p><a href="https://snyk.io/vuln/SNYK-JS-JSYAML-13961110">More about this vulnerability</a></p>
</div>
</div><!-- .card -->
<div class="card card--vuln disclosure--not-new severity--medium" data-snyk-test="medium">
<h2 class="card__title">MPL-2.0 license</h2>

View File

@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:27:12 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:27:47 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following paths:</span>
@@ -2429,6 +2429,8 @@
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/c2b96348bfa662f25f4fabf81958ae822063dae3">https://github.openssl.org/openssl/extended-releases/commit/c2b96348bfa662f25f4fabf81958ae822063dae3</a></li>
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/dfbaf161d8dafc1132dd88cd48ad990ed9b4c8ba">https://github.openssl.org/openssl/extended-releases/commit/dfbaf161d8dafc1132dd88cd48ad990ed9b4c8ba</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2025/10/msg00001.html">https://lists.debian.org/debian-lts-announce/2025/10/msg00001.html</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -2581,6 +2583,7 @@
<li><a href="https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4">https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4</a></li>
<li><a href="https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2">https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -2738,6 +2741,7 @@
<li><a href="https://github.com/openssl/openssl/commit/89e790ac431125a4849992858490bed6b225eadf">https://github.com/openssl/openssl/commit/89e790ac431125a4849992858490bed6b225eadf</a></li>
<li><a href="https://github.com/openssl/openssl/commit/bbf38c034cdabd0a13330abcc4855c866f53d2e0">https://github.com/openssl/openssl/commit/bbf38c034cdabd0a13330abcc4855c866f53d2e0</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>

View File

@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:27:16 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:27:51 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following path:</span>
@@ -694,6 +694,8 @@
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/c2b96348bfa662f25f4fabf81958ae822063dae3">https://github.openssl.org/openssl/extended-releases/commit/c2b96348bfa662f25f4fabf81958ae822063dae3</a></li>
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/dfbaf161d8dafc1132dd88cd48ad990ed9b4c8ba">https://github.openssl.org/openssl/extended-releases/commit/dfbaf161d8dafc1132dd88cd48ad990ed9b4c8ba</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2025/10/msg00001.html">https://lists.debian.org/debian-lts-announce/2025/10/msg00001.html</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -879,6 +881,7 @@
<li><a href="https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4">https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4</a></li>
<li><a href="https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2">https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -1069,6 +1072,7 @@
<li><a href="https://github.com/openssl/openssl/commit/89e790ac431125a4849992858490bed6b225eadf">https://github.com/openssl/openssl/commit/89e790ac431125a4849992858490bed6b225eadf</a></li>
<li><a href="https://github.com/openssl/openssl/commit/bbf38c034cdabd0a13330abcc4855c866f53d2e0">https://github.com/openssl/openssl/commit/bbf38c034cdabd0a13330abcc4855c866f53d2e0</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>

View File

@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:27:21 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:27:57 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following paths:</span>

View File

@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:27:42 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:28:20 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following paths:</span>
@@ -673,6 +673,7 @@
<li><a href="https://lists.gnu.org/archive/html/bug-tar/2025-08/msg00012.html">https://lists.gnu.org/archive/html/bug-tar/2025-08/msg00012.html</a></li>
<li><a href="https://www.gnu.org/software/tar/manual/html_node/Integrity.html">https://www.gnu.org/software/tar/manual/html_node/Integrity.html</a></li>
<li><a href="https://www.gnu.org/software/tar/manual/html_node/Security-rules-of-thumb.html">https://www.gnu.org/software/tar/manual/html_node/Security-rules-of-thumb.html</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/11/01/6">http://www.openwall.com/lists/oss-security/2025/11/01/6</a></li>
</ul>
<hr/>
@@ -926,6 +927,7 @@
<li><a href="https://access.redhat.com/errata/RHSA-2025:15827">https://access.redhat.com/errata/RHSA-2025:15827</a></li>
<li><a href="https://access.redhat.com/errata/RHSA-2025:16524">https://access.redhat.com/errata/RHSA-2025:16524</a></li>
<li><a href="https://access.redhat.com/errata/RHSA-2025:18219">https://access.redhat.com/errata/RHSA-2025:18219</a></li>
<li><a href="https://access.redhat.com/errata/RHSA-2025:17181">https://access.redhat.com/errata/RHSA-2025:17181</a></li>
</ul>
<hr/>
@@ -1920,7 +1922,7 @@
<em>See <code>How to fix?</code> for <code>Ubuntu:24.04</code> relevant fixed versions and status.</em></p>
<p>A flaw was found in libssh, a library that implements the SSH protocol. When calculating the session ID during the key exchange (KEX) process, an allocation failure in cryptographic functions may lead to a NULL pointer dereference. This issue can cause the client or server to crash.</p>
<h2 id="remediation">Remediation</h2>
<p>There is no fixed version for <code>Ubuntu:24.04</code> <code>libssh</code>.</p>
<p>Upgrade <code>Ubuntu:24.04</code> <code>libssh</code> to version 0.10.6-2ubuntu0.2 or higher.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="http://people.ubuntu.com/~ubuntu-security/cve/CVE-2025-8114">http://people.ubuntu.com/~ubuntu-security/cve/CVE-2025-8114</a></li>
@@ -2416,6 +2418,7 @@
<li><a href="https://curl.se/docs/CVE-2025-9086.html">https://curl.se/docs/CVE-2025-9086.html</a></li>
<li><a href="https://curl.se/docs/CVE-2025-9086.json">https://curl.se/docs/CVE-2025-9086.json</a></li>
<li><a href="https://hackerone.com/reports/3294999">https://hackerone.com/reports/3294999</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/10/1">http://www.openwall.com/lists/oss-security/2025/09/10/1</a></li>
</ul>
<hr/>
@@ -2499,6 +2502,8 @@
<li><a href="https://curl.se/docs/CVE-2025-10148.html">https://curl.se/docs/CVE-2025-10148.html</a></li>
<li><a href="https://curl.se/docs/CVE-2025-10148.json">https://curl.se/docs/CVE-2025-10148.json</a></li>
<li><a href="https://hackerone.com/reports/3330839">https://hackerone.com/reports/3330839</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/10/2">http://www.openwall.com/lists/oss-security/2025/09/10/2</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/10/3">http://www.openwall.com/lists/oss-security/2025/09/10/3</a></li>
</ul>
<hr/>

View File

@@ -456,7 +456,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:26:40 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:27:14 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following path:</span>

View File

@@ -456,7 +456,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:26:50 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:27:24 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following path:</span>

View File

@@ -7,7 +7,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Snyk test report</title>
<meta name="description" content="10 known vulnerabilities found in 33 vulnerable dependency paths.">
<meta name="description" content="11 known vulnerabilities found in 35 vulnerable dependency paths.">
<base target="_blank">
<link rel="icon" type="image/png" href="https://res.cloudinary.com/snyk/image/upload/v1468845142/favicon/favicon.png"
sizes="194x194">
@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:24:33 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:25:14 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following paths:</span>
@@ -499,8 +499,8 @@
</div>
<div class="meta-counts">
<div class="meta-count"><span>10</span> <span>known vulnerabilities</span></div>
<div class="meta-count"><span>33 vulnerable dependency paths</span></div>
<div class="meta-count"><span>11</span> <span>known vulnerabilities</span></div>
<div class="meta-count"><span>35 vulnerable dependency paths</span></div>
<div class="meta-count"><span>2115</span> <span>dependencies</span></div>
</div><!-- .meta-counts -->
</div><!-- .layout-container--short -->
@@ -782,9 +782,10 @@
<h3 id="for-more-information-on-this-vulnerability-type">For more information on this vulnerability type:</h3>
<p><a href="https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript_prototype_pollution_attack_in_NodeJS.pdf">Arteau, Oliver. “JavaScript prototype pollution attack in NodeJS application.” GitHub, 26 May 2018</a></p>
<h2 id="remediation">Remediation</h2>
<p>There is no fixed version for <code>min-document</code>.</p>
<p>Upgrade <code>min-document</code> to version 2.19.1 or higher.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="https://github.com/Raynos/min-document/commit/6c5f31aa57e2122fcedd4c7eae58b82f477e09f5">Github Commit</a></li>
<li><a href="https://github.com/Raynos/min-document/pull/55/commits/0d4e8192ef723fb869645256102a56ed922efd68">Github Commit</a></li>
<li><a href="https://github.com/Raynos/min-document/issues/54">GitHub Issue</a></li>
<li><a href="https://github.com/OrangeShieldInfos/PoCs/tree/main/JavaScript/prototype-pollution/CVE-2025-57352">POC</a></li>
@@ -797,6 +798,173 @@
<p><a href="https://snyk.io/vuln/SNYK-JS-MINDOCUMENT-13045385">More about this vulnerability</a></p>
</div>
</div><!-- .card -->
<div class="card card--vuln disclosure--not-new severity--medium" data-snyk-test="medium">
<h2 class="card__title">Prototype Pollution</h2>
<div class="card__section">
<div class="card__labels">
<div class="label label--medium">
<span class="label__text">medium severity</span>
</div>
</div>
<hr/>
<ul class="card__meta">
<li class="card__meta__item">
Manifest file: /argo-cd <span class="list-paths__item__arrow"></span> ui/yarn.lock
</li>
<li class="card__meta__item">
Package Manager: npm
</li>
<li class="card__meta__item">
Vulnerable module:
js-yaml
</li>
<li class="card__meta__item">Introduced through:
argo-cd-ui@1.0.0 and js-yaml@4.1.0
</li>
</ul>
<hr/>
<h3 class="card__section__title">Detailed paths</h3>
<ul class="card__meta__paths">
<li>
<span class="list-paths__item__introduced"><em>Introduced through</em>:
argo-cd-ui@1.0.0
<span class="list-paths__item__arrow"></span>
js-yaml@4.1.0
</span>
</li>
<li>
<span class="list-paths__item__introduced"><em>Introduced through</em>:
argo-cd-ui@1.0.0
<span class="list-paths__item__arrow"></span>
redoc@2.4.0
<span class="list-paths__item__arrow"></span>
@redocly/openapi-core@1.30.0
<span class="list-paths__item__arrow"></span>
js-yaml@4.1.0
</span>
</li>
</ul><!-- .list-paths -->
</div><!-- .card__section -->
<hr/>
<!-- Overview -->
<h2 id="overview">Overview</h2>
<p><a href="https://www.npmjs.com/package/js-yaml">js-yaml</a> is a human-friendly data serialization language.</p>
<p>Affected versions of this package are vulnerable to Prototype Pollution via the <code>merge</code> function. An attacker can alter object prototypes by supplying specially crafted YAML documents containing <code>__proto__</code> properties. This can lead to unexpected behavior or security issues in applications that process untrusted YAML input.</p>
<h2 id="workaround">Workaround</h2>
<p>This vulnerability can be mitigated by running the server with <code>node --disable-proto=delete</code> or by using Deno, which has pollution protection enabled by default.</p>
<h2 id="details">Details</h2>
<p>Prototype Pollution is a vulnerability affecting JavaScript. Prototype Pollution refers to the ability to inject properties into existing JavaScript language construct prototypes, such as objects. JavaScript allows all Object attributes to be altered, including their magical attributes such as <code>__proto__</code>, <code>constructor</code> and <code>prototype</code>. An attacker manipulates these attributes to overwrite, or pollute, a JavaScript application object prototype of the base object by injecting other values. Properties on the <code>Object.prototype</code> are then inherited by all the JavaScript objects through the prototype chain. When that happens, this leads to either denial of service by triggering JavaScript exceptions, or it tampers with the application source code to force the code path that the attacker injects, thereby leading to remote code execution.</p>
<p>There are two main ways in which the pollution of prototypes occurs:</p>
<ul>
<li><p>Unsafe <code>Object</code> recursive merge</p>
</li>
<li><p>Property definition by path</p>
</li>
</ul>
<h3 id="unsafe-object-recursive-merge">Unsafe Object recursive merge</h3>
<p>The logic of a vulnerable recursive merge function follows the following high-level model:</p>
<pre><code>merge (target, source)
foreach property of source
if property exists and is an object on both the target and the source
merge(target[property], source[property])
else
target[property] = source[property]
</code></pre>
<br>
<p>When the source object contains a property named <code>__proto__</code> defined with <code>Object.defineProperty()</code> , the condition that checks if the property exists and is an object on both the target and the source passes and the merge recurses with the target, being the prototype of <code>Object</code> and the source of <code>Object</code> as defined by the attacker. Properties are then copied on the <code>Object</code> prototype.</p>
<p>Clone operations are a special sub-class of unsafe recursive merges, which occur when a recursive merge is conducted on an empty object: <code>merge({},source)</code>.</p>
<p><code>lodash</code> and <code>Hoek</code> are examples of libraries susceptible to recursive merge attacks.</p>
<h3 id="property-definition-by-path">Property definition by path</h3>
<p>There are a few JavaScript libraries that use an API to define property values on an object based on a given path. The function that is generally affected contains this signature: <code>theFunction(object, path, value)</code></p>
<p>If the attacker can control the value of “path”, they can set this value to <code>__proto__.myValue</code>. <code>myValue</code> is then assigned to the prototype of the class of the object.</p>
<h2 id="types-of-attacks">Types of attacks</h2>
<p>There are a few methods by which Prototype Pollution can be manipulated:</p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Origin</th>
<th>Short description</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Denial of service (DoS)</strong></td>
<td>Client</td>
<td>This is the most likely attack. <br>DoS occurs when <code>Object</code> holds generic functions that are implicitly called for various operations (for example, <code>toString</code> and <code>valueOf</code>). <br> The attacker pollutes <code>Object.prototype.someattr</code> and alters its state to an unexpected value such as <code>Int</code> or <code>Object</code>. In this case, the code fails and is likely to cause a denial of service. <br><strong>For example:</strong> if an attacker pollutes <code>Object.prototype.toString</code> by defining it as an integer, if the codebase at any point was reliant on <code>someobject.toString()</code> it would fail.</td>
</tr>
<tr>
<td><strong>Remote Code Execution</strong></td>
<td>Client</td>
<td>Remote code execution is generally only possible in cases where the codebase evaluates a specific attribute of an object, and then executes that evaluation.<br><strong>For example:</strong> <code>eval(someobject.someattr)</code>. In this case, if the attacker pollutes <code>Object.prototype.someattr</code> they are likely to be able to leverage this in order to execute code.</td>
</tr>
<tr>
<td><strong>Property Injection</strong></td>
<td>Client</td>
<td>The attacker pollutes properties that the codebase relies on for their informative value, including security properties such as cookies or tokens.<br> <strong>For example:</strong> if a codebase checks privileges for <code>someuser.isAdmin</code>, then when the attacker pollutes <code>Object.prototype.isAdmin</code> and sets it to equal <code>true</code>, they can then achieve admin privileges.</td>
</tr>
</tbody></table>
<h2 id="affected-environments">Affected environments</h2>
<p>The following environments are susceptible to a Prototype Pollution attack:</p>
<ul>
<li><p>Application server</p>
</li>
<li><p>Web server</p>
</li>
<li><p>Web browser</p>
</li>
</ul>
<h2 id="how-to-prevent">How to prevent</h2>
<ol>
<li><p>Freeze the prototype— use <code>Object.freeze (Object.prototype)</code>.</p>
</li>
<li><p>Require schema validation of JSON input.</p>
</li>
<li><p>Avoid using unsafe recursive merge functions.</p>
</li>
<li><p>Consider using objects without prototypes (for example, <code>Object.create(null)</code>), breaking the prototype chain and preventing pollution.</p>
</li>
<li><p>As a best practice use <code>Map</code> instead of <code>Object</code>.</p>
</li>
</ol>
<h3 id="for-more-information-on-this-vulnerability-type">For more information on this vulnerability type:</h3>
<p><a href="https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript_prototype_pollution_attack_in_NodeJS.pdf">Arteau, Oliver. “JavaScript prototype pollution attack in NodeJS application.” GitHub, 26 May 2018</a></p>
<h2 id="remediation">Remediation</h2>
<p>Upgrade <code>js-yaml</code> to version 4.1.1 or higher.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="https://github.com/nodeca/js-yaml/commit/383665ff4248ec2192d1274e934462bb30426879">GitHub Commit</a></li>
</ul>
<hr/>
<div class="cta card__cta">
<p><a href="https://snyk.io/vuln/SNYK-JS-JSYAML-13961110">More about this vulnerability</a></p>
</div>
</div><!-- .card -->
<div class="card card--vuln disclosure--not-new severity--medium" data-snyk-test="medium">
<h2 class="card__title">MPL-2.0 license</h2>

View File

@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:24:40 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:25:20 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following paths:</span>
@@ -2429,6 +2429,8 @@
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/c2b96348bfa662f25f4fabf81958ae822063dae3">https://github.openssl.org/openssl/extended-releases/commit/c2b96348bfa662f25f4fabf81958ae822063dae3</a></li>
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/dfbaf161d8dafc1132dd88cd48ad990ed9b4c8ba">https://github.openssl.org/openssl/extended-releases/commit/dfbaf161d8dafc1132dd88cd48ad990ed9b4c8ba</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2025/10/msg00001.html">https://lists.debian.org/debian-lts-announce/2025/10/msg00001.html</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -2581,6 +2583,7 @@
<li><a href="https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4">https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4</a></li>
<li><a href="https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2">https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -2738,6 +2741,7 @@
<li><a href="https://github.com/openssl/openssl/commit/89e790ac431125a4849992858490bed6b225eadf">https://github.com/openssl/openssl/commit/89e790ac431125a4849992858490bed6b225eadf</a></li>
<li><a href="https://github.com/openssl/openssl/commit/bbf38c034cdabd0a13330abcc4855c866f53d2e0">https://github.com/openssl/openssl/commit/bbf38c034cdabd0a13330abcc4855c866f53d2e0</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>

View File

@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:24:44 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:25:25 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following path:</span>
@@ -694,6 +694,8 @@
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/c2b96348bfa662f25f4fabf81958ae822063dae3">https://github.openssl.org/openssl/extended-releases/commit/c2b96348bfa662f25f4fabf81958ae822063dae3</a></li>
<li><a href="https://github.openssl.org/openssl/extended-releases/commit/dfbaf161d8dafc1132dd88cd48ad990ed9b4c8ba">https://github.openssl.org/openssl/extended-releases/commit/dfbaf161d8dafc1132dd88cd48ad990ed9b4c8ba</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="https://lists.debian.org/debian-lts-announce/2025/10/msg00001.html">https://lists.debian.org/debian-lts-announce/2025/10/msg00001.html</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -879,6 +881,7 @@
<li><a href="https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4">https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4</a></li>
<li><a href="https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2">https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>
@@ -1069,6 +1072,7 @@
<li><a href="https://github.com/openssl/openssl/commit/89e790ac431125a4849992858490bed6b225eadf">https://github.com/openssl/openssl/commit/89e790ac431125a4849992858490bed6b225eadf</a></li>
<li><a href="https://github.com/openssl/openssl/commit/bbf38c034cdabd0a13330abcc4855c866f53d2e0">https://github.com/openssl/openssl/commit/bbf38c034cdabd0a13330abcc4855c866f53d2e0</a></li>
<li><a href="https://openssl-library.org/news/secadv/20250930.txt">https://openssl-library.org/news/secadv/20250930.txt</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/30/5">http://www.openwall.com/lists/oss-security/2025/09/30/5</a></li>
</ul>
<hr/>

View File

@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:24:56 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:25:32 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following path:</span>

View File

@@ -7,7 +7,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Snyk test report</title>
<meta name="description" content="19 known vulnerabilities found in 55 vulnerable dependency paths.">
<meta name="description" content="20 known vulnerabilities found in 56 vulnerable dependency paths.">
<base target="_blank">
<link rel="icon" type="image/png" href="https://res.cloudinary.com/snyk/image/upload/v1468845142/favicon/favicon.png"
sizes="194x194">
@@ -487,7 +487,7 @@
<div class="header-wrap">
<h1 class="project__header__title">Snyk test report</h1>
<p class="timestamp">November 2nd 2025, 12:25:21 am (UTC+00:00)</p>
<p class="timestamp">November 16th 2025, 12:25:55 am (UTC+00:00)</p>
</div>
<div class="source-panel">
<span>Scanned the following paths:</span>
@@ -501,8 +501,8 @@
</div>
<div class="meta-counts">
<div class="meta-count"><span>19</span> <span>known vulnerabilities</span></div>
<div class="meta-count"><span>55 vulnerable dependency paths</span></div>
<div class="meta-count"><span>20</span> <span>known vulnerabilities</span></div>
<div class="meta-count"><span>56 vulnerable dependency paths</span></div>
<div class="meta-count"><span>2322</span> <span>dependencies</span></div>
</div><!-- .meta-counts -->
</div><!-- .layout-container--short -->
@@ -671,6 +671,7 @@
<li><a href="https://lists.gnu.org/archive/html/bug-tar/2025-08/msg00012.html">https://lists.gnu.org/archive/html/bug-tar/2025-08/msg00012.html</a></li>
<li><a href="https://www.gnu.org/software/tar/manual/html_node/Integrity.html">https://www.gnu.org/software/tar/manual/html_node/Integrity.html</a></li>
<li><a href="https://www.gnu.org/software/tar/manual/html_node/Security-rules-of-thumb.html">https://www.gnu.org/software/tar/manual/html_node/Security-rules-of-thumb.html</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/11/01/6">http://www.openwall.com/lists/oss-security/2025/11/01/6</a></li>
</ul>
<hr/>
@@ -946,6 +947,7 @@
<li><a href="https://access.redhat.com/errata/RHSA-2025:15827">https://access.redhat.com/errata/RHSA-2025:15827</a></li>
<li><a href="https://access.redhat.com/errata/RHSA-2025:16524">https://access.redhat.com/errata/RHSA-2025:16524</a></li>
<li><a href="https://access.redhat.com/errata/RHSA-2025:18219">https://access.redhat.com/errata/RHSA-2025:18219</a></li>
<li><a href="https://access.redhat.com/errata/RHSA-2025:17181">https://access.redhat.com/errata/RHSA-2025:17181</a></li>
</ul>
<hr/>
@@ -1421,6 +1423,77 @@
<p><a href="https://snyk.io/vuln/SNYK-UBUNTU2504-GIT-9792199">More about this vulnerability</a></p>
</div>
</div><!-- .card -->
<div class="card card--vuln disclosure--not-new severity--medium" data-snyk-test="medium">
<h2 class="card__title">CVE-2025-11563</h2>
<div class="card__section">
<div class="card__labels">
<div class="label label--medium">
<span class="label__text">medium severity</span>
</div>
</div>
<hr/>
<ul class="card__meta">
<li class="card__meta__item">
Manifest file: quay.io/argoproj/argocd:v3.2.0-rc4/argoproj/argocd <span class="list-paths__item__arrow"></span> Dockerfile
</li>
<li class="card__meta__item">
Package Manager: ubuntu:25.04
</li>
<li class="card__meta__item">
Vulnerable module:
curl/libcurl3t64-gnutls
</li>
<li class="card__meta__item">Introduced through:
docker-image|quay.io/argoproj/argocd@v3.2.0-rc4, git@1:2.48.1-0ubuntu1.1 and others
</li>
</ul>
<hr/>
<h3 class="card__section__title">Detailed paths</h3>
<ul class="card__meta__paths">
<li>
<span class="list-paths__item__introduced"><em>Introduced through</em>:
docker-image|quay.io/argoproj/argocd@v3.2.0-rc4
<span class="list-paths__item__arrow"></span>
git@1:2.48.1-0ubuntu1.1
<span class="list-paths__item__arrow"></span>
curl/libcurl3t64-gnutls@8.12.1-3ubuntu1
</span>
</li>
</ul><!-- .list-paths -->
</div><!-- .card__section -->
<hr/>
<!-- Overview -->
<h2 id="nvd-description">NVD Description</h2>
<p><em>This vulnerability has not been analyzed by NVD yet.</em></p>
<h2 id="remediation">Remediation</h2>
<p>There is no fixed version for <code>Ubuntu:25.04</code> <code>curl</code>.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="http://people.ubuntu.com/~ubuntu-security/cve/CVE-2025-11563">http://people.ubuntu.com/~ubuntu-security/cve/CVE-2025-11563</a></li>
</ul>
<hr/>
<div class="cta card__cta">
<p><a href="https://snyk.io/vuln/SNYK-UBUNTU2504-CURL-13842495">More about this vulnerability</a></p>
</div>
</div><!-- .card -->
<div class="card card--vuln disclosure--not-new severity--low" data-snyk-test="low">
<h2 class="card__title">CVE-2024-56433</h2>
@@ -2153,6 +2226,7 @@
<li><a href="https://curl.se/docs/CVE-2025-9086.html">https://curl.se/docs/CVE-2025-9086.html</a></li>
<li><a href="https://curl.se/docs/CVE-2025-9086.json">https://curl.se/docs/CVE-2025-9086.json</a></li>
<li><a href="https://hackerone.com/reports/3294999">https://hackerone.com/reports/3294999</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/10/1">http://www.openwall.com/lists/oss-security/2025/09/10/1</a></li>
</ul>
<hr/>
@@ -2236,6 +2310,8 @@
<li><a href="https://curl.se/docs/CVE-2025-10148.html">https://curl.se/docs/CVE-2025-10148.html</a></li>
<li><a href="https://curl.se/docs/CVE-2025-10148.json">https://curl.se/docs/CVE-2025-10148.json</a></li>
<li><a href="https://hackerone.com/reports/3330839">https://hackerone.com/reports/3330839</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/10/2">http://www.openwall.com/lists/oss-security/2025/09/10/2</a></li>
<li><a href="http://www.openwall.com/lists/oss-security/2025/09/10/3">http://www.openwall.com/lists/oss-security/2025/09/10/3</a></li>
</ul>
<hr/>

View File

@@ -9,6 +9,7 @@
| argocd.argoproj.io/hook | any | [see resource hooks docs](resource_hooks.md) | Used to configure [resource hooks](resource_hooks.md). |
| argocd.argoproj.io/hook-delete-policy | any | [see resource hooks docs](resource_hooks.md#hook-deletion-policies) | Used to set a [resource hook's deletion policy](resource_hooks.md#hook-deletion-policies). |
| argocd.argoproj.io/manifest-generate-paths | Application | [see scaling docs](../operator-manual/high_availability.md#webhook-and-manifest-paths-annotation) | Used to avoid unnecessary Application refreshes, especially in mono-repos. |
| argocd.argoproj.io/managed-by-url | Application | A valid http(s) URL | Specifies the URL of the Argo CD instance managing the application. Used to correctly link to applications managed by a different Argo CD instance. See [managed-by-url docs](../operator-manual/managed-by-url.md) for details. |
| argocd.argoproj.io/refresh | Application | `normal`, `hard` | Indicates that app needs to be refreshed. Removed by application controller after app is refreshed. Value `"hard"` means manifest cache and target cluster state cache should be invalidated before refresh. |
| argocd.argoproj.io/skip-reconcile | Application | `"true"` | Indicates to the Argo CD application controller that the Application should not be reconciled. See the [skip reconcile documentation](skip_reconcile.md) for use cases. |
| argocd.argoproj.io/sync-options | any | [see sync options docs](sync-options.md) | Provides a variety of settings to determine how an Application's resources are synced. |

View File

@@ -58,3 +58,120 @@ Argo CD performs [background cascading deletion](https://kubernetes.io/docs/conc
When you invoke `argocd app delete` with `--cascade`, the finalizer is added automatically.
You can set the propagation policy with `--propagation-policy <foreground|background>`.
## Deleting Applications in the UI
Argo CD provides a consistent deletion experience across different views in the UI. When deleting applications, you can access the delete functionality from:
- **Applications List View**: The main applications page showing all applications
- **Application Details View - Resource Tree**: When viewing an application's resource tree that contains child applications
### Consistent Deletion Behaviour
Starting in Argo CD 3.2, deletion behavior is now **consistent** across all UI views. Whether you delete an application from the Applications List or from the Resource Tree view, the same deletion mechanism and options are used.
Previously, deleting an application from the Resource Tree treated it as a generic Kubernetes resource, which could lead to unexpected behaviour with non-cascading deletes. Now, Argo CD properly detects Application resources and uses the standard Application deletion API in all contexts.
### Deleting Child Applications in App of Apps Pattern
When using the [App of Apps pattern](../operator-manual/cluster-bootstrapping.md), parent applications can contain child applications as resources. Argo CD automatically detects child applications and provides improved dialog messages to help you understand what you're deleting.
#### Child Application Detection
Argo CD identifies a child application by checking for the `app.kubernetes.io/part-of` label. If this label is present and has a non-empty value, the application is considered a child application.
#### Delete Dialog Differences
**When deleting a child application:**
- Dialog title: "Delete child application"
- Confirmation prompt references "child application" to make it clear you're deleting a managed application
- Additional warning note appears when deleting from the Resource Tree
**When deleting a regular application:**
- Dialog title: "Delete application"
- Standard confirmation prompt
**When deleting from the Resource Tree:**
An additional informational note appears:
> ⚠️ **Note:** You are about to delete an Application from the resource tree. This uses the same deletion behaviour as the Applications list page.
This note clarifies that the deletion will use the proper Application deletion API, not generic Kubernetes resource deletion.
### Deletion Options (Propagation Policies)
When deleting an application through the UI, you can choose from three propagation policies:
#### 1. Foreground (Default)
- Deletes the application and all its managed resources
- Waits for all managed resources to be deleted before the Application is removed
- **Use case**: When you want to ensure all resources are cleaned up before the Application disappears
#### 2. Background
- Deletes the application and all its managed resources
- The Application is removed immediately, and resources are deleted in the background
- **Use case**: When you want faster Application deletion and don't need to wait for resource cleanup
#### 3. Non-Cascading (Orphan)
- Deletes **only** the Application resource
- All managed resources (Deployments, Services, ConfigMaps, etc.) are **preserved** in the cluster
- The finalizer is removed automatically before deletion
- **Use case**: When you want to stop managing resources through Argo CD but keep them running
> [!WARNING]
> **Important for Non-Cascading Deletes**
>
> When you select **Non-Cascading**, Argo CD will:
> - Remove the `resources-finalizer.argocd.argoproj.io` finalizer from the Application
> - Delete only the Application resource
> - Leave all managed resources (Pods, Services, Deployments, etc.) running in the cluster
>
> This behaviour is now **consistent** whether you delete from the Applications List or from the Resource Tree view.
### Best Practices for App of Apps Pattern
When working with the App of Apps pattern:
1. **Understand the impact**: Deleting a child application with Foreground or Background propagation will delete all of its managed resources
2. **Review before deleting**: Always verify what resources are managed by the application before performing a cascading delete
3. **Use Non-Cascading cautiously**: If you only want to remove the Application resource but keep the deployed workloads, use Non-Cascading delete
4. **Consider finalizers**: Ensure child applications have appropriate finalizers set based on your deletion strategy (see [Cascading Deletion](../operator-manual/cluster-bootstrapping.md#cascading-deletion))
### Example Scenarios
#### Scenario 1: Deleting a child application and all its resources
1. Navigate to the parent application's Resource Tree
2. Click the kebab menu (button with the three vertical dots) on a child Application resource
3. Select "Delete"
4. Choose **Foreground** or **Background** propagation policy
5. Confirm the deletion
**Result**: The child Application and all its managed resources (Deployments, Services, etc.) are deleted.
#### Scenario 2: Removing Argo CD management but keeping resources
1. Navigate to the Applications List or the parent application's Resource Tree
2. Click the kebab menu (button with the three vertical dots) on a child Application resource
3. Select "Delete"
4. Choose **Non-Cascading** propagation policy
5. Confirm the deletion
**Result**: Only the Application resource is deleted. All managed resources continue running in the cluster.
#### Scenario 3: Deleting from Resource Tree with context awareness
When you delete a child application from the Resource Tree view:
- Argo CD recognizes it as an Application resource (not just a generic Kubernetes resource)
- Shows "Delete child application" dialog if it detects the `app.kubernetes.io/part-of` label
- Displays an informational note explaining you're using the same behaviour as the Applications List
- Provides the same three propagation policy options
This ensures predictable and consistent deletion behaviour regardless of where you initiate the deletion.

View File

@@ -251,7 +251,7 @@ metadata:
argocd.argoproj.io/sync-options: ServerSideApply=true
```
If you want to disable ServerSideApply for a specific resource, while it is enabled at the application level,
If you want to disable ServerSideApply for a specific resource, while it is enabled at the application level,
add the following sync-option annotation in it:
```yaml
@@ -305,7 +305,7 @@ kind: Application
spec:
syncPolicy:
syncOptions:
- DisableClientSideApplyMigration=true
- ClientSideApplyMigration=false
```
You can specify a custom field manager for the client-side apply migration using an annotation:
@@ -435,7 +435,7 @@ spec:
In the case where Argo CD is "adopting" an existing namespace which already has metadata set on it, you should first
[upgrade the resource to server-side apply](https://kubernetes.io/docs/reference/using-api/server-side-apply/#upgrading-from-client-side-apply-to-server-side-apply)
before enabling `managedNamespaceMetadata`. Argo CD relies on `kubectl`, which does not support managing
before enabling `managedNamespaceMetadata`. Argo CD relies on `kubectl`, which does not support managing
client-side-applied resources with server-side-applies. If you do not upgrade the resource to server-side apply, Argo CD
may remove existing labels/annotations, which may or may not be the desired behavior.

View File

@@ -46,6 +46,7 @@ This can take the following values:
| `HookFailed` | The hook resource is deleted after the hook failed. |
| `BeforeHookCreation` | Any existing hook resource is deleted before the new one is created (since v1.3). It is meant to be used with `/metadata/name`. |
Note that if no deletion policy is specified, Argo CD will automatically assume `BeforeHookCreation` rules.
## How sync waves work?

View File

@@ -606,6 +606,10 @@ func (c *clusterCache) listResources(ctx context.Context, resClient dynamic.Reso
retryCount++
c.log.Info(fmt.Sprintf("Error while listing resources: %v (try %d/%d)", ierr, retryCount, c.listRetryLimit))
}
// Ensure res is never nil even when there's an error
if res == nil {
res = &unstructured.UnstructuredList{}
}
//nolint:wrapcheck // wrap outside the retry
return ierr
}

View File

@@ -0,0 +1,109 @@
package cache
import (
"context"
"errors"
"testing"
"golang.org/x/sync/semaphore"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/tools/pager"
"k8s.io/klog/v2/textlogger"
)
// mockResourceInterface simulates a dynamic resource interface that returns (nil, error)
type mockResourceInterface struct{}
func (m *mockResourceInterface) Create(ctx context.Context, obj *unstructured.Unstructured, options metav1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) {
return nil, errors.New("not implemented")
}
func (m *mockResourceInterface) Update(ctx context.Context, obj *unstructured.Unstructured, options metav1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) {
return nil, errors.New("not implemented")
}
func (m *mockResourceInterface) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options metav1.UpdateOptions) (*unstructured.Unstructured, error) {
return nil, errors.New("not implemented")
}
func (m *mockResourceInterface) Delete(ctx context.Context, name string, options metav1.DeleteOptions, subresources ...string) error {
return errors.New("not implemented")
}
func (m *mockResourceInterface) DeleteCollection(ctx context.Context, options metav1.DeleteOptions, listOptions metav1.ListOptions) error {
return errors.New("not implemented")
}
func (m *mockResourceInterface) Get(ctx context.Context, name string, options metav1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) {
return nil, errors.New("not implemented")
}
func (m *mockResourceInterface) List(ctx context.Context, opts metav1.ListOptions) (*unstructured.UnstructuredList, error) {
// This simulates the problematic behavior that caused the original panic:
// returning (nil, error) instead of (emptyList, error)
return nil, errors.New("simulated list failure")
}
func (m *mockResourceInterface) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) {
return nil, errors.New("not implemented")
}
func (m *mockResourceInterface) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options metav1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) {
return nil, errors.New("not implemented")
}
func (m *mockResourceInterface) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options metav1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) {
return nil, errors.New("not implemented")
}
func (m *mockResourceInterface) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options metav1.ApplyOptions) (*unstructured.Unstructured, error) {
return nil, errors.New("not implemented")
}
func (m *mockResourceInterface) Namespace(string) dynamic.ResourceInterface {
return m
}
// TestListResourcesNilPointerFix tests that our fix prevents panic when
// resClient.List() returns (nil, error)
func TestListResourcesNilPointerFix(t *testing.T) {
// Create a cluster cache with proper configuration
cache := &clusterCache{
listSemaphore: semaphore.NewWeighted(1),
listPageSize: 100,
listPageBufferSize: 1,
listRetryLimit: 1,
listRetryUseBackoff: false,
listRetryFunc: ListRetryFuncNever,
log: textlogger.NewLogger(textlogger.NewConfig()),
}
// Use our mock that returns (nil, error)
mockClient := &mockResourceInterface{}
// This should not panic even though mockClient.List() returns (nil, error)
_, err := cache.listResources(context.Background(), mockClient, func(listPager *pager.ListPager) error {
// The fix ensures the pager receives a non-nil UnstructuredList
// preventing panic in GetContinue()
return listPager.EachListItem(context.Background(), metav1.ListOptions{}, func(obj runtime.Object) error {
return nil
})
})
// We expect an error (wrapped), but no panic should occur
if err == nil {
t.Fatal("Expected error from listResources due to simulated failure")
}
// Check that the error is properly wrapped
if err.Error() != "failed to list resources: simulated list failure" {
t.Fatalf("Unexpected error message: %v", err.Error())
}
t.Log("Test passed: no panic occurred despite (nil, error) from resClient.List()")
}

View File

@@ -183,6 +183,9 @@ func serverSideDiff(config, live *unstructured.Unstructured, opts ...Option) (*D
}
}
// Remarshal predictedLive to ensure it receives the same normalization as live.
predictedLive = remarshal(predictedLive, o)
Normalize(predictedLive, opts...)
unstructured.RemoveNestedField(predictedLive.Object, "metadata", "managedFields")

View File

@@ -1607,6 +1607,68 @@ metadata:
assert.False(t, ok)
}
func TestRemarshalStatefulSetCreationTimestamp(t *testing.T) {
manifest := []byte(`
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: test-sts
creationTimestamp: "2025-11-06T19:35:31Z"
spec:
serviceName: test
selector:
matchLabels:
app: test
template:
metadata:
creationTimestamp: null
labels:
app: test
spec:
containers:
- name: test
image: nginx
volumeClaimTemplates:
- metadata:
name: data
creationTimestamp: null
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
`)
var un unstructured.Unstructured
require.NoError(t, yaml.Unmarshal(manifest, &un))
// Verify creationTimestamp exists in nested metadata before remarshal
spec := un.Object["spec"].(map[string]any)
templateMetadata := spec["template"].(map[string]any)["metadata"].(map[string]any)
_, ok := templateMetadata["creationTimestamp"]
assert.True(t, ok, "creationTimestamp should exist in template.metadata before remarshal")
volumeClaimTemplates := spec["volumeClaimTemplates"].([]any)
vctMetadata := volumeClaimTemplates[0].(map[string]any)["metadata"].(map[string]any)
_, ok = vctMetadata["creationTimestamp"]
assert.True(t, ok, "creationTimestamp should exist in volumeClaimTemplates[0].metadata before remarshal")
// Remarshal
newUn := remarshal(&un, applyOptions(diffOptionsForTest()))
// Verify creationTimestamp is removed from nested metadata after remarshal
// (top-level metadata.creationTimestamp is preserved as it's part of the resource identity)
spec = newUn.Object["spec"].(map[string]any)
templateMetadata = spec["template"].(map[string]any)["metadata"].(map[string]any)
_, ok = templateMetadata["creationTimestamp"]
assert.False(t, ok, "creationTimestamp should be removed from template.metadata after remarshal")
volumeClaimTemplates = spec["volumeClaimTemplates"].([]any)
vctMetadata = volumeClaimTemplates[0].(map[string]any)["metadata"].(map[string]any)
_, ok = vctMetadata["creationTimestamp"]
assert.False(t, ok, "creationTimestamp should be removed from volumeClaimTemplates[0].metadata after remarshal")
}
func TestRemarshalResources(t *testing.T) {
getRequests := func(un *unstructured.Unstructured) map[string]any {
return un.Object["spec"].(map[string]any)["containers"].([]any)[0].(map[string]any)["resources"].(map[string]any)["requests"].(map[string]any)

67
go.mod
View File

@@ -3,29 +3,29 @@ module github.com/argoproj/argo-cd/v3
go 1.25.0
require (
code.gitea.io/sdk/gitea v0.22.0
code.gitea.io/sdk/gitea v0.22.1
dario.cat/mergo v1.0.2
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.0
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1
github.com/Azure/kubelogin v0.2.12
github.com/Masterminds/semver/v3 v3.4.0
github.com/Masterminds/sprig/v3 v3.3.0
github.com/TomOnTime/utfutil v1.0.0
github.com/alicebob/miniredis/v2 v2.35.0
github.com/argoproj/gitops-engine v0.7.1-0.20250908182407-97ad5b59a627
github.com/argoproj/notifications-engine v0.5.1-0.20251028200032-58cdc54685b4
github.com/argoproj/notifications-engine v0.5.1-0.20251105183712-783b97d496ca
github.com/argoproj/pkg v0.13.6
github.com/argoproj/pkg/v2 v2.0.1
github.com/aws/aws-sdk-go v1.55.7
github.com/bmatcuk/doublestar/v4 v4.9.1
github.com/bombsimon/logrusr/v4 v4.1.0
github.com/bradleyfalzon/ghinstallation/v2 v2.17.0
github.com/casbin/casbin/v2 v2.131.0
github.com/casbin/casbin/v2 v2.132.0
github.com/casbin/govaluate v1.10.0
github.com/cespare/xxhash/v2 v2.3.0
github.com/chainguard-dev/git-urls v1.0.2
github.com/coreos/go-oidc/v3 v3.14.1
github.com/cyphar/filepath-securejoin v0.4.1
github.com/cyphar/filepath-securejoin v0.6.0
github.com/dlclark/regexp2 v1.11.5
github.com/dustin/go-humanize v1.0.1
github.com/evanphx/json-patch v5.9.11+incompatible
@@ -37,8 +37,8 @@ require (
github.com/go-git/go-git/v5 v5.14.0
github.com/go-jose/go-jose/v4 v4.1.3
github.com/go-logr/logr v1.4.3
github.com/go-openapi/loads v0.23.1
github.com/go-openapi/runtime v0.29.0
github.com/go-openapi/loads v0.23.2
github.com/go-openapi/runtime v0.29.2
github.com/go-playground/webhooks/v6 v6.4.0
github.com/go-redis/cache/v9 v9.0.0
github.com/gobwas/glob v0.2.3
@@ -57,7 +57,7 @@ require (
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674
github.com/gosimple/slug v1.15.0
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3
github.com/grpc-ecosystem/grpc-gateway v1.16.0
github.com/hashicorp/go-retryablehttp v0.7.8
github.com/improbable-eng/grpc-web v0.15.1-0.20230209220825-1d9bbb09a099
@@ -70,7 +70,7 @@ require (
github.com/mattn/go-zglob v0.0.6
github.com/microsoft/azure-devops-go-api/azuredevops/v7 v7.1.1-0.20241014080628-3045bdf43455
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1
github.com/olekukonko/tablewriter v1.1.0
github.com/olekukonko/tablewriter v1.1.1
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.1.1
github.com/patrickmn/go-cache v2.1.1-0.20191004192108-46f407853014+incompatible
@@ -87,16 +87,16 @@ require (
github.com/stretchr/testify v1.11.1
github.com/valyala/fasttemplate v1.2.2
github.com/yuin/gopher-lua v1.1.1
gitlab.com/gitlab-org/api/client-go v0.157.1
gitlab.com/gitlab-org/api/client-go v0.160.0
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0
go.opentelemetry.io/otel v1.38.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0
go.opentelemetry.io/otel/sdk v1.38.0
golang.org/x/crypto v0.43.0
golang.org/x/net v0.46.0
golang.org/x/oauth2 v0.32.0
golang.org/x/sync v0.17.0
golang.org/x/term v0.36.0
golang.org/x/crypto v0.44.0
golang.org/x/net v0.47.0
golang.org/x/oauth2 v0.33.0
golang.org/x/sync v0.18.0
golang.org/x/term v0.37.0
golang.org/x/time v0.14.0
google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5
google.golang.org/grpc v1.76.0
@@ -123,6 +123,7 @@ require (
cloud.google.com/go/auth v0.15.0 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect
cloud.google.com/go/compute/metadata v0.7.0 // indirect
cyphar.com/go-pathrs v0.2.1 // indirect
github.com/42wim/httpsig v1.2.3 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect
@@ -134,7 +135,7 @@ require (
github.com/Azure/go-autorest/logger v0.2.1 // indirect
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
@@ -142,7 +143,6 @@ require (
github.com/PagerDuty/go-pagerduty v1.8.0 // indirect
github.com/ProtonMail/go-crypto v1.1.6 // indirect
github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20240116134246-a8cbe886bab0 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/aws/aws-sdk-go-v2 v1.36.3 // indirect
github.com/aws/aws-sdk-go-v2/config v1.29.9 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.17.62 // indirect
@@ -162,6 +162,9 @@ require (
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
github.com/chai2010/gettext-go v1.0.3 // indirect
github.com/clipperhouse/displaywidth v0.3.1 // indirect
github.com/clipperhouse/stringish v0.1.1 // indirect
github.com/clipperhouse/uax29/v2 v2.2.0 // indirect
github.com/cloudflare/circl v1.6.1 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
@@ -182,12 +185,12 @@ require (
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.6.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/analysis v0.24.0 // indirect
github.com/go-openapi/errors v0.22.3 // indirect
github.com/go-openapi/analysis v0.24.1 // indirect
github.com/go-openapi/errors v0.22.4 // indirect
github.com/go-openapi/jsonpointer v0.22.1 // indirect
github.com/go-openapi/jsonreference v0.21.2 // indirect
github.com/go-openapi/spec v0.22.0 // indirect
github.com/go-openapi/strfmt v0.24.0 // indirect
github.com/go-openapi/jsonreference v0.21.3 // indirect
github.com/go-openapi/spec v0.22.1 // indirect
github.com/go-openapi/strfmt v0.25.0 // indirect
github.com/go-openapi/swag v0.23.1 // indirect
github.com/go-openapi/swag/conv v0.25.1 // indirect
github.com/go-openapi/swag/fileutils v0.25.1 // indirect
@@ -198,7 +201,7 @@ require (
github.com/go-openapi/swag/stringutils v0.25.1 // indirect
github.com/go-openapi/swag/typeutils v0.25.1 // indirect
github.com/go-openapi/swag/yamlutils v0.25.1 // indirect
github.com/go-openapi/validate v0.25.0 // indirect
github.com/go-openapi/validate v0.25.1 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
github.com/golang/glog v1.2.5 // indirect
@@ -229,7 +232,7 @@ require (
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/mailru/easyjson v0.9.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mattn/go-runewidth v0.0.19 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
@@ -242,8 +245,9 @@ require (
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 // indirect
github.com/olekukonko/errors v1.1.0 // indirect
github.com/olekukonko/ll v0.0.9 // indirect
github.com/olekukonko/ll v0.1.2 // indirect
github.com/opsgenie/opsgenie-go-sdk-v2 v1.2.23 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pjbgf/sha1cd v0.3.2 // indirect
@@ -252,7 +256,6 @@ require (
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/common v0.66.1 // indirect
github.com/prometheus/procfs v0.16.1 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rs/cors v1.11.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
@@ -268,7 +271,7 @@ require (
github.com/x448/float16 v0.8.4 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
go.mongodb.org/mongo-driver v1.17.4 // indirect
go.mongodb.org/mongo-driver v1.17.6 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect
@@ -278,10 +281,10 @@ require (
go.yaml.in/yaml/v2 v2.4.2 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
golang.org/x/mod v0.28.0 // indirect
golang.org/x/sys v0.37.0 // indirect
golang.org/x/text v0.30.0 // indirect
golang.org/x/tools v0.37.0 // indirect
golang.org/x/mod v0.29.0 // indirect
golang.org/x/sys v0.38.0 // indirect
golang.org/x/text v0.31.0 // indirect
golang.org/x/tools v0.38.0 // indirect
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated // indirect
gomodules.xyz/envconfig v1.3.1-0.20190308184047-426f31af0d45 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect

133
go.sum
View File

@@ -37,17 +37,19 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
code.gitea.io/sdk/gitea v0.22.0 h1:HCKq7bX/HQ85Nw7c/HAhWgRye+vBp5nQOE8Md1+9Ef0=
code.gitea.io/sdk/gitea v0.22.0/go.mod h1:yyF5+GhljqvA30sRDreoyHILruNiy4ASufugzYg0VHM=
code.gitea.io/sdk/gitea v0.22.1 h1:7K05KjRORyTcTYULQ/AwvlVS6pawLcWyXZcTr7gHFyA=
code.gitea.io/sdk/gitea v0.22.1/go.mod h1:yyF5+GhljqvA30sRDreoyHILruNiy4ASufugzYg0VHM=
cyphar.com/go-pathrs v0.2.1 h1:9nx1vOgwVvX1mNBWDu93+vaceedpbsDqo+XuBGL40b8=
cyphar.com/go-pathrs v0.2.1/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc=
dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=
dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/42wim/httpsig v1.2.3 h1:xb0YyWhkYj57SPtfSttIobJUPJZB9as1nsfo7KWVcEs=
github.com/42wim/httpsig v1.2.3/go.mod h1:nZq9OlYKDrUBhptd77IHx4/sZZD+IxTBADvAPI9G/EM=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1 h1:5YTBM8QDVIBN3sxBil89WfdAAqDZbyJTgh688DSxX5w=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1/go.mod h1:YD5h/ldMsG0XiIw7PdyNhLxaM317eFh5yNLccNfGdyw=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.0 h1:KpMC6LFL7mqpExyMC9jVOYRiVhLmamjeZfRsUpB7l4s=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.0/go.mod h1:J7MUC/wtRpfGVbQ5sIItY5/FuVWmvzlY21WAOfQnq/I=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0 h1:JXg2dwJUmPB9JmtVmdEB16APJ7jurfbY5jnfXpJoRMc=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0/go.mod h1:YD5h/ldMsG0XiIw7PdyNhLxaM317eFh5yNLccNfGdyw=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 h1:Hk5QBxZQC1jb2Fwj6mpzme37xbCDdNTxU7O9eb5+LB4=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1/go.mod h1:IYus9qsFobWIc2YVwe/WPjcnyCkPKtnHAqUYeebc8z0=
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY=
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA=
@@ -74,8 +76,8 @@ github.com/Azure/kubelogin v0.2.12 h1:cF77bhIcbv1kcW7AG7Lk+brgwDv5WVcsbPwBFBSwuK
github.com/Azure/kubelogin v0.2.12/go.mod h1:PnSXkmJ9HMhyUiy5KpbeXITk0X9w7cTP5jH8w2DK4qM=
github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM=
github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE=
github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0 h1:XkkQbfMyuH2jTSjQjSoihryI8GINRcs4xp8lNawg0FI=
github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk=
github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 h1:XRzhVemXdgvJqCH0sFfrBUTnUJSBrBf7++ypk+twtRs=
github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Jeffail/gabs v1.4.0 h1://5fYRRTq1edjfIrQGvdkcd22pkYUrHZ5YC/H2GJVAo=
@@ -113,16 +115,14 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFI
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/appscode/go v0.0.0-20191119085241-0887d8ec2ecc/go.mod h1:OawnOmAL4ZX3YaPdN+8HTNwBveT1jMsqP74moa9XUbE=
github.com/argoproj/notifications-engine v0.5.1-0.20251028200032-58cdc54685b4 h1:3RZiddNmnwG+RMqjIcGoDIJTK5gq7TKDYI0mhGiHERk=
github.com/argoproj/notifications-engine v0.5.1-0.20251028200032-58cdc54685b4/go.mod h1:d1RazGXWvKRFv9//rg4MRRR7rbvbE7XLgTSMT5fITTE=
github.com/argoproj/notifications-engine v0.5.1-0.20251105183712-783b97d496ca h1:1fgy4PV3C0GL4CCR0KszhNCm3G5N9C+3gCRK0z1TMog=
github.com/argoproj/notifications-engine v0.5.1-0.20251105183712-783b97d496ca/go.mod h1:d1RazGXWvKRFv9//rg4MRRR7rbvbE7XLgTSMT5fITTE=
github.com/argoproj/pkg v0.13.6 h1:36WPD9MNYECHcO1/R1pj6teYspiK7uMQLCgLGft2abM=
github.com/argoproj/pkg v0.13.6/go.mod h1:I698DoJBKuvNFaixh4vFl2C88cNIT1WS7KCbz5ewyF8=
github.com/argoproj/pkg/v2 v2.0.1 h1:O/gCETzB/3+/hyFL/7d/VM/6pSOIRWIiBOTb2xqAHvc=
github.com/argoproj/pkg/v2 v2.0.1/go.mod h1:sdifF6sUTx9ifs38ZaiNMRJuMpSCBB9GulHfbPgQeRE=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/aws/aws-sdk-go v1.44.39/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE=
github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
@@ -173,8 +173,8 @@ github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdb
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/bwmarrin/discordgo v0.19.0/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q=
github.com/casbin/casbin/v2 v2.131.0 h1:JWkedeOpvxkBE7iIrWqf2RSMOU/xmxsxgbQ8QzsmGiQ=
github.com/casbin/casbin/v2 v2.131.0/go.mod h1:FmcfntdXLTcYXv/hxgNntcRPqAbwOG9xsism0yXT+18=
github.com/casbin/casbin/v2 v2.132.0 h1:73hGmOszGSL3hTVquwkAi98XLl3gPJ+BxB6D7G9Fxtk=
github.com/casbin/casbin/v2 v2.132.0/go.mod h1:FmcfntdXLTcYXv/hxgNntcRPqAbwOG9xsism0yXT+18=
github.com/casbin/govaluate v1.3.0/go.mod h1:G/UnbIjZk/0uMNaLwZZmFQrR72tYRZWQkO70si/iR7A=
github.com/casbin/govaluate v1.10.0 h1:ffGw51/hYH3w3rZcxO/KcaUIDOLP84w7nsidMVgaDG0=
github.com/casbin/govaluate v1.10.0/go.mod h1:G/UnbIjZk/0uMNaLwZZmFQrR72tYRZWQkO70si/iR7A=
@@ -204,6 +204,12 @@ github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObk
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/clipperhouse/displaywidth v0.3.1 h1:k07iN9gD32177o1y4O1jQMzbLdCrsGJh+blirVYybsk=
github.com/clipperhouse/displaywidth v0.3.1/go.mod h1:tgLJKKyaDOCadywag3agw4snxS5kYEuYR6Y9+qWDDYM=
github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=
github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA=
github.com/clipperhouse/uax29/v2 v2.2.0 h1:ChwIKnQN3kcZteTXMgb1wztSgaU+ZemkgWdohwgs8tY=
github.com/clipperhouse/uax29/v2 v2.2.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM=
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
@@ -217,8 +223,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6N
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
github.com/cyphar/filepath-securejoin v0.6.0 h1:BtGB77njd6SVO6VztOHfPxKitJvd/VPT+OFBFMOi1Is=
github.com/cyphar/filepath-securejoin v0.6.0/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
@@ -325,26 +331,26 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
github.com/go-openapi/analysis v0.24.0 h1:vE/VFFkICKyYuTWYnplQ+aVr45vlG6NcZKC7BdIXhsA=
github.com/go-openapi/analysis v0.24.0/go.mod h1:GLyoJA+bvmGGaHgpfeDh8ldpGo69fAJg7eeMDMRCIrw=
github.com/go-openapi/errors v0.22.3 h1:k6Hxa5Jg1TUyZnOwV2Lh81j8ayNw5VVYLvKrp4zFKFs=
github.com/go-openapi/errors v0.22.3/go.mod h1:+WvbaBBULWCOna//9B9TbLNGSFOfF8lY9dw4hGiEiKQ=
github.com/go-openapi/analysis v0.24.1 h1:Xp+7Yn/KOnVWYG8d+hPksOYnCYImE3TieBa7rBOesYM=
github.com/go-openapi/analysis v0.24.1/go.mod h1:dU+qxX7QGU1rl7IYhBC8bIfmWQdX4Buoea4TGtxXY84=
github.com/go-openapi/errors v0.22.4 h1:oi2K9mHTOb5DPW2Zjdzs/NIvwi2N3fARKaTJLdNabaM=
github.com/go-openapi/errors v0.22.4/go.mod h1:z9S8ASTUqx7+CP1Q8dD8ewGH/1JWFFLX/2PmAYNQLgk=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk=
github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM=
github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU=
github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ=
github.com/go-openapi/loads v0.23.1 h1:H8A0dX2KDHxDzc797h0+uiCZ5kwE2+VojaQVaTlXvS0=
github.com/go-openapi/loads v0.23.1/go.mod h1:hZSXkyACCWzWPQqizAv/Ye0yhi2zzHwMmoXQ6YQml44=
github.com/go-openapi/runtime v0.29.0 h1:Y7iDTFarS9XaFQ+fA+lBLngMwH6nYfqig1G+pHxMRO0=
github.com/go-openapi/runtime v0.29.0/go.mod h1:52HOkEmLL/fE4Pg3Kf9nxc9fYQn0UsIWyGjGIJE9dkg=
github.com/go-openapi/spec v0.22.0 h1:xT/EsX4frL3U09QviRIZXvkh80yibxQmtoEvyqug0Tw=
github.com/go-openapi/spec v0.22.0/go.mod h1:K0FhKxkez8YNS94XzF8YKEMULbFrRw4m15i2YUht4L0=
github.com/go-openapi/strfmt v0.24.0 h1:dDsopqbI3wrrlIzeXRbqMihRNnjzGC+ez4NQaAAJLuc=
github.com/go-openapi/strfmt v0.24.0/go.mod h1:Lnn1Bk9rZjXxU9VMADbEEOo7D7CDyKGLsSKekhFr7s4=
github.com/go-openapi/jsonreference v0.21.3 h1:96Dn+MRPa0nYAR8DR1E03SblB5FJvh7W6krPI0Z7qMc=
github.com/go-openapi/jsonreference v0.21.3/go.mod h1:RqkUP0MrLf37HqxZxrIAtTWW4ZJIK1VzduhXYBEeGc4=
github.com/go-openapi/loads v0.23.2 h1:rJXAcP7g1+lWyBHC7iTY+WAF0rprtM+pm8Jxv1uQJp4=
github.com/go-openapi/loads v0.23.2/go.mod h1:IEVw1GfRt/P2Pplkelxzj9BYFajiWOtY2nHZNj4UnWY=
github.com/go-openapi/runtime v0.29.2 h1:UmwSGWNmWQqKm1c2MGgXVpC2FTGwPDQeUsBMufc5Yj0=
github.com/go-openapi/runtime v0.29.2/go.mod h1:biq5kJXRJKBJxTDJXAa00DOTa/anflQPhT0/wmjuy+0=
github.com/go-openapi/spec v0.22.1 h1:beZMa5AVQzRspNjvhe5aG1/XyBSMeX1eEOs7dMoXh/k=
github.com/go-openapi/spec v0.22.1/go.mod h1:c7aeIQT175dVowfp7FeCvXXnjN/MrpaONStibD2WtDA=
github.com/go-openapi/strfmt v0.25.0 h1:7R0RX7mbKLa9EYCTHRcCuIPcaqlyQiWNPTXwClK0saQ=
github.com/go-openapi/strfmt v0.25.0/go.mod h1:nNXct7OzbwrMY9+5tLX4I21pzcmE6ccMGXl3jFdPfn8=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU=
@@ -369,8 +375,10 @@ github.com/go-openapi/swag/typeutils v0.25.1 h1:rD/9HsEQieewNt6/k+JBwkxuAHktFtH3
github.com/go-openapi/swag/typeutils v0.25.1/go.mod h1:9McMC/oCdS4BKwk2shEB7x17P6HmMmA6dQRtAkSnNb8=
github.com/go-openapi/swag/yamlutils v0.25.1 h1:mry5ez8joJwzvMbaTGLhw8pXUnhDK91oSJLDPF1bmGk=
github.com/go-openapi/swag/yamlutils v0.25.1/go.mod h1:cm9ywbzncy3y6uPm/97ysW8+wZ09qsks+9RS8fLWKqg=
github.com/go-openapi/validate v0.25.0 h1:JD9eGX81hDTjoY3WOzh6WqxVBVl7xjsLnvDo1GL5WPU=
github.com/go-openapi/validate v0.25.0/go.mod h1:SUY7vKrN5FiwK6LyvSwKjDfLNirSfWwHNgxd2l29Mmw=
github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls=
github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54=
github.com/go-openapi/validate v0.25.1 h1:sSACUI6Jcnbo5IWqbYHgjibrhhmt3vR6lCzKZnmAgBw=
github.com/go-openapi/validate v0.25.1/go.mod h1:RMVyVFYte0gbSTaZ0N4KmTn6u/kClvAFp+mAVfS/DQc=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
@@ -524,8 +532,8 @@ github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:Fecb
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI=
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 h1:QGLs/O40yoNK9vmy4rhUGBVyMf1lISBGtXRpsu/Qu/o=
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0/go.mod h1:hM2alZsMUni80N33RBe6J0e423LB+odMj7d3EMP9l20=
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 h1:sGm2vDRFUrQJO/Veii4h4zG2vvqG6uWNkBHSTqXOZk0=
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2/go.mod h1:wd1YpapPLivG6nQgbf7ZkG1hhSOXDhhn4MLTknx2aAc=
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 h1:B+8ClL/kCQkRiU82d9xajRPKYMrB7E0MbtzWVi1K4ns=
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3/go.mod h1:NbCUVmiS4foBGBHOYlCT25+YmGpJ32dZPi75pGEUpj4=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
@@ -642,8 +650,8 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=
github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
github.com/mattn/go-zglob v0.0.6 h1:mP8RnmCgho4oaUYDIDn6GNxYk+qJGUs8fJLn+twYj2A=
github.com/mattn/go-zglob v0.0.6/go.mod h1:MxxjyoXXnMxfIpxTK2GAkw1w8glPsQILx3N5wrKakiY=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
@@ -695,13 +703,15 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 h1:zrbMGy9YXpIeTnGj4EljqMiZsIcE09mmF8XsD5AYOJc=
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6/go.mod h1:rEKTHC9roVVicUIfZK7DYrdIoM0EOr8mK1Hj5s3JjH0=
github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5sM=
github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
github.com/olekukonko/ll v0.0.9 h1:Y+1YqDfVkqMWuEQMclsF9HUR5+a82+dxJuL1HHSRpxI=
github.com/olekukonko/ll v0.0.9/go.mod h1:En+sEW0JNETl26+K8eZ6/W4UQ7CYSrrgg/EdIYT2H8g=
github.com/olekukonko/ll v0.1.2 h1:lkg/k/9mlsy0SxO5aC+WEpbdT5K83ddnNhAepz7TQc0=
github.com/olekukonko/ll v0.1.2/go.mod h1:b52bVQRRPObe+yyBl0TxNfhesL0nedD4Cht0/zx55Ew=
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v1.1.0 h1:N0LHrshF4T39KvI96fn6GT8HEjXRXYNDrDjKFDB7RIY=
github.com/olekukonko/tablewriter v1.1.0/go.mod h1:5c+EBPeSqvXnLLgkm9isDdzR3wjfBkHR9Nhfp3NWrzo=
github.com/olekukonko/tablewriter v1.1.1 h1:b3reP6GCfrHwmKkYwNRFh2rxidGHcT6cgxj/sHiDDx0=
github.com/olekukonko/tablewriter v1.1.1/go.mod h1:De/bIcTF+gpBDB3Alv3fEsZA+9unTsSzAg/ZGADCtn4=
github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852/go.mod h1:eqOVx5Vwu4gd2mmMZvVZsgIqNSaW3xxRThUJ0k/TPk4=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@@ -815,9 +825,6 @@ github.com/r3labs/diff/v3 v3.0.2/go.mod h1:Cy542hv0BAEmhDYWtGxXRQ4kqRsVIcEjG9gCh
github.com/redis/go-redis/v9 v9.0.0-rc.4/go.mod h1:Vo3EsyWnicKnSKCA7HhgnvnyA74wOA69Cd2Meli5mmA=
github.com/redis/go-redis/v9 v9.8.0 h1:q3nRvjrlge/6UD7eTu/DSg2uYiU2mCL0G/uzBWqhicI=
github.com/redis/go-redis/v9 v9.8.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/robfig/cron/v3 v3.0.2-0.20210106135023-bc59245fe10e h1:0xChnl3lhHiXbgSJKgChye0D+DvoItkOdkGcwelDXH0=
github.com/robfig/cron/v3 v3.0.2-0.20210106135023-bc59245fe10e/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
@@ -918,10 +925,10 @@ github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
gitlab.com/gitlab-org/api/client-go v0.157.1 h1:oYbOYk0A2Q+bc1drw8fikSvgi5GImQ9Cj0L0zkZ+PfY=
gitlab.com/gitlab-org/api/client-go v0.157.1/go.mod h1:CQVoxjEswJZeXft4Mi+H+OF1MVrpNVF6m4xvlPTQ2J4=
go.mongodb.org/mongo-driver v1.17.4 h1:jUorfmVzljjr0FLzYQsGP8cgN/qzzxlY9Vh0C9KFXVw=
go.mongodb.org/mongo-driver v1.17.4/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=
gitlab.com/gitlab-org/api/client-go v0.160.0 h1:aMQzbcE8zFe0lR/J+a3zneEgH+/EBFs8rD8Chrr4Snw=
gitlab.com/gitlab-org/api/client-go v0.160.0/go.mod h1:ooCNtKB7OyP7GBa279+HrUS3eeJF6Yi6XABZZy7RTSk=
go.mongodb.org/mongo-driver v1.17.6 h1:87JUG1wZfWsr6rIz3ZmpH90rL5tea7O3IHuSwHUpsss=
go.mongodb.org/mongo-driver v1.17.6/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
@@ -994,8 +1001,8 @@ golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU=
golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -1039,8 +1046,8 @@ golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1106,8 +1113,8 @@ golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -1115,8 +1122,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY=
golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo=
golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1132,8 +1139,8 @@ golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1216,8 +1223,8 @@ golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/telemetry v0.0.0-20250710130107-8d8967aff50b/go.mod h1:4ZwOYna0/zsOKwuR5X/m0QFOJpSZvAxFfkQT+Erd9D4=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -1244,8 +1251,8 @@ golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q=
golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss=
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1270,8 +1277,8 @@ golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=

View File

@@ -63,6 +63,7 @@ nav:
- operator-manual/web_based_terminal.md
- operator-manual/config-management-plugins.md
- operator-manual/deep_links.md
- operator-manual/managed-by-url.md
- Notifications:
- Overview: operator-manual/notifications/index.md
- operator-manual/notifications/triggers.md

View File

@@ -162,7 +162,7 @@ func (t *terminalSession) performValidationsAndReconnect(p []byte) (int, error)
}
// check if token still valid
_, newToken, err := t.sessionManager.VerifyToken(*t.token)
_, newToken, err := t.sessionManager.VerifyToken(t.ctx, *t.token)
// err in case if token is revoked, newToken in case if refresh happened
if err != nil || newToken != "" {
// need to send reconnect code in case if token was refreshed

View File

@@ -31,7 +31,7 @@ func NewHandler(settingsMrg *settings.SettingsManager, sessionMgr *session.Sessi
type Handler struct {
settingsMgr *settings.SettingsManager
rootPath string
verifyToken func(tokenString string) (jwt.Claims, string, error)
verifyToken func(ctx context.Context, tokenString string) (jwt.Claims, string, error)
revokeToken func(ctx context.Context, id string, expiringAt time.Duration) error
baseHRef string
}
@@ -94,7 +94,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Set-Cookie", argocdCookie.String())
}
claims, _, err := h.verifyToken(tokenString)
claims, _, err := h.verifyToken(r.Context(), tokenString)
if err != nil {
http.Redirect(w, r, logoutRedirectURL, http.StatusSeeOther)
return

View File

@@ -1,6 +1,7 @@
package logout
import (
"context"
"errors"
"net/http"
"net/http/httptest"
@@ -245,28 +246,28 @@ func TestHandlerConstructLogoutURL(t *testing.T) {
sessionManager := session.NewSessionManager(settingsManagerWithOIDCConfig, test.NewFakeProjLister(), "", nil, session.NewUserStateStorage(nil))
oidcHandler := NewHandler(settingsManagerWithOIDCConfig, sessionManager, rootPath, baseHRef)
oidcHandler.verifyToken = func(tokenString string) (jwt.Claims, string, error) {
oidcHandler.verifyToken = func(_ context.Context, tokenString string) (jwt.Claims, string, error) {
if !validJWTPattern.MatchString(tokenString) {
return nil, "", errors.New("invalid jwt")
}
return &jwt.RegisteredClaims{Issuer: "okta"}, "", nil
}
nonoidcHandler := NewHandler(settingsManagerWithoutOIDCConfig, sessionManager, "", baseHRef)
nonoidcHandler.verifyToken = func(tokenString string) (jwt.Claims, string, error) {
nonoidcHandler.verifyToken = func(_ context.Context, tokenString string) (jwt.Claims, string, error) {
if !validJWTPattern.MatchString(tokenString) {
return nil, "", errors.New("invalid jwt")
}
return &jwt.RegisteredClaims{Issuer: session.SessionManagerClaimsIssuer}, "", nil
}
oidcHandlerWithoutLogoutURL := NewHandler(settingsManagerWithOIDCConfigButNoLogoutURL, sessionManager, "", baseHRef)
oidcHandlerWithoutLogoutURL.verifyToken = func(tokenString string) (jwt.Claims, string, error) {
oidcHandlerWithoutLogoutURL.verifyToken = func(_ context.Context, tokenString string) (jwt.Claims, string, error) {
if !validJWTPattern.MatchString(tokenString) {
return nil, "", errors.New("invalid jwt")
}
return &jwt.RegisteredClaims{Issuer: "okta"}, "", nil
}
nonoidcHandlerWithMultipleURLs := NewHandler(settingsManagerWithoutOIDCAndMultipleURLs, sessionManager, "", baseHRef)
nonoidcHandlerWithMultipleURLs.verifyToken = func(tokenString string) (jwt.Claims, string, error) {
nonoidcHandlerWithMultipleURLs.verifyToken = func(_ context.Context, tokenString string) (jwt.Claims, string, error) {
if !validJWTPattern.MatchString(tokenString) {
return nil, "", errors.New("invalid jwt")
}
@@ -274,7 +275,7 @@ func TestHandlerConstructLogoutURL(t *testing.T) {
}
oidcHandlerWithoutBaseURL := NewHandler(settingsManagerWithOIDCConfigButNoURL, sessionManager, "argocd", baseHRef)
oidcHandlerWithoutBaseURL.verifyToken = func(tokenString string) (jwt.Claims, string, error) {
oidcHandlerWithoutBaseURL.verifyToken = func(_ context.Context, tokenString string) (jwt.Claims, string, error) {
if !validJWTPattern.MatchString(tokenString) {
return nil, "", errors.New("invalid jwt")
}

View File

@@ -323,6 +323,8 @@ func NewServer(ctx context.Context, opts ArgoCDServerOpts, appsetOpts Applicatio
appsetLister := appFactory.Argoproj().V1alpha1().ApplicationSets().Lister()
userStateStorage := util_session.NewUserStateStorage(opts.RedisClient)
ssoClientApp, err := oidc.NewClientApp(settings, opts.DexServerAddr, opts.DexTLSConfig, opts.BaseHRef, cacheutil.NewRedisCache(opts.RedisClient, settings.UserInfoCacheExpiration(), cacheutil.RedisCompressionNone))
errorsutil.CheckError(err)
sessionMgr := util_session.NewSessionManager(settingsMgr, projLister, opts.DexServerAddr, opts.DexTLSConfig, userStateStorage)
enf := rbac.NewEnforcer(opts.KubeClientset, opts.Namespace, common.ArgoCDRBACConfigMapName, nil)
enf.EnableEnforce(!opts.DisableAuth)
@@ -370,6 +372,7 @@ func NewServer(ctx context.Context, opts ArgoCDServerOpts, appsetOpts Applicatio
a := &ArgoCDServer{
ArgoCDServerOpts: opts,
ApplicationSetOpts: appsetOpts,
ssoClientApp: ssoClientApp,
log: logger,
settings: settings,
sessionMgr: sessionMgr,
@@ -1125,19 +1128,7 @@ func (server *ArgoCDServer) translateGrpcCookieHeader(ctx context.Context, w htt
}
func (server *ArgoCDServer) setTokenCookie(token string, w http.ResponseWriter) error {
cookiePath := "path=/" + strings.TrimRight(strings.TrimLeft(server.BaseHRef, "/"), "/")
flags := []string{cookiePath, "SameSite=lax", "httpOnly"}
if !server.Insecure {
flags = append(flags, "Secure")
}
cookies, err := httputil.MakeCookieMetadata(common.AuthCookieName, token, flags...)
if err != nil {
return fmt.Errorf("error creating cookie metadata: %w", err)
}
for _, cookie := range cookies {
w.Header().Add("Set-Cookie", cookie)
}
return nil
return httputil.SetTokenCookie(token, server.BaseHRef, !server.Insecure, w)
}
func withRootPath(handler http.Handler, a *ArgoCDServer) http.Handler {
@@ -1221,9 +1212,6 @@ func (server *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWeb
terminalOpts := application.TerminalOptions{DisableAuth: server.DisableAuth, Enf: server.enf}
// SSO ClientApp
server.ssoClientApp, _ = oidc.NewClientApp(server.settings, server.DexServerAddr, server.DexTLSConfig, server.BaseHRef, cacheutil.NewRedisCache(server.RedisClient, server.settings.UserInfoCacheExpiration(), cacheutil.RedisCompressionNone))
terminal := application.NewHandler(server.appLister, server.Namespace, server.ApplicationNamespaces, server.db, appResourceTreeFn, server.settings.ExecShells, server.sessionMgr, &terminalOpts).
WithFeatureFlagMiddleware(server.settingsMgr.GetSettings)
th := util_session.WithAuthMiddleware(server.DisableAuth, server.settings.IsSSOConfigured(), server.ssoClientApp, server.sessionMgr, terminal)
@@ -1368,9 +1356,7 @@ func (server *ArgoCDServer) registerDexHandlers(mux *http.ServeMux) {
return
}
// Run dex OpenID Connect Identity Provider behind a reverse proxy (served at /api/dex)
var err error
mux.HandleFunc(common.DexAPIEndpoint+"/", dexutil.NewDexHTTPReverseProxy(server.DexServerAddr, server.BaseHRef, server.DexTLSConfig))
errorsutil.CheckError(err)
mux.HandleFunc(common.LoginEndpoint, server.ssoClientApp.HandleLogin)
mux.HandleFunc(common.CallbackEndpoint, server.ssoClientApp.HandleCallback)
}
@@ -1566,6 +1552,7 @@ func (server *ArgoCDServer) Authenticate(ctx context.Context) (context.Context,
return ctx, nil
}
// getClaims extracts, validates and refreshes a JWT token from an incoming request context.
func (server *ArgoCDServer) getClaims(ctx context.Context) (jwt.Claims, string, error) {
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
@@ -1575,17 +1562,29 @@ func (server *ArgoCDServer) getClaims(ctx context.Context) (jwt.Claims, string,
if tokenString == "" {
return nil, "", ErrNoSession
}
claims, newToken, err := server.sessionMgr.VerifyToken(tokenString)
// A valid argocd-issued token is automatically refreshed here prior to expiration.
// OIDC tokens will be verified but will not be refreshed here.
claims, newToken, err := server.sessionMgr.VerifyToken(ctx, tokenString)
if err != nil {
return claims, "", status.Errorf(codes.Unauthenticated, "invalid session: %v", err)
}
finalClaims := claims
if server.settings.IsSSOConfigured() {
finalClaims, err = server.ssoClientApp.SetGroupsFromUserInfo(claims, util_session.SessionManagerClaimsIssuer)
updatedClaims, err := server.ssoClientApp.SetGroupsFromUserInfo(ctx, claims, util_session.SessionManagerClaimsIssuer)
if err != nil {
return claims, "", status.Errorf(codes.Unauthenticated, "invalid session: %v", err)
}
finalClaims = updatedClaims
// OIDC tokens are automatically refreshed here prior to expiration
refreshedToken, err := server.ssoClientApp.CheckAndRefreshToken(ctx, updatedClaims, server.settings.OIDCRefreshTokenThreshold)
if err != nil {
log.Errorf("error checking and refreshing token: %v", err)
}
if refreshedToken != "" && refreshedToken != tokenString {
newToken = refreshedToken
log.Infof("refreshed token for subject: %v", jwtutil.StringField(updatedClaims, "sub"))
}
}
return finalClaims, newToken, nil

View File

@@ -838,17 +838,19 @@ Are you sure you want to disable auto-sync and rollback application '${props.mat
}}
/>
{state.extensions &&
(state.extensions || []).map(ext => (
<i
key={ext.title}
className={classNames(`fa ${ext.icon}`, {selected: pref.view === ext.title})}
title={ext.title}
onClick={() => {
appContext.navigation.goto('.', {view: ext.title});
services.viewPreferences.updatePreferences({appDetails: {...pref, view: ext.title}});
}}
/>
))}
(state.extensions || [])
.filter(ext => ext.shouldDisplay(application))
.map(ext => (
<i
key={ext.title}
className={classNames(`fa ${ext.icon}`, {selected: pref.view === ext.title})}
title={ext.title}
onClick={() => {
appContext.navigation.goto('.', {view: ext.title});
services.viewPreferences.updatePreferences({appDetails: {...pref, view: ext.title}});
}}
/>
))}
</div>
</React.Fragment>
)

View File

@@ -342,7 +342,7 @@ export const ApplicationStatusPanel = ({application, showDiff, showOperation, sh
}}>
{(data: models.ApplicationSyncWindowState) => (
<React.Fragment>
{data.assignedWindows && (
{data?.assignedWindows && (
<div className='application-status-panel__item' style={{position: 'relative'}}>
{sectionLabel({
title: 'SYNC WINDOWS',

View File

@@ -53,6 +53,9 @@
}
.applications-list__external-link {
align-items: center;
display: flex;
button {
background: none;
border: none;
@@ -60,6 +63,9 @@
padding: 0;
margin: 0;
color: inherit;
display: flex;
align-items: center;
justify-content: center;
&:hover {
color: $argo-color-teal-5;

View File

@@ -153,26 +153,25 @@ export const ApplicationTiles = ({applications, syncApplication, refreshApplicat
title={getManagedByURL(app) ? `Managed by: ${getManagedByURL(app)}` : 'Open application'}>
<i className='fa fa-external-link-alt' />
</button>
<Tooltip content={favList?.includes(app.metadata.name) ? 'Remove Favorite' : 'Add Favorite'}>
<button
className='large-text-height'
onClick={e => {
e.stopPropagation();
favList?.includes(app.metadata.name)
? favList.splice(favList.indexOf(app.metadata.name), 1)
: favList.push(app.metadata.name);
services.viewPreferences.updatePreferences({appList: {...pref.appList, favoritesAppList: favList}});
}}>
<i
className={favList?.includes(app.metadata.name) ? 'fas fa-star fa-lg' : 'far fa-star fa-lg'}
style={{
cursor: 'pointer',
marginLeft: '7px',
color: favList?.includes(app.metadata.name) ? '#FFCE25' : '#8fa4b1'
}}
/>
</button>
</Tooltip>
<button
title={favList?.includes(app.metadata.name) ? 'Remove Favorite' : 'Add Favorite'}
className='large-text-height'
onClick={e => {
e.stopPropagation();
favList?.includes(app.metadata.name)
? favList.splice(favList.indexOf(app.metadata.name), 1)
: favList.push(app.metadata.name);
services.viewPreferences.updatePreferences({appList: {...pref.appList, favoritesAppList: favList}});
}}>
<i
className={favList?.includes(app.metadata.name) ? 'fas fa-star fa-lg' : 'far fa-star fa-lg'}
style={{
cursor: 'pointer',
margin: '-1px 0px 0px 7px',
color: favList?.includes(app.metadata.name) ? '#FFCE25' : '#8fa4b1'
}}
/>
</button>
</div>
</div>
</div>

View File

@@ -94,7 +94,7 @@ export const ApplicationsRefreshPanel = ({show, apps, hide}: {show: boolean; app
))}
</div>
</div>
<ApplicationSelector apps={apps} formApi={formApi} />
{show && <ApplicationSelector apps={apps} formApi={formApi} />}
</div>
)}
</Form>

View File

@@ -146,7 +146,7 @@ export const ApplicationsSyncPanel = ({show, apps, hide}: {show: boolean; apps:
<ApplicationRetryOptions id='applications-sync-panel' formApi={formApi} />
<ApplicationSelector apps={apps} formApi={formApi} />
{show && <ApplicationSelector apps={apps} formApi={formApi} />}
</div>
)}
</Form>

View File

@@ -1570,13 +1570,13 @@ export const SyncWindowStatusIcon = ({state, window}: {state: appModels.SyncWind
);
};
export const ApplicationSyncWindowStatusIcon = ({project, state}: {project: string; state: appModels.ApplicationSyncWindowState}) => {
export const ApplicationSyncWindowStatusIcon = ({project, state}: {project: string; state?: appModels.ApplicationSyncWindowState}) => {
let className = '';
let color = '';
let deny = false;
let allow = false;
let inactiveAllow = false;
if (state.assignedWindows !== undefined && state.assignedWindows.length > 0) {
if (state?.assignedWindows !== undefined && state?.assignedWindows.length > 0) {
if (state.activeWindows !== undefined && state.activeWindows.length > 0) {
for (const w of state.activeWindows) {
if (w.kind === 'deny') {

View File

@@ -50,8 +50,8 @@ function registerSystemLevelExtension(component: ExtensionComponent, title: stri
extensions.eventTarget.emit('systemLevel', ext);
}
function registerAppViewExtension(component: ExtensionComponent, title: string, icon: string) {
const ext = {component, title, icon};
function registerAppViewExtension(component: AppViewExtensionComponent, title: string, icon: string, shouldDisplay?: (app: Application) => boolean) {
const ext = {component, title, icon, shouldDisplay: shouldDisplay || (() => true)};
extensions.appViewExtensions.push(ext);
extensions.eventTarget.emit('appView', ext);
}
@@ -109,6 +109,7 @@ export interface AppViewExtension {
component: AppViewExtensionComponent;
title: string;
icon?: string;
shouldDisplay: (app: Application) => boolean;
}
export interface StatusPanelExtension {

View File

@@ -6616,9 +6616,9 @@ mimic-fn@^2.1.0:
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
min-document@^2.19.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=
version "2.19.1"
resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.1.tgz#7083ad4bc8879a6eba6516688e9f5d91d32e2d23"
integrity sha512-8lqe85PkqQJzIcs2iD7xW/WSxcncC3/DPVbTOafKNJDIMXwGfwXS350mH4SJslomntN2iYtFBuC0yNO3CEap6g==
dependencies:
dom-walk "^0.1.0"

View File

@@ -241,3 +241,23 @@ func drainBody(body io.ReadCloser) {
log.Warnf("error reading response body: %s", err.Error())
}
}
func SetTokenCookie(token string, baseHRef string, isSecure bool, w http.ResponseWriter) error {
var path string
if baseHRef != "" {
path = strings.TrimRight(strings.TrimLeft(baseHRef, "/"), "/")
}
cookiePath := "path=/" + path
flags := []string{cookiePath, "SameSite=lax", "httpOnly"}
if isSecure {
flags = append(flags, "Secure")
}
cookies, err := MakeCookieMetadata(common.AuthCookieName, token, flags...)
if err != nil {
return fmt.Errorf("error creating cookie metadata: %w", err)
}
for _, cookie := range cookies {
w.Header().Add("Set-Cookie", cookie)
}
return nil
}

View File

@@ -1,10 +1,13 @@
package http
import (
"fmt"
"net/http"
"strings"
"testing"
"github.com/argoproj/argo-cd/v3/common"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -49,6 +52,101 @@ func TestSplitCookie(t *testing.T) {
assert.Equal(t, cookieValue, token)
}
// mockResponseWriter is a mock implementation of http.ResponseWriter.
// It captures added headers for verification in tests.
type mockResponseWriter struct {
header http.Header
}
func (m *mockResponseWriter) Header() http.Header {
if m.header == nil {
m.header = make(http.Header)
}
return m.header
}
func (m *mockResponseWriter) Write([]byte) (int, error) { return 0, nil }
func (m *mockResponseWriter) WriteHeader(_ int) {}
func TestSetTokenCookie(t *testing.T) {
tests := []struct {
name string
token string
baseHRef string
isSecure bool
expectedCookies []string // Expected Set-Cookie header values
}{
{
name: "Insecure cookie",
token: "insecure-token",
baseHRef: "",
isSecure: false,
expectedCookies: []string{
fmt.Sprintf("%s=%s; path=/; SameSite=lax; httpOnly", common.AuthCookieName, "insecure-token"),
},
},
{
name: "Secure cookie",
token: "secure-token",
baseHRef: "",
isSecure: true,
expectedCookies: []string{
fmt.Sprintf("%s=%s; path=/; SameSite=lax; httpOnly; Secure", common.AuthCookieName, "secure-token"),
},
},
{
name: "Insecure cookie with baseHRef",
token: "token-with-path",
baseHRef: "/app",
isSecure: false,
expectedCookies: []string{
fmt.Sprintf("%s=%s; path=/app; SameSite=lax; httpOnly", common.AuthCookieName, "token-with-path"),
},
},
{
name: "Secure cookie with baseHRef",
token: "secure-token-with-path",
baseHRef: "app/",
isSecure: true,
expectedCookies: []string{
fmt.Sprintf("%s=%s; path=/app; SameSite=lax; httpOnly; Secure", common.AuthCookieName, "secure-token-with-path"),
},
},
{
name: "Unsecured cookie, baseHRef with multiple segments and mixed slashes",
token: "complex-path-token",
baseHRef: "///api/v1/auth///",
isSecure: false,
expectedCookies: []string{
fmt.Sprintf("%s=%s; path=/api/v1/auth; SameSite=lax; httpOnly", common.AuthCookieName, "complex-path-token"),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
w := &mockResponseWriter{}
err := SetTokenCookie(tt.token, tt.baseHRef, tt.isSecure, w)
if err != nil {
t.Fatalf("%s: Unexpected error: %v", tt.name, err)
}
setCookieHeaders := w.Header()["Set-Cookie"]
if len(setCookieHeaders) != len(tt.expectedCookies) {
t.Errorf("Mistmatch in Set-Cookie header length: %s\nExpected: %d\nGot: %d",
tt.name, len(tt.expectedCookies), len(setCookieHeaders))
return
}
if len(tt.expectedCookies) > 0 && setCookieHeaders[0] != tt.expectedCookies[0] {
t.Errorf("Mismatch in Set-Cookie header: %s\nExpected: %s\nGot: %s",
tt.name, tt.expectedCookies[0], setCookieHeaders[0])
}
})
}
}
// TestRoundTripper just copy request headers to the resposne.
type TestRoundTripper struct{}

View File

@@ -7,13 +7,14 @@ import (
"os"
securejoin "github.com/cyphar/filepath-securejoin"
pathrs "github.com/cyphar/filepath-securejoin/pathrs-lite"
)
// SecureMkdirAll creates a directory with the given mode and returns the full path to the directory. It prevents
// directory traversal attacks by ensuring the path is within the root directory. The path is constructed as if the
// given root is the root of the filesystem. So anything traversing outside the root is simply removed from the path.
func SecureMkdirAll(root, unsafePath string, mode os.FileMode) (string, error) {
err := securejoin.MkdirAll(root, unsafePath, mode)
err := pathrs.MkdirAll(root, unsafePath, mode)
if err != nil {
return "", fmt.Errorf("failed to make directory: %w", err)
}

View File

@@ -43,6 +43,7 @@ const (
ResponseTypeCode = "code"
UserInfoResponseCachePrefix = "userinfo_response"
AccessTokenCachePrefix = "access_token"
OidcTokenCachePrefix = "oidc_token"
)
// OIDCConfiguration holds a subset of interested fields from the OIDC configuration spec
@@ -87,6 +88,8 @@ type ClientApp struct {
clientCache cache.CacheClient
// properties for azure workload identity.
azure azureApp
// preemptive token refresh threshold
refreshTokenThreshold time.Duration
}
type azureApp struct {
@@ -98,6 +101,63 @@ type azureApp struct {
mtx *sync.RWMutex
}
// OidcTokenCache is a serialization wrapper around oauth2 provider configuration needed to generate a TokenSource
type OidcTokenCache struct {
// Redirect URL is needed for oauth2 config initialization
RedirectURL string `json:"redirect_url"`
// oauth2 Token
Token *oauth2.Token `json:"token"`
// TokenExtraIdToken captures value of id_token
TokenExtraIdToken string `json:"token_extra_id_token"`
}
// NewOidcTokenCache initializes the struct from a redirect URL and an existing token
func NewOidcTokenCache(redirectURL string, token *oauth2.Token) *OidcTokenCache {
var idToken string
if token.Extra("id_token") == nil {
idToken = ""
} else {
idToken = token.Extra("id_token").(string)
}
return &OidcTokenCache{
RedirectURL: redirectURL,
Token: token,
TokenExtraIdToken: idToken,
}
}
// GetOidcTokenCacheFromJSON deserializes the json representation of OidcTokenCache. The Token extra map is updated from
// the serialization wrapper to propagate the id_token. This will ensure that the TokenSource always retrieves a usable token.
func GetOidcTokenCacheFromJSON(jsonBytes []byte) (*OidcTokenCache, error) {
var newToken OidcTokenCache
err := json.Unmarshal(jsonBytes, &newToken)
if err != nil {
return nil, err
}
if newToken.Token == nil {
return nil, errors.New("empty token")
}
newToken.Token = newToken.Token.WithExtra(map[string]any{
"id_token": newToken.TokenExtraIdToken,
})
return &newToken, nil
}
// GetTokenSourceFromCache creates an oauth2 TokenSource from a cached oidc token. The TokenSource will be configured
// with an early expiration based on the refreshTokenThreshold.
func (a *ClientApp) GetTokenSourceFromCache(ctx context.Context, oidcTokenCache *OidcTokenCache) (oauth2.TokenSource, error) {
if oidcTokenCache == nil {
return nil, errors.New("oidcTokenCache is required")
}
config, err := a.getOauth2ConfigForRedirectURI(oidcTokenCache.RedirectURL)
if err != nil {
return nil, err
}
baseTokenSource := config.TokenSource(ctx, oidcTokenCache.Token)
tokenRefresher := oauth2.ReuseTokenSourceWithExpiry(oidcTokenCache.Token, baseTokenSource, a.refreshTokenThreshold)
return tokenRefresher, nil
}
func GetScopesOrDefault(scopes []string) []string {
if len(scopes) == 0 {
return []string{"openid", "profile", "email", "groups"}
@@ -127,6 +187,7 @@ func NewClientApp(settings *settings.ArgoCDSettings, dexServerAddr string, dexTL
encryptionKey: encryptionKey,
clientCache: cacheClient,
azure: azureApp{mtx: &sync.RWMutex{}},
refreshTokenThreshold: settings.OIDCRefreshTokenThreshold,
}
log.Infof("Creating client app (%s)", a.clientID)
u, err := url.Parse(settings.URL)
@@ -165,23 +226,27 @@ func NewClientApp(settings *settings.ArgoCDSettings, dexServerAddr string, dexTL
return &a, nil
}
func (a *ClientApp) oauth2Config(request *http.Request, scopes []string) (*oauth2.Config, error) {
func (a *ClientApp) getRedirectURIForRequest(req *http.Request) string {
redirectURI, err := a.settings.RedirectURLForRequest(req)
if err != nil {
log.Warnf("Unable to find ArgoCD URL from request, falling back to configured redirect URI: %v", err)
redirectURI = a.redirectURI
}
return redirectURI
}
func (a *ClientApp) getOauth2ConfigForRedirectURI(redirectURI string) (*oauth2.Config, error) {
endpoint, err := a.provider.Endpoint()
if err != nil {
return nil, err
}
redirectURL, err := a.settings.RedirectURLForRequest(request)
if err != nil {
log.Warnf("Unable to find ArgoCD URL from request, falling back to configured redirect URI: %v", err)
redirectURL = a.redirectURI
}
return &oauth2.Config{
ClientID: a.clientID,
ClientSecret: a.clientSecret,
Endpoint: *endpoint,
Scopes: scopes,
RedirectURL: redirectURL,
Scopes: a.getScopes(),
RedirectURL: redirectURI,
}, nil
}
@@ -315,17 +380,13 @@ func (a *ClientApp) HandleLogin(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
scopes := make([]string, 0)
pkceVerifier := ""
var opts []oauth2.AuthCodeOption
if config := a.settings.OIDCConfig(); config != nil {
scopes = GetScopesOrDefault(config.RequestedScopes)
opts = AppendClaimsAuthenticationRequestParameter(opts, config.RequestedIDTokenClaims)
} else if a.settings.IsDexConfigured() {
scopes = append(GetScopesOrDefault(nil), common.DexFederatedScope)
}
oauth2Config, err := a.oauth2Config(r, scopes)
oauth2Config, err := a.getOauth2ConfigForRedirectURI(a.getRedirectURIForRequest(r))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -406,7 +467,7 @@ func (a *azureApp) getFederatedServiceAccountToken(context.Context) (string, err
// HandleCallback is the callback handler for an OAuth2 login flow
func (a *ClientApp) HandleCallback(w http.ResponseWriter, r *http.Request) {
oauth2Config, err := a.oauth2Config(r, nil)
oauth2Config, err := a.getOauth2ConfigForRedirectURI(a.getRedirectURIForRequest(r))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -456,27 +517,21 @@ func (a *ClientApp) HandleCallback(w http.ResponseWriter, r *http.Request) {
return
}
// Parse out id token
idTokenRAW, ok := token.Extra("id_token").(string)
if !ok {
http.Error(w, "no id_token in token response", http.StatusInternalServerError)
return
}
idToken, err := a.provider.Verify(idTokenRAW, a.settings)
idToken, err := a.provider.Verify(ctx, idTokenRAW, a.settings)
if err != nil {
log.Warnf("Failed to verify token: %s", err)
log.Warnf("Failed to verify oidc token: %s", err)
http.Error(w, common.TokenVerificationError, http.StatusInternalServerError)
return
}
path := "/"
if a.baseHRef != "" {
path = strings.TrimRight(strings.TrimLeft(a.baseHRef, "/"), "/")
}
cookiePath := "path=/" + path
flags := []string{cookiePath, "SameSite=lax", "httpOnly"}
if a.secureCookie {
flags = append(flags, "Secure")
}
// Set cache
var claims jwt.MapClaims
err = idToken.Claims(&claims)
if err != nil {
@@ -484,38 +539,38 @@ func (a *ClientApp) HandleCallback(w http.ResponseWriter, r *http.Request) {
return
}
// save the accessToken in memory for later use
encToken, err := crypto.Encrypt([]byte(token.AccessToken), a.encryptionKey)
sub := jwtutil.StringField(claims, "sub")
err = a.SetValueInEncryptedCache(FormatAccessTokenCacheKey(sub), []byte(token.AccessToken), GetTokenExpiration(claims))
if err != nil {
claimsJSON, _ := json.Marshal(claims)
http.Error(w, "failed encrypting token", http.StatusInternalServerError)
log.Errorf("cannot encrypt accessToken: %v (claims=%s)", err, claimsJSON)
log.Errorf("cannot cache encrypted accessToken: %v (claims=%s)", err, claimsJSON)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
sub := jwtutil.StringField(claims, "sub")
err = a.clientCache.Set(&cache.Item{
Key: FormatAccessTokenCacheKey(sub),
Object: encToken,
CacheActionOpts: cache.CacheActionOpts{
Expiration: getTokenExpiration(claims),
},
})
// Cache encrypted raw token for background refresh
oidcTokenCache := NewOidcTokenCache(a.getRedirectURIForRequest(r), token)
oidcTokenCacheJSON, err := json.Marshal(oidcTokenCache)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
sid := jwtutil.StringField(claims, "sid")
err = a.SetValueInEncryptedCache(formatOidcTokenCacheKey(sub, sid), oidcTokenCacheJSON, GetTokenExpiration(claims))
if err != nil {
claimsJSON, _ := json.Marshal(claims)
http.Error(w, fmt.Sprintf("claims=%s, err=%v", claimsJSON, err), http.StatusInternalServerError)
log.Errorf("cannot cache encrypted oidc token: %v (claims=%s)", err, claimsJSON)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if idTokenRAW != "" {
cookies, err := httputil.MakeCookieMetadata(common.AuthCookieName, idTokenRAW, flags...)
err = httputil.SetTokenCookie(idTokenRAW, a.baseHRef, a.secureCookie, w)
if err != nil {
claimsJSON, _ := json.Marshal(claims)
http.Error(w, fmt.Sprintf("claims=%s, err=%v", claimsJSON, err), http.StatusInternalServerError)
return
}
for _, cookie := range cookies {
w.Header().Add("Set-Cookie", cookie)
}
}
claimsJSON, _ := json.Marshal(claims)
@@ -528,6 +583,109 @@ func (a *ClientApp) HandleCallback(w http.ResponseWriter, r *http.Request) {
}
}
// GetValueFromEncryptedCache is a convenience method for retreiving a value from cache and decrypting it. If the cache
// does not contain a value for the given key, a nil value is returned. Return handling should check for error and then
// check for nil.
func (a *ClientApp) GetValueFromEncryptedCache(key string) (value []byte, err error) {
var encryptedValue []byte
err = a.clientCache.Get(key, &encryptedValue)
if err != nil {
if errors.Is(err, cache.ErrCacheMiss) {
// Return nil to signify a cache miss
return nil, nil
}
return nil, fmt.Errorf("failed to get encrypted value from cache: %w", err)
}
value, err = crypto.Decrypt(encryptedValue, a.encryptionKey)
if err != nil {
return nil, fmt.Errorf("failed to decrypt value from cache: %w", err)
}
return value, err
}
// SetValueFromEncyrptedCache is a convenience method for encrypting a value and storing it in the cache at a given key.
// Cache expiration is set based on input.
func (a *ClientApp) SetValueInEncryptedCache(key string, value []byte, expiration time.Duration) error {
encryptedValue, err := crypto.Encrypt(value, a.encryptionKey)
if err != nil {
return err
}
err = a.clientCache.Set(&cache.Item{
Key: key,
Object: encryptedValue,
CacheActionOpts: cache.CacheActionOpts{
Expiration: expiration,
},
})
if err != nil {
return err
}
return nil
}
func (a *ClientApp) CheckAndRefreshToken(ctx context.Context, groupClaims jwt.MapClaims, refreshTokenThreshold time.Duration) (string, error) {
sub := jwtutil.StringField(groupClaims, "sub")
sid := jwtutil.StringField(groupClaims, "sid")
if GetTokenExpiration(groupClaims) < refreshTokenThreshold {
token, err := a.GetUpdatedOidcTokenFromCache(ctx, sub, sid)
if err != nil {
log.Errorf("Failed to get token from cache: %v", err)
return "", err
}
if token != nil {
idTokenRAW, ok := token.Extra("id_token").(string)
if !ok {
return "", errors.New("empty id_token")
}
return idTokenRAW, nil
}
}
return "", nil
}
// GetUpdatedOidcTokenFromCache fetches a token from cache and refreshes it if under the threshold for expiration.
// The cached token will also be updated if it is refreshed. Returns latest token or an error if the process fails.
func (a *ClientApp) GetUpdatedOidcTokenFromCache(ctx context.Context, subject string, sessionId string) (*oauth2.Token, error) {
ctx = gooidc.ClientContext(ctx, a.client)
// Get oauth2 config
cacheKey := formatOidcTokenCacheKey(subject, sessionId)
oidcTokenCacheJSON, err := a.GetValueFromEncryptedCache(cacheKey)
if err != nil {
return nil, err
}
if oidcTokenCacheJSON == nil {
return nil, nil
}
oidcTokenCache, err := GetOidcTokenCacheFromJSON(oidcTokenCacheJSON)
if err != nil {
err = fmt.Errorf("failed to unmarshal cached oidc token: %w", err)
return nil, err
}
tokenSource, err := a.GetTokenSourceFromCache(ctx, oidcTokenCache)
if err != nil {
err = fmt.Errorf("failed to get token source from cached oidc token: %w", err)
return nil, err
}
token, err := tokenSource.Token()
if err != nil {
return nil, fmt.Errorf("failed to refresh token from source: %w", err)
}
if token.AccessToken != oidcTokenCache.Token.AccessToken {
oidcTokenCache = NewOidcTokenCache(oidcTokenCache.RedirectURL, token)
oidcTokenCacheJSON, err = json.Marshal(oidcTokenCache)
if err != nil {
return nil, fmt.Errorf("failed to marshal oidc oidcTokenCache refresher: %w", err)
}
err = a.SetValueInEncryptedCache(cacheKey, oidcTokenCacheJSON, time.Until(token.Expiry))
if err != nil {
return nil, err
}
}
return token, nil
}
var implicitFlowTmpl = template.Must(template.New("implicit.html").Parse(`<script>
var hash = window.location.hash.substr(1);
var result = hash.split('&').reduce(function (result, item) {
@@ -645,7 +803,7 @@ func createClaimsAuthenticationRequestParameter(requestedClaims map[string]*oidc
// If querying the UserInfo endpoint fails, we return an error to indicate the session is invalid
// we assume that everywhere in argocd jwt.MapClaims is used as type for interface jwt.Claims
// otherwise this would cause a panic
func (a *ClientApp) SetGroupsFromUserInfo(claims jwt.Claims, sessionManagerClaimsIssuer string) (jwt.MapClaims, error) {
func (a *ClientApp) SetGroupsFromUserInfo(ctx context.Context, claims jwt.Claims, sessionManagerClaimsIssuer string) (jwt.MapClaims, error) {
var groupClaims jwt.MapClaims
var ok bool
if groupClaims, ok = claims.(jwt.MapClaims); !ok {
@@ -657,7 +815,7 @@ func (a *ClientApp) SetGroupsFromUserInfo(claims jwt.Claims, sessionManagerClaim
}
iss := jwtutil.StringField(groupClaims, "iss")
if iss != sessionManagerClaimsIssuer && a.settings.UserInfoGroupsEnabled() && a.settings.UserInfoPath() != "" {
userInfo, unauthorized, err := a.GetUserInfo(groupClaims, a.settings.IssuerURL(), a.settings.UserInfoPath())
userInfo, unauthorized, err := a.GetUserInfo(ctx, groupClaims, a.settings.IssuerURL(), a.settings.UserInfoPath())
if unauthorized {
return groupClaims, fmt.Errorf("error while quering userinfo endpoint: %w", err)
}
@@ -674,7 +832,7 @@ func (a *ClientApp) SetGroupsFromUserInfo(claims jwt.Claims, sessionManagerClaim
}
// GetUserInfo queries the IDP userinfo endpoint for claims
func (a *ClientApp) GetUserInfo(actualClaims jwt.MapClaims, issuerURL, userInfoPath string) (jwt.MapClaims, bool, error) {
func (a *ClientApp) GetUserInfo(ctx context.Context, actualClaims jwt.MapClaims, issuerURL, userInfoPath string) (jwt.MapClaims, bool, error) {
sub := jwtutil.StringField(actualClaims, "sub")
var claims jwt.MapClaims
var encClaims []byte
@@ -696,19 +854,13 @@ func (a *ClientApp) GetUserInfo(actualClaims jwt.MapClaims, issuerURL, userInfoP
}
// check if the accessToken for the user is still present
var encAccessToken []byte
err := a.clientCache.Get(FormatAccessTokenCacheKey(sub), &encAccessToken)
// without an accessToken we can't query the user info endpoint
// thus the user needs to reauthenticate for argocd to get a new accessToken
if errors.Is(err, cache.ErrCacheMiss) {
return claims, true, fmt.Errorf("no accessToken for %s: %w", sub, err)
} else if err != nil {
accessTokenBytes, err := a.GetValueFromEncryptedCache(FormatAccessTokenCacheKey(sub))
if err != nil {
return claims, true, fmt.Errorf("could not read accessToken from cache for %s: %w", sub, err)
}
accessToken, err := crypto.Decrypt(encAccessToken, a.encryptionKey)
if err != nil {
return claims, true, fmt.Errorf("could not decrypt accessToken for %s: %w", sub, err)
if accessTokenBytes == nil {
return claims, true, fmt.Errorf("no accessToken for %s: %w", sub, err)
}
url := issuerURL + userInfoPath
@@ -718,7 +870,7 @@ func (a *ClientApp) GetUserInfo(actualClaims jwt.MapClaims, issuerURL, userInfoP
return claims, false, err
}
bearer := fmt.Sprintf("Bearer %s", accessToken)
bearer := "Bearer " + string(accessTokenBytes)
request.Header.Set("Authorization", bearer)
response, err := a.client.Do(request)
@@ -740,7 +892,7 @@ func (a *ClientApp) GetUserInfo(actualClaims jwt.MapClaims, issuerURL, userInfoP
switch header {
case "application/jwt":
// if body is JWT, first validate it before extracting claims
idToken, err := a.provider.Verify(string(rawBody), a.settings)
idToken, err := a.provider.Verify(ctx, string(rawBody), a.settings)
if err != nil {
return claims, false, fmt.Errorf("user info response in jwt format not valid: %w", err)
}
@@ -760,7 +912,7 @@ func (a *ClientApp) GetUserInfo(actualClaims jwt.MapClaims, issuerURL, userInfoP
// but first let's determine the expiry of the cache
var cacheExpiry time.Duration
settingExpiry := a.settings.UserInfoCacheExpiration()
tokenExpiry := getTokenExpiration(claims)
tokenExpiry := GetTokenExpiration(claims)
// only use configured expiry if the token lives longer and the expiry is configured
// if the token has no expiry, use the expiry of the actual token
@@ -769,7 +921,7 @@ func (a *ClientApp) GetUserInfo(actualClaims jwt.MapClaims, issuerURL, userInfoP
case settingExpiry < tokenExpiry && settingExpiry != 0:
cacheExpiry = settingExpiry
case tokenExpiry < 0:
cacheExpiry = getTokenExpiration(actualClaims)
cacheExpiry = GetTokenExpiration(actualClaims)
default:
cacheExpiry = tokenExpiry
}
@@ -797,8 +949,8 @@ func (a *ClientApp) GetUserInfo(actualClaims jwt.MapClaims, issuerURL, userInfoP
return claims, false, nil
}
// getTokenExpiration returns a time.Duration until the token expires
func getTokenExpiration(claims jwt.MapClaims) time.Duration {
// GetTokenExpiration returns a time.Duration until the token expires
func GetTokenExpiration(claims jwt.MapClaims) time.Duration {
// get duration until token expires
exp := jwtutil.Float64Field(claims, "exp")
tm := time.Unix(int64(exp), 0)
@@ -806,12 +958,28 @@ func getTokenExpiration(claims jwt.MapClaims) time.Duration {
return tokenExpiry
}
// formatUserInfoResponseCacheKey returns the key which is used to store userinfo of user in cache
// getScopes returns scopes based on provider configuration
func (a *ClientApp) getScopes() []string {
scopes := make([]string, 0)
if config := a.settings.OIDCConfig(); config != nil {
scopes = GetScopesOrDefault(config.RequestedScopes)
} else if a.settings.IsDexConfigured() {
scopes = append(GetScopesOrDefault(nil), common.DexFederatedScope)
}
return scopes
}
// FormatUserInfoResponseCacheKey returns the key which is used to store userinfo of user in cache
func FormatUserInfoResponseCacheKey(sub string) string {
return fmt.Sprintf("%s_%s", UserInfoResponseCachePrefix, sub)
}
// formatAccessTokenCacheKey returns the key which is used to store the accessToken of a user in cache
// FormatAccessTokenCacheKey returns the key which is used to store the accessToken of a user in cache
func FormatAccessTokenCacheKey(sub string) string {
return fmt.Sprintf("%s_%s", AccessTokenCachePrefix, sub)
}
// formatRefreshTokenCacheKey returns the key which is used to store the oidc Token for a session in cache
func formatOidcTokenCacheKey(sub string, sid string) string {
return fmt.Sprintf("%s_%s_%s", OidcTokenCachePrefix, sub, sid)
}

View File

@@ -1,9 +1,11 @@
package oidc
import (
"context"
"crypto/tls"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"net/http"
"net/http/httptest"
@@ -15,6 +17,8 @@ import (
"testing"
"time"
log "github.com/sirupsen/logrus"
gooidc "github.com/coreos/go-oidc/v3/oidc"
"github.com/golang-jwt/jwt/v5"
"github.com/stretchr/testify/assert"
@@ -28,6 +32,7 @@ import (
"github.com/argoproj/argo-cd/v3/util/cache"
"github.com/argoproj/argo-cd/v3/util/crypto"
"github.com/argoproj/argo-cd/v3/util/dex"
jwtutil "github.com/argoproj/argo-cd/v3/util/jwt"
"github.com/argoproj/argo-cd/v3/util/settings"
"github.com/argoproj/argo-cd/v3/util/test"
)
@@ -97,9 +102,14 @@ func TestIDTokenClaims(t *testing.T) {
assert.JSONEq(t, "{\"id_token\":{\"groups\":{\"essential\":true}}}", values.Get("claims"))
}
type fakeProvider struct{}
type fakeProvider struct {
EndpointError bool
}
func (p *fakeProvider) Endpoint() (*oauth2.Endpoint, error) {
if p.EndpointError {
return nil, errors.New("fake provider endpoint error")
}
return &oauth2.Endpoint{}, nil
}
@@ -107,7 +117,7 @@ func (p *fakeProvider) ParseConfig() (*OIDCConfiguration, error) {
return nil, nil
}
func (p *fakeProvider) Verify(_ string, _ *settings.ArgoCDSettings) (*gooidc.IDToken, error) {
func (p *fakeProvider) Verify(_ context.Context, _ string, _ *settings.ArgoCDSettings) (*gooidc.IDToken, error) {
return nil, nil
}
@@ -530,7 +540,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL),
app.HandleCallback(w, req)
if !strings.Contains(w.Body.String(), "certificate signed by unknown authority") && !strings.Contains(w.Body.String(), "certificate is not trusted") {
t.Fatal("did not receive expected certificate verification failure error")
t.Fatalf("did not receive expected certificate verification failure error: %v", w.Code)
}
cdSettings.OIDCTLSInsecureSkipVerify = true
@@ -700,7 +710,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL),
app.HandleCallback(w, req)
if !strings.Contains(w.Body.String(), "certificate signed by unknown authority") && !strings.Contains(w.Body.String(), "certificate is not trusted") {
t.Fatal("did not receive expected certificate verification failure error")
t.Fatalf("did not receive expected certificate verification failure error: %v", w.Code)
}
cdSettings.OIDCTLSInsecureSkipVerify = true
@@ -1147,7 +1157,7 @@ func TestGetUserInfo(t *testing.T) {
require.NoError(t, err)
}
got, unauthenticated, err := a.GetUserInfo(tt.idpClaims, ts.URL, tt.userInfoPath)
got, unauthenticated, err := a.GetUserInfo(t.Context(), tt.idpClaims, ts.URL, tt.userInfoPath)
assert.Equal(t, tt.expectedOutput, got)
assert.Equal(t, tt.expectUnauthenticated, unauthenticated)
if tt.expectError {
@@ -1253,7 +1263,7 @@ userInfoPath: /`,
require.NoError(t, err, "failed setting item to in-memory cache")
}
receivedClaims, err := a.SetGroupsFromUserInfo(tt.inputClaims, "argocd")
receivedClaims, err := a.SetGroupsFromUserInfo(t.Context(), tt.inputClaims, "argocd")
if tt.expectError {
require.Error(t, err)
} else {
@@ -1263,3 +1273,300 @@ userInfoPath: /`,
})
}
}
func TestGetOidcTokenCacheFromJSON(t *testing.T) {
tests := []struct {
name string
oidcTokenCache *OidcTokenCache
expectErrorContains string
expectIdToken string
}{
{
name: "empty",
oidcTokenCache: &OidcTokenCache{},
expectErrorContains: "empty token",
},
{
name: "empty id token",
oidcTokenCache: &OidcTokenCache{
Token: &oauth2.Token{},
},
expectIdToken: "",
},
{
name: "simple",
oidcTokenCache: NewOidcTokenCache("", (&oauth2.Token{}).WithExtra(map[string]any{"id_token": "simple"})),
expectIdToken: "simple",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tokenJSON, err := json.Marshal(tt.oidcTokenCache)
require.NoError(t, err)
token, err := GetOidcTokenCacheFromJSON(tokenJSON)
if tt.expectErrorContains != "" {
assert.ErrorContains(t, err, tt.expectErrorContains)
return
}
require.NoError(t, err)
if tt.expectIdToken != "" {
assert.Equal(t, tt.expectIdToken, token.Token.Extra("id_token").(string))
}
})
}
}
func TestClientApp_GetTokenSourceFromCache(t *testing.T) {
tests := []struct {
name string
oidcTokenCache *OidcTokenCache
expectErrorContains string
provider Provider
}{
{
name: "provider error",
oidcTokenCache: &OidcTokenCache{},
expectErrorContains: "fake provider endpoint error",
provider: &fakeProvider{
EndpointError: true,
},
},
{
name: "empty oidcTokenCache",
expectErrorContains: "oidcTokenCache is required",
provider: &fakeProvider{},
},
{
name: "simple",
oidcTokenCache: NewOidcTokenCache("", (&oauth2.Token{}).WithExtra(map[string]any{"id_token": "simple"})),
provider: &fakeProvider{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
app := ClientApp{provider: tt.provider, settings: &settings.ArgoCDSettings{}}
tokenSource, err := app.GetTokenSourceFromCache(t.Context(), tt.oidcTokenCache)
if tt.expectErrorContains != "" {
assert.ErrorContains(t, err, tt.expectErrorContains)
return
}
require.NoError(t, err)
assert.NotNil(t, tokenSource)
})
}
}
func TestClientApp_GetUpdatedOidcTokenFromCache(t *testing.T) {
tests := []struct {
name string
subject string
session string
insertIntoCache bool
oidcTokenCache *OidcTokenCache
expectErrorContains string
expectTokenNotNil bool
}{
{
name: "empty token cache",
subject: "alice",
session: "111",
insertIntoCache: true,
expectErrorContains: "failed to unmarshal cached oidc token: empty token",
},
{
name: "no refresh token",
subject: "alice",
session: "111",
insertIntoCache: true,
oidcTokenCache: &OidcTokenCache{Token: &oauth2.Token{}},
expectErrorContains: "failed to refresh token from source: oauth2: token expired and refresh token is not set",
},
{
name: "cache miss",
subject: "",
session: "",
insertIntoCache: false,
},
{
name: "updated token from cache",
subject: "alice",
session: "111",
insertIntoCache: true,
oidcTokenCache: &OidcTokenCache{Token: &oauth2.Token{
RefreshToken: "not empty",
}},
expectTokenNotNil: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
oidcTestServer := test.GetOIDCTestServer(t, nil)
t.Cleanup(oidcTestServer.Close)
cdSettings := &settings.ArgoCDSettings{
URL: "https://argocd.example.com",
OIDCConfigRAW: fmt.Sprintf(`
name: Test
issuer: %s
clientID: test-client-id
clientSecret: test-client-secret
requestedScopes: ["oidc"]`, oidcTestServer.URL),
OIDCTLSInsecureSkipVerify: true,
}
app, err := NewClientApp(cdSettings, "", nil, "/", cache.NewInMemoryCache(24*time.Hour))
require.NoError(t, err)
if tt.insertIntoCache {
oidcTokenCacheJSON, err := json.Marshal(tt.oidcTokenCache)
require.NoError(t, err)
require.NoError(t, app.SetValueInEncryptedCache(formatOidcTokenCacheKey(tt.subject, tt.session), oidcTokenCacheJSON, time.Minute))
}
token, err := app.GetUpdatedOidcTokenFromCache(t.Context(), tt.subject, tt.session)
if tt.expectErrorContains != "" {
assert.ErrorContains(t, err, tt.expectErrorContains)
return
}
require.NoError(t, err)
if tt.expectTokenNotNil {
assert.NotNil(t, token)
}
})
}
}
func TestClientApp_CheckAndGetRefreshToken(t *testing.T) {
tests := []struct {
name string
expectErrorContains string
expectNewToken bool
groupClaims jwt.MapClaims
refreshTokenThreshold string
}{
{
name: "no new token",
groupClaims: jwt.MapClaims{
"aud": common.ArgoCDClientAppID,
"exp": float64(time.Now().Add(time.Hour).Unix()),
"sub": "randomUser",
"sid": "1111",
"iss": "issuer",
"groups": "group1",
},
expectNewToken: false,
refreshTokenThreshold: "1m",
},
{
name: "new token",
groupClaims: jwt.MapClaims{
"aud": common.ArgoCDClientAppID,
"exp": float64(time.Now().Add(55 * time.Second).Unix()),
"sub": "randomUser",
"sid": "1111",
"iss": "issuer",
"groups": "group1",
},
expectNewToken: true,
refreshTokenThreshold: "1m",
},
{
name: "parse error",
groupClaims: jwt.MapClaims{
"aud": common.ArgoCDClientAppID,
"exp": float64(time.Now().Add(time.Minute).Unix()),
"sub": "randomUser",
"sid": "1111",
"iss": "issuer",
"groups": "group1",
},
expectNewToken: false,
refreshTokenThreshold: "1xx",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
oidcTestServer := test.GetOIDCTestServer(t, nil)
t.Cleanup(oidcTestServer.Close)
cdSettings := &settings.ArgoCDSettings{
URL: "https://argocd.example.com",
OIDCConfigRAW: fmt.Sprintf(`
name: Test
issuer: %s
clientID: test-client-id
clientSecret: test-client-secret
refreshTokenThreshold: %s
requestedScopes: ["oidc"]`, oidcTestServer.URL, tt.refreshTokenThreshold),
OIDCTLSInsecureSkipVerify: true,
}
// The base href (the last argument for NewClientApp) is what HandleLogin will fall back to when no explicit
// redirect URL is given.
app, err := NewClientApp(cdSettings, "", nil, "/", cache.NewInMemoryCache(24*time.Hour))
require.NoError(t, err)
oidcTokenCacheJSON, err := json.Marshal(&OidcTokenCache{Token: &oauth2.Token{
RefreshToken: "not empty",
}})
require.NoError(t, err)
sub := jwtutil.StringField(tt.groupClaims, "sub")
require.NotEmpty(t, sub)
sid := jwtutil.StringField(tt.groupClaims, "sid")
require.NotEmpty(t, sid)
require.NoError(t, app.SetValueInEncryptedCache(formatOidcTokenCacheKey(sub, sid), oidcTokenCacheJSON, time.Minute))
token, err := app.CheckAndRefreshToken(t.Context(), tt.groupClaims, cdSettings.RefreshTokenThreshold())
if tt.expectErrorContains != "" {
require.ErrorContains(t, err, tt.expectErrorContains)
return
}
require.NoError(t, err)
if tt.expectNewToken {
require.NotEmpty(t, token)
} else {
require.Empty(t, token)
}
})
}
}
func TestClientApp_getRedirectURIForRequest(t *testing.T) {
tests := []struct {
name string
req *http.Request
expectLogContains string
expectedRequestURI string
expectError bool
}{
{
name: "empty",
req: &http.Request{
URL: &url.URL{},
},
},
{
name: "nil URL",
expectLogContains: "falling back to configured redirect URI",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
app := ClientApp{provider: &fakeProvider{}, settings: &settings.ArgoCDSettings{}}
hook := test.LogHook{}
log.AddHook(&hook)
t.Cleanup(func() {
log.StandardLogger().ReplaceHooks(log.LevelHooks{})
})
redirectURI := app.getRedirectURIForRequest(tt.req)
if tt.expectLogContains != "" {
assert.NotEmpty(t, hook.GetRegexMatchesInEntries(tt.expectLogContains), "expected log")
} else {
assert.Empty(t, hook.Entries, "expected log")
}
if tt.req == nil {
return
}
expectedRedirectURI, err := app.settings.RedirectURLForRequest(tt.req)
if tt.expectError {
assert.Error(t, err)
return
}
assert.Equal(t, expectedRedirectURI, redirectURI, "expected URI")
})
}
}

View File

@@ -27,7 +27,7 @@ type Provider interface {
ParseConfig() (*OIDCConfiguration, error)
Verify(tokenString string, argoSettings *settings.ArgoCDSettings) (*gooidc.IDToken, error)
Verify(ctx context.Context, tokenString string, argoSettings *settings.ArgoCDSettings) (*gooidc.IDToken, error)
}
type providerImpl struct {
@@ -85,7 +85,7 @@ func (t tokenVerificationError) Error() string {
return "token verification failed for all audiences: " + strings.Join(errorStrings, ", ")
}
func (p *providerImpl) Verify(tokenString string, argoSettings *settings.ArgoCDSettings) (*gooidc.IDToken, error) {
func (p *providerImpl) Verify(ctx context.Context, tokenString string, argoSettings *settings.ArgoCDSettings) (*gooidc.IDToken, error) {
// According to the JWT spec, the aud claim is optional. The spec also says (emphasis mine):
//
// If the principal processing the claim does not identify itself with a value in the "aud" claim _when this
@@ -110,7 +110,7 @@ func (p *providerImpl) Verify(tokenString string, argoSettings *settings.ArgoCDS
var idToken *gooidc.IDToken
if !unverifiedHasAudClaim {
idToken, err = p.verify("", tokenString, argoSettings.SkipAudienceCheckWhenTokenHasNoAudience())
idToken, err = p.verify(ctx, "", tokenString, argoSettings.SkipAudienceCheckWhenTokenHasNoAudience())
} else {
allowedAudiences := argoSettings.OAuth2AllowedAudiences()
if len(allowedAudiences) == 0 {
@@ -119,7 +119,7 @@ func (p *providerImpl) Verify(tokenString string, argoSettings *settings.ArgoCDS
tokenVerificationErrors := make(map[string]error)
// Token must be verified for at least one allowed audience
for _, aud := range allowedAudiences {
idToken, err = p.verify(aud, tokenString, false)
idToken, err = p.verify(ctx, aud, tokenString, false)
tokenExpiredError := &gooidc.TokenExpiredError{}
if errors.As(err, &tokenExpiredError) {
// If the token is expired, we won't bother checking other audiences. It's important to return a
@@ -143,14 +143,13 @@ func (p *providerImpl) Verify(tokenString string, argoSettings *settings.ArgoCDS
}
if err != nil {
return nil, fmt.Errorf("failed to verify token: %w", err)
return nil, fmt.Errorf("failed to verify provider token: %w", err)
}
return idToken, nil
}
func (p *providerImpl) verify(clientID, tokenString string, skipClientIDCheck bool) (*gooidc.IDToken, error) {
ctx := context.Background()
func (p *providerImpl) verify(ctx context.Context, clientID, tokenString string, skipClientIDCheck bool) (*gooidc.IDToken, error) {
prov, err := p.provider()
if err != nil {
return nil, err

View File

@@ -489,7 +489,7 @@ func (mgr *SessionManager) AuthMiddlewareFunc(disabled bool, isSSOConfigured boo
// TokenVerifier defines the contract to invoke token
// verification logic
type TokenVerifier interface {
VerifyToken(token string) (jwt.Claims, string, error)
VerifyToken(ctx context.Context, token string) (jwt.Claims, string, error)
}
// WithAuthMiddleware is an HTTP middleware used to ensure incoming
@@ -504,12 +504,13 @@ func WithAuthMiddleware(disabled bool, isSSOConfigured bool, ssoClientApp *oidcu
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
cookies := r.Cookies()
ctx := r.Context()
tokenString, err := httputil.JoinCookies(common.AuthCookieName, cookies)
if err != nil {
http.Error(w, "Auth cookie not found", http.StatusBadRequest)
return
}
claims, _, err := authn.VerifyToken(tokenString)
claims, _, err := authn.VerifyToken(ctx, tokenString)
if err != nil {
http.Error(w, "Invalid token", http.StatusUnauthorized)
return
@@ -517,14 +518,12 @@ func WithAuthMiddleware(disabled bool, isSSOConfigured bool, ssoClientApp *oidcu
finalClaims := claims
if isSSOConfigured {
finalClaims, err = ssoClientApp.SetGroupsFromUserInfo(claims, SessionManagerClaimsIssuer)
finalClaims, err = ssoClientApp.SetGroupsFromUserInfo(ctx, claims, SessionManagerClaimsIssuer)
if err != nil {
http.Error(w, "Invalid session", http.StatusUnauthorized)
return
}
}
ctx := r.Context()
// Add claims to the context to inspect for RBAC
//nolint:staticcheck
ctx = context.WithValue(ctx, "claims", finalClaims)
@@ -536,7 +535,7 @@ func WithAuthMiddleware(disabled bool, isSSOConfigured bool, ssoClientApp *oidcu
// VerifyToken verifies if a token is correct. Tokens can be issued either from us or by an IDP.
// We choose how to verify based on the issuer.
func (mgr *SessionManager) VerifyToken(tokenString string) (jwt.Claims, string, error) {
func (mgr *SessionManager) VerifyToken(ctx context.Context, tokenString string) (jwt.Claims, string, error) {
parser := jwt.NewParser(jwt.WithoutClaimsValidation())
claims := jwt.MapClaims{}
_, _, err := parser.ParseUnverified(tokenString, &claims)
@@ -564,12 +563,12 @@ func (mgr *SessionManager) VerifyToken(tokenString string) (jwt.Claims, string,
return nil, "", errors.New("settings are not available while verifying the token")
}
idToken, err := prov.Verify(tokenString, argoSettings)
idToken, err := prov.Verify(ctx, tokenString, argoSettings)
// The token verification has failed. If the token has expired, we will
// return a dummy claims only containing a value for the issuer, so the
// UI can handle expired tokens appropriately.
if err != nil {
log.Warnf("Failed to verify token: %s", err)
log.Warnf("Failed to verify session token: %s", err)
tokenExpiredError := &oidc.TokenExpiredError{}
if errors.As(err, &tokenExpiredError) {
claims = jwt.MapClaims{

View File

@@ -228,7 +228,7 @@ type tokenVerifierMock struct {
err error
}
func (tm *tokenVerifierMock) VerifyToken(_ string) (jwt.Claims, string, error) {
func (tm *tokenVerifierMock) VerifyToken(_ context.Context, _ string) (jwt.Claims, string, error) {
if tm.claims == nil {
return nil, "", tm.err
}
@@ -255,7 +255,7 @@ func TestSessionManager_WithAuthMiddleware(t *testing.T) {
}
}
jsonClaims, err := json.Marshal(gotClaims)
require.NoError(t, err, "erorr marshalling claims set by AuthMiddleware")
require.NoError(t, err, "error marshalling claims set by AuthMiddleware")
w.Header().Set("Content-Type", "application/json")
_, err = w.Write(jsonClaims)
require.NoError(t, err, "error writing response: %s", err)
@@ -720,7 +720,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL),
tokenString, err := token.SignedString(key)
require.NoError(t, err)
_, _, err = mgr.VerifyToken(tokenString)
_, _, err = mgr.VerifyToken(t.Context(), tokenString)
assert.NotContains(t, err.Error(), "oidc: id token signed with unsupported algorithm")
})
@@ -752,7 +752,7 @@ rootCA: |
tokenString, err := token.SignedString(key)
require.NoError(t, err)
_, _, err = mgr.VerifyToken(tokenString)
_, _, err = mgr.VerifyToken(t.Context(), tokenString)
// If the root CA is being respected, we won't get this error. The error message is environment-dependent, so
// we check for either of the error messages associated with a failed cert check.
assert.NotContains(t, err.Error(), "certificate is not trusted")
@@ -789,7 +789,7 @@ rootCA: |
tokenString, err := token.SignedString(key)
require.NoError(t, err)
_, _, err = mgr.VerifyToken(tokenString)
_, _, err = mgr.VerifyToken(t.Context(), tokenString)
require.Error(t, err)
assert.ErrorIs(t, err, common.ErrTokenVerification)
})
@@ -824,7 +824,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL),
tokenString, err := token.SignedString(key)
require.NoError(t, err)
_, _, err = mgr.VerifyToken(tokenString)
_, _, err = mgr.VerifyToken(t.Context(), tokenString)
require.Error(t, err)
assert.ErrorIs(t, err, common.ErrTokenVerification)
})
@@ -859,7 +859,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL),
tokenString, err := token.SignedString(key)
require.NoError(t, err)
_, _, err = mgr.VerifyToken(tokenString)
_, _, err = mgr.VerifyToken(t.Context(), tokenString)
require.Error(t, err)
assert.ErrorIs(t, err, common.ErrTokenVerification)
})
@@ -895,7 +895,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL),
tokenString, err := token.SignedString(key)
require.NoError(t, err)
_, _, err = mgr.VerifyToken(tokenString)
_, _, err = mgr.VerifyToken(t.Context(), tokenString)
assert.NotContains(t, err.Error(), "certificate is not trusted")
assert.NotContains(t, err.Error(), "certificate signed by unknown authority")
})
@@ -924,7 +924,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL),
tokenString, err := token.SignedString(key)
require.NoError(t, err)
_, _, err = mgr.VerifyToken(tokenString)
_, _, err = mgr.VerifyToken(t.Context(), tokenString)
// This is the error thrown when the test server's certificate _is_ being verified.
assert.NotContains(t, err.Error(), "certificate is not trusted")
assert.NotContains(t, err.Error(), "certificate signed by unknown authority")
@@ -961,7 +961,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL),
tokenString, err := token.SignedString(key)
require.NoError(t, err)
_, _, err = mgr.VerifyToken(tokenString)
_, _, err = mgr.VerifyToken(t.Context(), tokenString)
require.Error(t, err)
})
@@ -997,7 +997,7 @@ skipAudienceCheckWhenTokenHasNoAudience: true`, oidcTestServer.URL),
tokenString, err := token.SignedString(key)
require.NoError(t, err)
_, _, err = mgr.VerifyToken(tokenString)
_, _, err = mgr.VerifyToken(t.Context(), tokenString)
require.NoError(t, err)
})
@@ -1033,7 +1033,7 @@ skipAudienceCheckWhenTokenHasNoAudience: false`, oidcTestServer.URL),
tokenString, err := token.SignedString(key)
require.NoError(t, err)
_, _, err = mgr.VerifyToken(tokenString)
_, _, err = mgr.VerifyToken(t.Context(), tokenString)
require.Error(t, err)
assert.ErrorIs(t, err, common.ErrTokenVerification)
})
@@ -1069,7 +1069,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL),
tokenString, err := token.SignedString(key)
require.NoError(t, err)
_, _, err = mgr.VerifyToken(tokenString)
_, _, err = mgr.VerifyToken(t.Context(), tokenString)
require.NoError(t, err)
})
@@ -1106,7 +1106,7 @@ allowedAudiences:
tokenString, err := token.SignedString(key)
require.NoError(t, err)
_, _, err = mgr.VerifyToken(tokenString)
_, _, err = mgr.VerifyToken(t.Context(), tokenString)
require.NoError(t, err)
})
@@ -1143,7 +1143,7 @@ allowedAudiences:
tokenString, err := token.SignedString(key)
require.NoError(t, err)
_, _, err = mgr.VerifyToken(tokenString)
_, _, err = mgr.VerifyToken(t.Context(), tokenString)
require.Error(t, err)
assert.ErrorIs(t, err, common.ErrTokenVerification)
})
@@ -1179,7 +1179,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL),
tokenString, err := token.SignedString(key)
require.NoError(t, err)
_, _, err = mgr.VerifyToken(tokenString)
_, _, err = mgr.VerifyToken(t.Context(), tokenString)
require.Error(t, err)
assert.ErrorIs(t, err, common.ErrTokenVerification)
})
@@ -1216,7 +1216,7 @@ allowedAudiences: []`, oidcTestServer.URL),
tokenString, err := token.SignedString(key)
require.NoError(t, err)
_, _, err = mgr.VerifyToken(tokenString)
_, _, err = mgr.VerifyToken(t.Context(), tokenString)
require.Error(t, err)
assert.ErrorIs(t, err, common.ErrTokenVerification)
})
@@ -1254,7 +1254,7 @@ allowedAudiences: ["aud-a", "aud-b"]`, oidcTestServer.URL),
tokenString, err := token.SignedString(key)
require.NoError(t, err)
_, _, err = mgr.VerifyToken(tokenString)
_, _, err = mgr.VerifyToken(t.Context(), tokenString)
require.NoError(t, err)
})
@@ -1289,7 +1289,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL),
tokenString, err := token.SignedString(key)
require.NoError(t, err)
_, _, err = mgr.VerifyToken(tokenString)
_, _, err = mgr.VerifyToken(t.Context(), tokenString)
require.Error(t, err)
assert.ErrorIs(t, err, common.ErrTokenVerification)
})

View File

@@ -136,6 +136,9 @@ type ArgoCDSettings struct {
// token verification to pass despite the OIDC provider having an invalid certificate. Only set to `true` if you
// understand the risks.
OIDCTLSInsecureSkipVerify bool `json:"oidcTLSInsecureSkipVerify"`
// OIDCRefreshTokenThreshold sets the threshold for preemptive server-side token refresh. If set to 0, tokens
// will not be refreshed and will expire before client is redirected to login.
OIDCRefreshTokenThreshold time.Duration `json:"oidcRefreshTokenThreshold,omitempty"`
// AppsInAnyNamespaceEnabled indicates whether applications are allowed to be created in any namespace
AppsInAnyNamespaceEnabled bool `json:"appsInAnyNamespaceEnabled"`
// ExtensionConfig configurations related to ArgoCD proxy extensions. The keys are the extension name.
@@ -193,6 +196,7 @@ func (o *oidcConfig) toExported() *OIDCConfig {
UserInfoPath: o.UserInfoPath,
EnableUserInfoGroups: o.EnableUserInfoGroups,
UserInfoCacheExpiration: o.UserInfoCacheExpiration,
RefreshTokenThreshold: o.RefreshTokenThreshold,
RequestedScopes: o.RequestedScopes,
RequestedIDTokenClaims: o.RequestedIDTokenClaims,
LogoutURL: o.LogoutURL,
@@ -218,22 +222,13 @@ type OIDCConfig struct {
EnablePKCEAuthentication bool `json:"enablePKCEAuthentication,omitempty"`
DomainHint string `json:"domainHint,omitempty"`
Azure *AzureOIDCConfig `json:"azure,omitempty"`
RefreshTokenThreshold string `json:"refreshTokenThreshold,omitempty"`
}
type AzureOIDCConfig struct {
UseWorkloadIdentity bool `json:"useWorkloadIdentity,omitempty"`
}
// DEPRECATED. Helm repository credentials are now managed using RepoCredentials
type HelmRepoCredentials struct {
URL string `json:"url,omitempty"`
Name string `json:"name,omitempty"`
UsernameSecret *corev1.SecretKeySelector `json:"usernameSecret,omitempty"`
PasswordSecret *corev1.SecretKeySelector `json:"passwordSecret,omitempty"`
CertSecret *corev1.SecretKeySelector `json:"certSecret,omitempty"`
KeySecret *corev1.SecretKeySelector `json:"keySecret,omitempty"`
}
var (
ByClusterURLIndexer = "byClusterURL"
byClusterURLIndexerFunc = func(obj any) ([]string, error) {
@@ -1442,6 +1437,7 @@ func getDownloadBinaryUrlsFromConfigMap(argoCDCM *corev1.ConfigMap) map[string]s
func updateSettingsFromConfigMap(settings *ArgoCDSettings, argoCDCM *corev1.ConfigMap) {
settings.DexConfig = argoCDCM.Data[settingDexConfigKey]
settings.OIDCConfigRAW = argoCDCM.Data[settingsOIDCConfigKey]
settings.OIDCRefreshTokenThreshold = settings.RefreshTokenThreshold()
settings.KustomizeBuildOptions = argoCDCM.Data[kustomizeBuildOptionsKey]
settings.StatusBadgeEnabled = argoCDCM.Data[statusBadgeEnabledKey] == "true"
settings.StatusBadgeRootUrl = argoCDCM.Data[statusBadgeRootURLKey]
@@ -1892,6 +1888,18 @@ func (a *ArgoCDSettings) UserInfoCacheExpiration() time.Duration {
return 0
}
// RefreshTokenThreshold returns the duration before token expiration that a token should be refreshed by the server
func (a *ArgoCDSettings) RefreshTokenThreshold() time.Duration {
if oidcConfig := a.OIDCConfig(); oidcConfig != nil && oidcConfig.RefreshTokenThreshold != "" {
refreshTokenThreshold, err := time.ParseDuration(oidcConfig.RefreshTokenThreshold)
if err != nil {
log.Warnf("Failed to parse 'oidc.config.refreshTokenThreshold' key: %v", err)
}
return refreshTokenThreshold
}
return 0
}
func (a *ArgoCDSettings) OAuth2ClientID() string {
if oidcConfig := a.OIDCConfig(); oidcConfig != nil {
return oidcConfig.ClientID
@@ -2011,6 +2019,9 @@ func (a *ArgoCDSettings) ArgoURLForRequest(r *http.Request) (string, error) {
}
func (a *ArgoCDSettings) RedirectURLForRequest(r *http.Request) (string, error) {
if r == nil {
return "", errors.New("request is nil")
}
base, err := a.ArgoURLForRequest(r)
if err != nil {
return "", err

View File

@@ -1020,43 +1020,94 @@ func TestSettingsManager_GetSettings(t *testing.T) {
}
func TestGetOIDCConfig(t *testing.T) {
kubeClient := fake.NewClientset(
&corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: common.ArgoCDConfigMapName,
Namespace: "default",
Labels: map[string]string{
"app.kubernetes.io/part-of": "argocd",
},
},
Data: map[string]string{
testCases := []struct {
name string
configMapData map[string]string
testFunc func(t *testing.T, settingsManager *SettingsManager)
}{
{
name: "requestedIDTokenClaims",
configMapData: map[string]string{
"oidc.config": "\n requestedIDTokenClaims: {\"groups\": {\"essential\": true}}\n",
},
testFunc: func(t *testing.T, settingsManager *SettingsManager) {
t.Helper()
settings, err := settingsManager.GetSettings()
require.NoError(t, err)
oidcConfig := settings.OIDCConfig()
assert.NotNil(t, oidcConfig)
claim := oidcConfig.RequestedIDTokenClaims["groups"]
assert.NotNil(t, claim)
assert.True(t, claim.Essential)
},
},
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: common.ArgoCDSecretName,
Namespace: "default",
Labels: map[string]string{
"app.kubernetes.io/part-of": "argocd",
{
name: "refreshTokenThreshold success",
configMapData: map[string]string{
"oidc.config": "\n refreshTokenThreshold: 5m\n",
},
testFunc: func(t *testing.T, settingsManager *SettingsManager) {
t.Helper()
settings, err := settingsManager.GetSettings()
require.NoError(t, err)
oidcConfig := settings.OIDCConfig()
assert.NotNil(t, oidcConfig)
assert.Equal(t, 5*time.Minute, settings.RefreshTokenThreshold())
},
},
{
name: "refreshTokenThreshold parse failure",
configMapData: map[string]string{
"oidc.config": "\n refreshTokenThreshold: 5xx\n",
},
testFunc: func(t *testing.T, settingsManager *SettingsManager) {
t.Helper()
settings, err := settingsManager.GetSettings()
require.NoError(t, err)
oidcConfig := settings.OIDCConfig()
assert.NotNil(t, oidcConfig)
assert.Equal(t, time.Duration(0), settings.RefreshTokenThreshold())
},
},
}
for i := range testCases {
tc := testCases[i]
t.Run(tc.name, func(t *testing.T) {
kubeClient := fake.NewClientset(
&corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: common.ArgoCDConfigMapName,
Namespace: "default",
Labels: map[string]string{
"app.kubernetes.io/part-of": "argocd",
},
},
Data: tc.configMapData,
},
},
Data: map[string][]byte{
"admin.password": nil,
"server.secretkey": nil,
},
},
)
settingsManager := NewSettingsManager(t.Context(), kubeClient, "default")
settings, err := settingsManager.GetSettings()
require.NoError(t, err)
oidcConfig := settings.OIDCConfig()
assert.NotNil(t, oidcConfig)
claim := oidcConfig.RequestedIDTokenClaims["groups"]
assert.NotNil(t, claim)
assert.True(t, claim.Essential)
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: common.ArgoCDSecretName,
Namespace: "default",
Labels: map[string]string{
"app.kubernetes.io/part-of": "argocd",
},
},
Data: map[string][]byte{
"admin.password": nil,
"server.secretkey": nil,
},
},
)
settingsManager := NewSettingsManager(t.Context(), kubeClient, "default")
tc.testFunc(t, settingsManager)
})
}
}
func TestRedirectURL(t *testing.T) {