Summary
Security audit identified 7 vulnerabilities (3 CRITICAL, 3 HIGH, 1 MEDIUM) in SkyLearn. The most severe is the entire payments module (11 views) having zero authentication, allowing anonymous payment bypass and invoice manipulation.
Critical Findings
1. CRITICAL: Entire Payments Module Missing Authentication (11 Views)
File: payments/views.py:18-191
None of the 11 payment views have @login_required or any authentication decorator:
def payment_paypal(request): # Line 18 - no decorator
def payment_stripe(request): # Line 22 - no decorator
class PaymentGetwaysView(TemplateView): # Line 38 - no mixin
def stripe_charge(request): # Line 51 - no decorator, processes Stripe charges
def gopay_charge(request): # Line 70 - no decorator, processes GoPay payments
def paymentComplete(request): # Line 146 - no decorator, marks invoices as paid
def create_invoice(request): # Line 159 - no decorator, creates invoices
def invoice_detail(request, slug): # Line 185 - no decorator, displays any invoice
2. CRITICAL: Payment Completion Without Server-Side Verification
File: payments/views.py:146-156
def paymentComplete(request):
if request.is_ajax() or request.method == "POST":
invoice_id = request.session["invoice_session"]
invoice = Invoice.objects.get(id=invoice_id)
invoice.payment_complete = True
invoice.save()
Marks invoices as paid without verifying any payment actually occurred with Stripe/PayPal/GoPay.
3. CRITICAL: Invoice Detail IDOR — No Auth, No Ownership
File: payments/views.py:185-190
def invoice_detail(request, slug):
return render(request, "invoice_detail.html",
context={"invoice": Invoice.objects.get(invoice_code=slug)})
HIGH Findings
4. post_add Missing @lecturer_required (1-of-N)
File: core/views.py:40-52
post_add has only @login_required, but edit_post and delete_post both have @login_required AND @lecturer_required. Any student can create official news/events.
5. File/Video Edit No Course Ownership Check
File: course/views.py:285-303
handle_file_edit fetches file by file_id without verifying it belongs to the course in the URL or to the requesting lecturer. A lecturer teaching Course A can modify files belonging to Course B.
6. Result PDF — Any Lecturer Views Any Course's Grades
File: result/views.py:277-446
result_sheet_pdf_view takes any course ID without checking the requesting lecturer is allocated to that course. 1-of-N: add_score_for (line 70) filters by allocated_course__lecturer__pk=request.user.id.
7. MEDIUM: SearchView Has No Authentication
File: search/views.py:1-38
SearchView(ListView) has no LoginRequiredMixin. Anonymous users can search and enumerate all programs, courses, quizzes, and events.
What Was Fixed from django-lms
SkyLearn correctly fixed the 2 most critical django-lms findings:
handle_file_delete now has @login_required + @lecturer_required
handle_video_delete now has @login_required + @lecturer_required
Recommended Systemic Fix
Add Django's LoginRequiredMiddleware (Django 4.1+) globally. Use @login_not_required for the handful of public views.
Reported by Lighthouse Security Research (lighthouse1212.com)
Summary
Security audit identified 7 vulnerabilities (3 CRITICAL, 3 HIGH, 1 MEDIUM) in SkyLearn. The most severe is the entire payments module (11 views) having zero authentication, allowing anonymous payment bypass and invoice manipulation.
Critical Findings
1. CRITICAL: Entire Payments Module Missing Authentication (11 Views)
File:
payments/views.py:18-191None of the 11 payment views have
@login_requiredor any authentication decorator:2. CRITICAL: Payment Completion Without Server-Side Verification
File:
payments/views.py:146-156Marks invoices as paid without verifying any payment actually occurred with Stripe/PayPal/GoPay.
3. CRITICAL: Invoice Detail IDOR — No Auth, No Ownership
File:
payments/views.py:185-190HIGH Findings
4. post_add Missing @lecturer_required (1-of-N)
File:
core/views.py:40-52post_addhas only@login_required, butedit_postanddelete_postboth have@login_requiredAND@lecturer_required. Any student can create official news/events.5. File/Video Edit No Course Ownership Check
File:
course/views.py:285-303handle_file_editfetches file byfile_idwithout verifying it belongs to the course in the URL or to the requesting lecturer. A lecturer teaching Course A can modify files belonging to Course B.6. Result PDF — Any Lecturer Views Any Course's Grades
File:
result/views.py:277-446result_sheet_pdf_viewtakes any course ID without checking the requesting lecturer is allocated to that course. 1-of-N:add_score_for(line 70) filters byallocated_course__lecturer__pk=request.user.id.7. MEDIUM: SearchView Has No Authentication
File:
search/views.py:1-38SearchView(ListView)has noLoginRequiredMixin. Anonymous users can search and enumerate all programs, courses, quizzes, and events.What Was Fixed from django-lms
SkyLearn correctly fixed the 2 most critical django-lms findings:
handle_file_deletenow has@login_required+@lecturer_requiredhandle_video_deletenow has@login_required+@lecturer_requiredRecommended Systemic Fix
Add Django's
LoginRequiredMiddleware(Django 4.1+) globally. Use@login_not_requiredfor the handful of public views.Reported by Lighthouse Security Research (lighthouse1212.com)