From patchwork Thu May 25 07:38:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Donnellan X-Patchwork-Id: 766876 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3wYLkr5bplz9s7B for ; Thu, 25 May 2017 17:39:48 +1000 (AEST) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3wYLkr4VxvzDqhc for ; Thu, 25 May 2017 17:39:48 +1000 (AEST) X-Original-To: patchwork@lists.ozlabs.org Delivered-To: patchwork@lists.ozlabs.org Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3wYLkd5ljBzDqhH for ; Thu, 25 May 2017 17:39:37 +1000 (AEST) Received: from pps.filterd (m0098393.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.20/8.16.0.20) with SMTP id v4P7cWbD077110 for ; Thu, 25 May 2017 03:39:30 -0400 Received: from e23smtp05.au.ibm.com (e23smtp05.au.ibm.com [202.81.31.147]) by mx0a-001b2d01.pphosted.com with ESMTP id 2anrv3vhp8-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Thu, 25 May 2017 03:39:29 -0400 Received: from localhost by e23smtp05.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 25 May 2017 17:39:25 +1000 Received: from d23relay07.au.ibm.com (202.81.31.226) by e23smtp05.au.ibm.com (202.81.31.211) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 25 May 2017 17:39:23 +1000 Received: from d23av06.au.ibm.com (d23av06.au.ibm.com [9.190.235.151]) by d23relay07.au.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v4P7dFLt61538374 for ; Thu, 25 May 2017 17:39:23 +1000 Received: from d23av06.au.ibm.com (localhost [127.0.0.1]) by d23av06.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id v4P7coAH001505 for ; Thu, 25 May 2017 17:38:50 +1000 Received: from ozlabs.au.ibm.com (ozlabs.au.ibm.com [9.192.253.14]) by d23av06.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id v4P7co1E000816; Thu, 25 May 2017 17:38:50 +1000 Received: from ajd.ozlabs.ibm.com (haven.au.ibm.com [9.192.254.114]) (using TLSv1.2 with cipher AES128-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.au.ibm.com (Postfix) with ESMTPSA id BF67CA00B3; Thu, 25 May 2017 17:38:25 +1000 (AEST) From: Andrew Donnellan To: patchwork@lists.ozlabs.org Subject: [PATCH 1/2] bundle: Fix use of basic auth for bundle mboxes Date: Thu, 25 May 2017 17:38:04 +1000 X-Mailer: git-send-email 2.11.0 X-TM-AS-MML: disable x-cbid: 17052507-0016-0000-0000-00000240CEDC X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17052507-0017-0000-0000-000006BE492C Message-Id: <20170525073805.30513-1-andrew.donnellan@au1.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-05-25_05:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=1 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1703280000 definitions=main-1705250143 X-BeenThere: patchwork@lists.ozlabs.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Patchwork development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: patchwork-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Patchwork" Commit 0b4f508a8438 ("views: Allow use of basic auth for bundle mboxes") added support for using Django REST Framework's BasicAuthentication to authenticate when accessing the bundle-mbox view. To check the user's credentials, we call BasicAuthentication.authenticate(), however, we don't check whether the returned user is actually the bundle owner. This means that any user can access any private bundle if they authenticate using basic authentication. Additionally, if invalid credentials are provided via a basic authentication header, BasicAuthentication.authenticate() will throw an AuthenticationFailed exception. We currently don't catch this, resulting in an exception page being displayed rather than a 404. Add a new helper, rest_auth(), that takes a request and returns a user. Call this in bundle_mbox() and save the result into request.user before we check whether request.user is actually the bundle owner. Found by code inspection. Fixes: 0b4f508a8438 ("views: Allow use of basic auth for bundle mboxes") Signed-off-by: Andrew Donnellan --- Given this is a (very, very, very minor) security issue, this should land in the 2.0 release. --- patchwork/views/bundle.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/patchwork/views/bundle.py b/patchwork/views/bundle.py index dc9b74b..387b7c6 100644 --- a/patchwork/views/bundle.py +++ b/patchwork/views/bundle.py @@ -37,9 +37,19 @@ from patchwork.views.utils import bundle_to_mbox if settings.ENABLE_REST_API: from rest_framework.authentication import BasicAuthentication # noqa - basic_auth = BasicAuthentication() -else: - basic_auth = None + from rest_framework.exceptions import AuthenticationFailed + + +def rest_auth(request): + if not settings.ENABLE_REST_API: + return request.user + try: + auth_result = BasicAuthentication().authenticate(request) + if auth_result: + return auth_result[0] + except AuthenticationFailed: + pass + return request.user @login_required @@ -140,8 +150,8 @@ def bundle_mbox(request, username, bundlename): bundle = get_object_or_404(Bundle, owner__username=username, name=bundlename) - if not (request.user == bundle.owner or bundle.public or - (basic_auth and basic_auth.authenticate(request))): + request.user = rest_auth(request) + if not (request.user == bundle.owner or bundle.public): return HttpResponseNotFound() response = HttpResponse(content_type='text/plain')