Files
offline-db/content/tests/test_review_delete_idor.py
Barış Keserandgoogle-labs-jules[bot] d8bae9f83a 🛡️ Sentinel: [HIGH] Fix IDOR in ReviewViewSet (#186)
🚨 Severity: HIGH
💡 Vulnerability: The `ReviewViewSet` inherited `update` and `destroy` from `ModelViewSet` but only checked for global authentication (`IsAuthenticatedOrReadOnly`). This meant any logged-in user could edit or delete reviews belonging to other users (Insecure Direct Object Reference).
🎯 Impact: An attacker could modify or delete the site's entire review database if they had a registered account.
🔧 Fix: Created and applied an `IsOwnerOrReadOnly` custom permission class to ensure object-level authorization (request.user == obj.user) for all modifying requests.
✅ Verification: Tested locally via automated test `test_review_delete_idor` which confirms `403 Forbidden` when attempting unauthorized deletion.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-03-01 04:11:12 +00:00

27 lines
1.1 KiB
Python

from django.urls import reverse
from rest_framework.test import APITestCase
from rest_framework import status
from django.contrib.auth import get_user_model
from content.models import Anime, Review
User = get_user_model()
class ReviewDeleteIDORTest(APITestCase):
def setUp(self):
self.user1 = User.objects.create_user(username='user1', password='password')
self.user2 = User.objects.create_user(username='user2', password='password')
self.anime = Anime.objects.create(title='Test Anime')
self.review = Review.objects.create(user=self.user1, anime=self.anime, rating=9, text='Great show!')
def test_user_cannot_delete_other_user_review(self):
# Authenticate as user2
self.client.force_authenticate(user=self.user2)
# Try to delete user1's review
url = reverse('review-detail', args=[self.review.id])
response = self.client.delete(url)
# This should fail if IDOR is patched
self.assertNotEqual(response.status_code, status.HTTP_204_NO_CONTENT)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)