Skip to content

Arbitrary privilege escalation, Arbitrary comment delete, Stored XSS, Authorization Bypass

High
DogukanUrker published GHSA-h239-vv39-v3vx Aug 14, 2025

Package

flaskBlog (python)

Affected versions

2.8.0

Patched versions

None

Description

1. Arbitrary privilege escalation

Description

An arbitrary user can change his role to "admin", giving its relative privileges (e.g. delete users, posts, comments etc.). The problem is in the routes/adminPanelUsers file, between line 36 and line 49:

            if "userDeleteButton" in request.form:
                Log.info(
                    f"Admin: {session['userName']} deleted user: {request.form['userName']}"
                )

                Delete.user(request.form["userName"])

            if "userRoleChangeButton" in request.form:
                Log.info(
                    f"Admin: {session['userName']} changed {request.form['userName']}'s role"
                )

                changeUserRole(request.form["userName"])

These lines of codes are right before the control of the user role, so they are executed even if the user is not an admin.
Another vulnerability showed in the code is that an arbitrary user could delete any other user of the blog, but escalating the privileges would allow anyway to do that, so the privilege escalation vulnerability is worst.

PoC

The "test" user's profile before the attack. As can be seen, it is non privileged (Role: User).
image

The image below shows the crafted request made using the "test" user.
image

The "test" user's profile after the attack. The user Role now is admin, giving it complete access to all the functionalities.
image

Solution

Move the code that checks for the user role BEFORE line 36 of the file routes/adminPanelUsers.

2. Arbitrary comment delete

Description

When deleting a comment, there's no validation of the ownership of the comment. Every user can delete an arbitrary comment of another user on every post, by simply intercepting the delete request and changing the commentID.
The code that causes the problem is in routes/post.py, line 77:

if "commentDeleteButton" in request.form:
    Delete.comment(request.form["commentID"])

PoC

image
In the image above, the commentID requested for deletion is NOT owned by the user that made the request.

Solution

Before deleting a comment, check if the user that is making the request owns the comment referred by commentID.

3. Stored XSS

Description

When creating a post, there's no validation of the content of the post stored in the variable "postContent". The vulnerability arises when displaying the content of the post using the | safe filter, that tells the engine to not escape the rendered content. This can lead to a stored XSS inside the content of the post.
The code that causes the problem is in template/routes.html, line 67:
<p>{{ content | safe }} <br /></p>.

PoC

Example of a malicious user intercepting the createPost request. As can be seen in the image, the payload is a simple <script>alert("STORED XSS")</script>.
image

Going to the home of the blog after creating the post triggers the XSS.
image

Solution

Remove the | safe filter to let Flask escape the content of the post.

4. Authorization Bypass

Description

The code checks if the userRole is "admin" only when visiting the /admin page, but not when visiting its subroutes. Specifically, only the file routes/adminPanel.py checks the user role when a user is trying to access the admin page, but that control is not done for the pages routes/adminPanelComments.py and routes/adminPanelPosts.py.
Thus, an unauthorized user can bypass the inteded restrictions, leaking sensitive data and accessing the following pages:

  • /admin/posts
  • /adminpanel/posts
  • /admin/comments
  • /adminpanel/comments

PoC

image
The user accessing the page is NOT admin.

Solution

Add a control for the user role when a user tries to access the /admin/ subroutes.

Severity

High

CVE ID

No known CVE

Weaknesses

Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users. Learn more on MITRE.

Improper Protection of Alternate Path

The product does not sufficiently protect all possible paths that a user can take to access restricted functionality or resources. Learn more on MITRE.

Direct Request ('Forced Browsing')

The web application does not adequately enforce appropriate authorization on all restricted URLs, scripts, or files. Learn more on MITRE.

Authorization Bypass Through User-Controlled Key

The system's authorization functionality does not prevent one user from gaining access to another user's data or record by modifying the key value identifying the data. Learn more on MITRE.

Reliance on Untrusted Inputs in a Security Decision

The product uses a protection mechanism that relies on the existence or values of an input, but the input can be modified by an untrusted actor in a way that bypasses the protection mechanism. Learn more on MITRE.

Credits