<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet href="/static/style.xsl" type="text/xsl"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
  <channel>
    <title>Most recent entries from all</title>
    <link>https://cve.radiocsirt.org</link>
    <description>Contains only the most 10 recent entries.</description>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>python-feedgen</generator>
    <language>en</language>
    <lastBuildDate>Fri, 16 Oct 2026 04:48:50 +0000</lastBuildDate>
    <item>
      <title>CVE-2026-43948 — wger: cross-tenant password reset and plaintext disclosure via gym=None bypass</title>
      <link>https://cve.radiocsirt.org/vuln/cve-2026-43948</link>
      <description>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; wger-project wger&lt;/p&gt;
&lt;p&gt;wger is a free, open-source workout and fitness manager. Prior to 2.6, the reset_user_password and gym_permissions_user_edit views in wger perform a gym-scope authorization check using Python object comparison (!=) that evaluates None != None as False, silently bypassing the guard when both the attacker and victim have no gym assignment (gym=None). A user with gym.manage_gym permission and gym=None can reset the password of any other gym=None user; the new plaintext password is returned verbatim in the HTML response body, enabling one-shot full account takeover. The victim&amp;#39;s original password is invalidated, locking them out permanently. This vulnerability is fixed in 2.6.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; wger-project wger&lt;/p&gt;
&lt;p&gt;wger is a free, open-source workout and fitness manager. Prior to 2.6, the reset_user_password and gym_permissions_user_edit views in wger perform a gym-scope authorization check using Python object comparison (!=) that evaluates None != None as False, silently bypassing the guard when both the attacker and victim have no gym assignment (gym=None). A user with gym.manage_gym permission and gym=None can reset the password of any other gym=None user; the new plaintext password is returned verbatim in the HTML response body, enabling one-shot full account takeover. The victim&amp;#39;s original password is invalidated, locking them out permanently. This vulnerability is fixed in 2.6.&lt;/p&gt;</content:encoded>
      <guid isPermaLink="false">https://cve.radiocsirt.org/vuln/cve-2026-43948</guid>
    </item>
    <item>
      <title>PYSEC-2026-574 — wger: cross-tenant password reset and plaintext disclosure via gym=None bypass</title>
      <link>https://cve.radiocsirt.org/vuln/pysec-2026-574</link>
      <description>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; PyPI: wger&lt;/p&gt;
&lt;p&gt;### Summary&lt;/p&gt;
&lt;p&gt;The `reset_user_password` and `gym_permissions_user_edit` views in wger perform a gym-scope authorization check using Python object comparison (`!=`) that evaluates `None != None` as `False`, silently bypassing the guard when both the attacker and victim have no gym assignment (`gym=None`). A user with `gym.manage_gym` permission and `gym=None` can reset the password of **any other `gym=None` user**; the new plaintext password is returned verbatim in the HTML response body, enabling one-shot full account takeover. The victim&amp;#39;s original password is invalidated, locking them out permanently.&lt;/p&gt;
&lt;p&gt;### Details&lt;/p&gt;
&lt;p&gt;**File**: `wger/gym/views/user.py`&lt;/p&gt;
&lt;p&gt;The authorization guard in `reset_user_password` (and the parallel check in `gym_permissions_user_edit`) uses Django ORM object comparison:&lt;/p&gt;
&lt;p&gt;```python
# VULNERABLE - wger/gym/views/user.py
 if request.user.userprofile.gym != user.userprofile.gym:
    return HttpResponseForbidden()
 ```&lt;/p&gt;
&lt;p&gt;When both `request.user.userprofile.gym` and `user.userprofile.gym` are `None` (representing users with no gym assignment - the default for newly registered users before gym linking), Python evaluates `None != None` as `False`. The guard therefore passes without raising `HttpResponseForbidden`, and execution continues unconditionally to:&lt;/p&gt;
&lt;p&gt;```python
password = password_generator()
user.set_password(password)
 user.save()
return render(request, &amp;#39;user/trainer_login.html&amp;#39;, {&amp;#39;password&amp;#39;: password, ...})
```&lt;/p&gt;
&lt;p&gt;The generated password is rendered verbatim…&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; PyPI: wger&lt;/p&gt;
&lt;p&gt;### Summary&lt;/p&gt;
&lt;p&gt;The `reset_user_password` and `gym_permissions_user_edit` views in wger perform a gym-scope authorization check using Python object comparison (`!=`) that evaluates `None != None` as `False`, silently bypassing the guard when both the attacker and victim have no gym assignment (`gym=None`). A user with `gym.manage_gym` permission and `gym=None` can reset the password of **any other `gym=None` user**; the new plaintext password is returned verbatim in the HTML response body, enabling one-shot full account takeover. The victim&amp;#39;s original password is invalidated, locking them out permanently.&lt;/p&gt;
&lt;p&gt;### Details&lt;/p&gt;
&lt;p&gt;**File**: `wger/gym/views/user.py`&lt;/p&gt;
&lt;p&gt;The authorization guard in `reset_user_password` (and the parallel check in `gym_permissions_user_edit`) uses Django ORM object comparison:&lt;/p&gt;
&lt;p&gt;```python
# VULNERABLE - wger/gym/views/user.py
 if request.user.userprofile.gym != user.userprofile.gym:
    return HttpResponseForbidden()
 ```&lt;/p&gt;
&lt;p&gt;When both `request.user.userprofile.gym` and `user.userprofile.gym` are `None` (representing users with no gym assignment - the default for newly registered users before gym linking), Python evaluates `None != None` as `False`. The guard therefore passes without raising `HttpResponseForbidden`, and execution continues unconditionally to:&lt;/p&gt;
&lt;p&gt;```python
password = password_generator()
user.set_password(password)
 user.save()
return render(request, &amp;#39;user/trainer_login.html&amp;#39;, {&amp;#39;password&amp;#39;: password, ...})
```&lt;/p&gt;
&lt;p&gt;The generated password is rendered verbatim…&lt;/p&gt;</content:encoded>
      <guid isPermaLink="false">https://cve.radiocsirt.org/vuln/pysec-2026-574</guid>
    </item>
  </channel>
</rss>
