fix a vulnerability in contest submission

This commit is contained in:
zema1
2018-11-29 11:36:44 +08:00
parent f2f6b48d69
commit 3406791d2a

View File

@@ -1,15 +1,15 @@
import ipaddress import ipaddress
from account.decorators import login_required, check_contest_permission from account.decorators import login_required, check_contest_permission
from contest.models import ContestStatus, ContestRuleType
from judge.tasks import judge_task from judge.tasks import judge_task
from options.options import SysOptions
# from judge.dispatcher import JudgeDispatcher # from judge.dispatcher import JudgeDispatcher
from problem.models import Problem, ProblemRuleType from problem.models import Problem, ProblemRuleType
from contest.models import Contest, ContestStatus, ContestRuleType
from options.options import SysOptions
from utils.api import APIView, validate_serializer from utils.api import APIView, validate_serializer
from utils.throttling import TokenBucket
from utils.captcha import Captcha
from utils.cache import cache from utils.cache import cache
from utils.captcha import Captcha
from utils.throttling import TokenBucket
from ..models import Submission from ..models import Submission
from ..serializers import (CreateSubmissionSerializer, SubmissionModelSerializer, from ..serializers import (CreateSubmissionSerializer, SubmissionModelSerializer,
ShareSubmissionSerializer) ShareSubmissionSerializer)
@@ -34,26 +34,27 @@ class SubmissionAPI(APIView):
# if not can_consume: # if not can_consume:
# return "Captcha is required" # return "Captcha is required"
@check_contest_permission(check_type="problems")
def check_contest_permission(self, request):
contest = self.contest
if contest.status == ContestStatus.CONTEST_ENDED:
return self.error("The contest have ended")
if not request.user.is_contest_admin(contest):
user_ip = ipaddress.ip_address(request.session.get("ip"))
if contest.allowed_ip_ranges:
if not any(user_ip in ipaddress.ip_network(cidr, strict=False) for cidr in contest.allowed_ip_ranges):
return self.error("Your IP is not allowed in this contest")
@validate_serializer(CreateSubmissionSerializer) @validate_serializer(CreateSubmissionSerializer)
@login_required @login_required
def post(self, request): def post(self, request):
data = request.data data = request.data
hide_id = False hide_id = False
if data.get("contest_id"): if data.get("contest_id"):
try: error = self.check_contest_permission(request)
contest = Contest.objects.get(id=data["contest_id"], visible=True) if error:
except Contest.DoesNotExist: return error
return self.error("Contest doesn't exist.") contest = self.contest
if contest.status == ContestStatus.CONTEST_ENDED:
return self.error("The contest have ended")
if not request.user.is_contest_admin(contest):
if contest.status == ContestStatus.CONTEST_NOT_START:
return self.error("Contest have not started")
user_ip = ipaddress.ip_address(request.session.get("ip"))
if contest.allowed_ip_ranges:
if not any(user_ip in ipaddress.ip_network(cidr, strict=False) for cidr in contest.allowed_ip_ranges):
return self.error("Your IP is not allowed in this contest")
if not contest.problem_details_permission(request.user): if not contest.problem_details_permission(request.user):
hide_id = True hide_id = True