PageSourceSearch

https://harvesterhci.io/assets/js/3acbc264.05212cb7.js

js harvesterhci.io collected 2026-10-03 19:28:28 UTC 13,174 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkharvesterhci_io=self.webpackChunkharvesterhci_io||[]).push([[3152],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return h}});var i=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,i,r=function(e,t){if(null==e)return{};var n,i,r={},a=Object.keys(e);for(i=0;i<a.length;i++)n=a[i],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i<a.length;i++)n=a[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=i.createContext({}),c=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=c(e.components);return i.createElement(l.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},u=i.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(n),h=r,d=u["".concat(l,".").concat(h)]||u[h]||m[h]||a;return n?i.createElement(d,o(o({ref:t},p),{},{components:n})):i.createElement(d,o({ref:t},p))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,o=new Array(a);o[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:r,o[1]=s;for(var c=2;c<a;c++)o[c]=n[c];return i.createElement.apply(null,o)}return i.createElement.apply(null,n)}u.displayName="MDXCreateElement"},8338:function(e,t,n){n.r(t),n.d(t,{assets:function(){return p},contentTitle:function(){return l},default:function(){return h},frontMatter:function(){return s},metadata:function(){return c},toc:function(){return m}});var i=n(7462),r=n(3366),a=(n(7294),n(3905)),o=["components"],s={title:"CVE-2025-1974: ingress-nginx admission controller RCE escalation",description:"This article describes the mitigation steps for the CVE-2025-1974 vulnerability in Harvester.",authors:[{name:"Ivan Sim",title:"Principal Software Engineer",url:"https://github.com/ihcsim",image_url:"https://github.com/ihcsim.png"}],tags:["security","cve"],hide_table_of_contents:!1},l=void 0,c={permalink:"/kb/2025/03/25/cve-2025-1974",editUrl:"https://github.com/harvester/harvesterhci.io/edit/main/kb/2025-03-25/cve-2025-1974.md",source:"@site/kb/2025-03-25/cve-2025-1974.md",title:"CVE-2025-1974: ingress-nginx admission controller RCE escalation",description:"This article describes the mitigation steps for the CVE-2025-1974 vulnerability in Harvester.",date:"2025-03-25T00:00:00.000Z",formattedDate:"March 25, 2025",tags:[{label:"security",permalink:"/kb/tags/security"},{label:"cve",permalink:"/kb/tags/cve"}],readingTime:2.17,truncated:!1,authors:[{name:"Ivan Sim",title:"Principal Software Engineer",url:"https://github.com/ihcsim",image_url:"https://github.com/ihcsim.png",imageURL:"https://github.com/ihcsim.png"}],frontMatter:{title:"CVE-2025-1974: ingress-nginx admission controller RCE escalation",description:"This article describes the mitigation steps for the CVE-2025-1974 vulnerability in Harvester.",authors:[{name:"Ivan Sim",title:"Principal Software Engineer",url:"https://github.com/ihcsim",image_url:"https://github.com/ihcsim.png",imageURL:"https://github.com/ihcsim.png"}],tags:["security","cve"],hide_table_of_contents:!1},prevItem:{title:"Using Pod Security Standards (PSS) in Harvester To Enforce Secure Workload Isolation",permalink:"/kb/2025/05/08/using-pod-security-standard"},nextItem:{title:"Harvester ISO boot fails with SBAT error",permalink:"/kb/iso_boot_fails_with_sbat_errror"}},p={authorsImageUrls:[void 0]},m=[{value:"References",id:"references",level:2}],u={toc:m};function h(e){var t=e.components,n=(0,r.Z)(e,o);return(0,a.kt)("wrapper",(0,i.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("div",{className:"admonition admonition-info alert alert--info"}
1,(0,a.kt)("div",{parentName:"div",className:"admonition-heading"},(0,a.kt)("h5",{parentName:"div"},(0,a.kt)("span",{parentName:"h5",className:"admonition-icon"},(0,a.kt)("svg",{parentName:"span",xmlns:"http://www.w3.org/2000/svg",width:"14",height:"16",viewBox:"0 0 14 16"},(0,a.kt)("path",{parentName:"svg",fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"}))),"important")),(0,a.kt)("div",{parentName:"div",className:"admonition-content"},(0,a.kt)("p",{parentName:"div"},(0,a.kt)("strong",{parentName:"p"},"CVE-2025-1974")," (vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) has a score of ",(0,a.kt)("a",{parentName:"p",href:"https://www.first.org/cvss/calculator/3-1#CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"},"9.8 (Critical)"),"."),(0,a.kt)("p",{parentName:"div"},"The vulnerability affects specific versions of the RKE2 ingress-nginx controller (v.1.11.4 and earlier, and v1.12.0). All Harvester versions that use this controller (including v1.4.2 and earlier) are therefore affected."),(0,a.kt)("p",{parentName:"div"},(0,a.kt)("strong",{parentName:"p"},"This CVE is fixed in Harvester 1.5.0, 1.4.3 and newer.")))),(0,a.kt)("p",null,"A security issue was discovered in Kubernetes where under certain conditions, an unauthenticated attacker with access to the pod network can achieve arbitrary code execution in the context of the ingress-nginx controller. This can lead to disclosure of secrets accessible to the controller. (Note that in the default installation, the controller can access all secrets cluster-wide.)"),(0,a.kt)("p",null,"You can confirm the version of the RKE2 ingress-nginx pods by running this command on your Harvester cluster:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"kubectl -n kube-system get po -l\"app.kubernetes.io/name=rke2-ingress-nginx\" -ojsonpath='{.items[].spec.containers[].image}'\n")),(0,a.kt)("p",null,"If the command returns one of the affected versions, disable the ",(0,a.kt)("inlineCode",{parentName:"p"},"rke2-ingress-nginx-admission")," validating webhook configuration by performing the following steps:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"On one of your control plane nodes, use ",(0,a.kt)("inlineCode",{parentName:"p"},"kubectl")," to confirm the existence of the ",(0,a.kt)("inlineCode",{parentName:"p"},"HelmChartConfig")," resource named ",(0,a.kt)("inlineCode",{parentName:"p"},"rke2-ingress-nginx"),":"),(0,a.kt)("pre",{parentName:"li"},(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"$ kubectl -n kube-system get helmchartconfig rke2-ingress-nginx\nNAME                 AGE\nrke2-ingress-nginx   14d1h\n"))),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Use ",(0,a.kt)("inlineCode",{parentName:"p"},"kubectl -n kube-system edit helmchartconfig rke2-ingress-nginx")," to add the following configurations to the resource:"),(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},".spec.valuesContent.controller.admissionWebhooks.enabled: false")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},".spec.valuesContent.controller.extraArgs.enable-annotation-validation: true")))),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"The following is an example of what the updated ",(0,a.kt)("inlineCode",{parentName:"p"},".spec.valuesContent")," configuration along with the default Harvester ingress-nginx configuration should look like:"),(0,a.kt)("pre",{parentName:"li"},(0,a.kt)("code",{parentName:"pre",className:"language-yaml"},'apiVersion: helm.cattle.io/v1\nkind: HelmChartConfig\nmetadata:\n  name: rke2-ingress-nginx\n  namespace: kube-system\nspec:\n  valuesContent: |-\n    controller:\n      admissionWebhooks:\n        port: 8444\n        enabled: false\n      extraArgs:\n        enable-annotation-validation: true\n        default-ssl-certificate: cattle-system/tls-rancher-internal\n      config:\n        proxy-body-size: "0"\n        proxy-request-buffering: "off"\n      publishService:\n        pathOverride: kube-system/ingress-expose\n')),(0,a.kt)("p",{parentName:"li"},"  Exit the ",(0,a.kt)("inlineCode",{parentName:"p"}
1,"kubectl edit")," command execution to save the configuration. "),(0,a.kt)("p",{parentName:"li"},"  Harvester automatically applies the change once the content is saved."),(0,a.kt)("div",{parentName:"li",className:"admonition admonition-info alert alert--info"},(0,a.kt)("div",{parentName:"div",className:"admonition-heading"},(0,a.kt)("h5",{parentName:"div"},(0,a.kt)("span",{parentName:"h5",className:"admonition-icon"},(0,a.kt)("svg",{parentName:"span",xmlns:"http://www.w3.org/2000/svg",width:"14",height:"16",viewBox:"0 0 14 16"},(0,a.kt)("path",{parentName:"svg",fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"}))),"important")),(0,a.kt)("div",{parentName:"div",className:"admonition-content"},(0,a.kt)("p",{parentName:"div"},"  The configuration disables the RKE2 ingress-nginx admission webhooks while preserving Harvester's default ingress-nginx configuration."),(0,a.kt)("p",{parentName:"div"},"  If the ",(0,a.kt)("inlineCode",{parentName:"p"},"HelmChartConfig")," resource contains other custom ingress-nginx configuration, you must retain them when editing the resource.")))),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Verify that RKE2 deleted the ",(0,a.kt)("inlineCode",{parentName:"p"},"rke2-ingress-nginx-admission")," validating webhook configuration."),(0,a.kt)("pre",{parentName:"li"},(0,a.kt)("code",{parentName:"pre",className:"language-sh"},'$ kubectl get validatingwebhookconfiguration rke2-ingress-nginx-admission\nError from server (NotFound): validatingwebhookconfigurations.admissionregistration.k8s.io "rke2-ingress-nginx-admission" not found\n'))),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Verify that the ingress-nginx pods are restarted successfully."),(0,a.kt)("pre",{parentName:"li"},(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"$ kubectl -n kube-system get po -lapp.kubernetes.io/instance=rke2-ingress-nginx\nNAME                                  READY   STATUS    RESTARTS   AGE\nrke2-ingress-nginx-controller-g8l49   1/1     Running   0          5s\n")))),(0,a.kt)("p",null,"Once your Harvester cluster receives the RKE2 ingress-nginx patch, you can re-install the ",(0,a.kt)("inlineCode",{parentName:"p"},"rke2-ingress-nginx-admission")," validating webhook configuration by removing the ",(0,a.kt)("inlineCode",{parentName:"p"},"HelmChartConfig")," patch."),(0,a.kt)("div",{className:"admonition admonition-info alert alert--info"},(0,a.kt)("div",{parentName:"div",className:"admonition-heading"},(0,a.kt)("h5",{parentName:"div"},(0,a.kt)("span",{parentName:"h5",className:"admonition-icon"},(0,a.kt)("svg",{parentName:"span",xmlns:"http://www.w3.org/2000/svg",width:"14",height:"16",viewBox:"0 0 14 16"},(0,a.kt)("path",{parentName:"svg",fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"}))),"important")),(0,a.kt)("div",{parentName:"div",className:"admonition-content"},(0,a.kt)("p",{parentName:"div"},"These steps only cover the RKE2 ingress-nginx controller that is managed by Harvester. You must also update other running ingress-nginx controllers. See the References section for more information."))),(0,a.kt)("h2",{id:"references"},"References"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://nvd.nist.gov/vuln/detail/CVE-2025-1974"},"https://nvd.nist.gov/vuln/detail/CVE-2025-1974")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/kubernetes/kubernetes/issues/131009"},"https://github.com/kubernetes/kubernetes/issues/131009")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/rancher/rke2/issues/7953"},"https://github.com/rancher/rke2/issues/7953")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://www.suse.com/support/kb/doc/?id=000021756"},"https://www.suse.com/support/kb/doc/?id=000021756"))))}h.isMDXComponent=!0}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.