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).

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

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

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

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>
.

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

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

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.
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: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).

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

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

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:
PoC
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>
.Going to the home of the blog after creating the post triggers the XSS.

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 fileroutes/adminPanel.py
checks the user role when a user is trying to access the admin page, but that control is not done for the pagesroutes/adminPanelComments.py
androutes/adminPanelPosts.py
.Thus, an unauthorized user can bypass the inteded restrictions, leaking sensitive data and accessing the following pages:
PoC
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.