From 73d7560e4ec3bf5267095938e387353c46f0e3dc Mon Sep 17 00:00:00 2001 From: Matjaz Gregoric Date: Tue, 11 Oct 2022 19:54:26 +0200 Subject: [PATCH 01/77] build: kickoff the Olive release We follow the instructions from: https://openedx.atlassian.net/wiki/spaces/COMM/pages/19662426/Process+to+Create+an+Open+edX+Release#Make-release-specific-changes-on-the-release-branch --- .github/pull_request_template.md | 17 ----------------- .tx/config | 11 +++++++++++ openedx/core/release.py | 2 +- 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 0c61d1fb74fa..ed907c803152 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,20 +1,3 @@ - - ## Description Describe what this pull request changes, and why. Include implications for people using this change. diff --git a/.tx/config b/.tx/config index 5ab82585d37b..f9b8d235598e 100644 --- a/.tx/config +++ b/.tx/config @@ -67,3 +67,14 @@ source_file = conf/locale/en/LC_MESSAGES/wiki.po source_lang = en type = PO +[o:open-edx:p:open-edx-releases:r:release-olive] +file_filter = conf/locale//LC_MESSAGES/django.po +source_file = conf/locale/en/LC_MESSAGES/django.po +source_lang = en +type = PO + +[o:open-edx:p:open-edx-releases:r:release-olive-js] +file_filter = conf/locale//LC_MESSAGES/djangojs.po +source_file = conf/locale/en/LC_MESSAGES/djangojs.po +source_lang = en +type = PO diff --git a/openedx/core/release.py b/openedx/core/release.py index ce30df8cc543..295b8b1f014a 100644 --- a/openedx/core/release.py +++ b/openedx/core/release.py @@ -8,7 +8,7 @@ # The release line: an Open edX release name ("ficus"), or "master". # This should always be "master" on the master branch, and will be changed # manually when we start release-line branches, like open-release/ficus.master. -RELEASE_LINE = "master" +RELEASE_LINE = "olive" def doc_version(): From b2305b4ca3a2964c593a3af107b87180e6997333 Mon Sep 17 00:00:00 2001 From: Soban Javed Date: Thu, 17 Nov 2022 01:04:38 +0500 Subject: [PATCH 02/77] build: run tests for open-release branches on GH hosted runners --- .github/workflows/unit-tests-gh-hosted.yml | 4 ++-- .github/workflows/unit-tests.yml | 2 +- .github/workflows/verify-gha-unit-tests-count.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/unit-tests-gh-hosted.yml b/.github/workflows/unit-tests-gh-hosted.yml index fd01feeccd99..94473111404d 100644 --- a/.github/workflows/unit-tests-gh-hosted.yml +++ b/.github/workflows/unit-tests-gh-hosted.yml @@ -9,7 +9,7 @@ on: jobs: run-test: - if: github.repository != 'openedx/edx-platform' && github.repository != 'edx/edx-platform-private' + if: (github.repository != 'openedx/edx-platform' && github.repository != 'edx/edx-platform-private') || (github.repository == 'openedx/edx-platform' && (startsWith(github.base_ref, 'open-release') == true)) runs-on: ubuntu-20.04 strategy: fail-fast: false @@ -75,7 +75,7 @@ jobs: uses: ./.github/actions/unit-tests collect-and-verify: - if: github.repository != 'openedx/edx-platform' && github.repository != 'edx/edx-platform-private' + if: (github.repository != 'openedx/edx-platform' && github.repository != 'edx/edx-platform-private') || (github.repository == 'openedx/edx-platform' && (startsWith(github.base_ref, 'open-release') == true)) runs-on: ubuntu-20.04 strategy: matrix: diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 51ae55569146..66cb5f7fd13f 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -9,7 +9,7 @@ on: jobs: run-tests: name: python-${{ matrix.python-version }},django-${{ matrix.django-version }},${{ matrix.shard_name }} - if: github.repository == 'openedx/edx-platform' || github.repository == 'edx/edx-platform-private' + if: (github.repository == 'edx/edx-platform-private') || (github.repository == 'openedx/edx-platform' && (startsWith(github.base_ref, 'open-release') == false)) runs-on: [ edx-platform-runner ] strategy: matrix: diff --git a/.github/workflows/verify-gha-unit-tests-count.yml b/.github/workflows/verify-gha-unit-tests-count.yml index 039d45ad9548..c68092942d70 100644 --- a/.github/workflows/verify-gha-unit-tests-count.yml +++ b/.github/workflows/verify-gha-unit-tests-count.yml @@ -8,7 +8,7 @@ on: jobs: collect-and-verify: - if: github.repository == 'openedx/edx-platform' || github.repository == 'edx/edx-platform-private' + if: (github.repository == 'edx/edx-platform-private') || (github.repository == 'openedx/edx-platform' && (startsWith(github.base_ref, 'open-release') == false)) runs-on: [ edx-platform-runner ] steps: - name: sync directory owner From df4f843adaf7e67138334ebb31450f9ed2f8e651 Mon Sep 17 00:00:00 2001 From: Soban Javed Date: Tue, 22 Nov 2022 02:14:00 +0500 Subject: [PATCH 03/77] build: update shard in unit test worflow for forks This workflow wasn't updated when we updated shards for self-hosted runners, so updating in this commit --- .github/workflows/unit-tests-gh-hosted.yml | 2 +- .github/workflows/unit-tests.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/unit-tests-gh-hosted.yml b/.github/workflows/unit-tests-gh-hosted.yml index 94473111404d..5edfbff88f9d 100644 --- a/.github/workflows/unit-tests-gh-hosted.yml +++ b/.github/workflows/unit-tests-gh-hosted.yml @@ -31,7 +31,7 @@ jobs: "cms-2", "common-1", "common-2", - "common-3", + "xmodule-1" ] name: gh-hosted-python-${{ matrix.python-version }},django-${{ matrix.django-version }},${{ matrix.shard_name }} steps: diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 66cb5f7fd13f..50b896977391 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -80,7 +80,7 @@ jobs: # https://github.com/orgs/community/discussions/33579 success: name: Tests successful - if: always() + if: (github.repository == 'edx/edx-platform-private') || (github.repository == 'openedx/edx-platform' && (startsWith(github.base_ref, 'open-release') == false)) needs: - run-tests runs-on: ubuntu-latest From 39b7b2b426c8b60318e1821b8c6e6d39f92c7410 Mon Sep 17 00:00:00 2001 From: Syed Sajjad Hussain Shah Date: Thu, 17 Nov 2022 08:43:40 +0500 Subject: [PATCH 04/77] fix: XSS and open redirect vulnerability --- openedx/core/djangoapps/user_authn/utils.py | 10 ++++++++++ .../djangoapps/user_authn/views/tests/test_logout.py | 2 ++ 2 files changed, 12 insertions(+) diff --git a/openedx/core/djangoapps/user_authn/utils.py b/openedx/core/djangoapps/user_authn/utils.py index 490223eaecda..5b70d2427859 100644 --- a/openedx/core/djangoapps/user_authn/utils.py +++ b/openedx/core/djangoapps/user_authn/utils.py @@ -19,6 +19,13 @@ from openedx.core.djangoapps.user_api.accounts import USERNAME_MAX_LENGTH +def _remove_unsafe_bytes_from_url(url): + _UNSAFE_URL_BYTES_TO_REMOVE = ["\t", "\r", "\n"] + for byte in _UNSAFE_URL_BYTES_TO_REMOVE: + url = url.replace(byte, "") + return url + + def is_safe_login_or_logout_redirect(redirect_to, request_host, dot_client_id, require_https): """ Determine if the given redirect URL/path is safe for redirection. @@ -41,6 +48,8 @@ def is_safe_login_or_logout_redirect(redirect_to, request_host, dot_client_id, r login_redirect_whitelist = set(getattr(settings, 'LOGIN_REDIRECT_WHITELIST', [])) login_redirect_whitelist.add(request_host) + redirect_to = _remove_unsafe_bytes_from_url(redirect_to) + # Allow OAuth2 clients to redirect back to their site after logout. if dot_client_id: application = Application.objects.get(client_id=dot_client_id) @@ -50,6 +59,7 @@ def is_safe_login_or_logout_redirect(redirect_to, request_host, dot_client_id, r is_safe_url = http.is_safe_url( redirect_to, allowed_hosts=login_redirect_whitelist, require_https=require_https ) + return is_safe_url diff --git a/openedx/core/djangoapps/user_authn/views/tests/test_logout.py b/openedx/core/djangoapps/user_authn/views/tests/test_logout.py index 2a458cb4fcea..84fa3b8d7d1d 100644 --- a/openedx/core/djangoapps/user_authn/views/tests/test_logout.py +++ b/openedx/core/djangoapps/user_authn/views/tests/test_logout.py @@ -88,6 +88,8 @@ def test_no_redirect_supplied(self): @ddt.data( ('https://www.amazon.org', 'edx.org'), + ('/%09/google.com/', 'edx.org'), + ('java%0D%0Ascript%0D%0A%3aalert(document.domain)', 'edx.org'), ) @ddt.unpack def test_logout_redirect_failure(self, redirect_url, host): From 203bf9fc30df005a75c44e6e6335302b9ae80dfe Mon Sep 17 00:00:00 2001 From: connorhaugh <49422820+connorhaugh@users.noreply.github.com> Date: Mon, 28 Nov 2022 04:21:44 -0500 Subject: [PATCH 05/77] fix: studio submit handler (olive backport) (#31219) * fix: studio submit handler * style: remove extra line Co-authored-by: Matjaz Gregoric --- cms/djangoapps/contentstore/views/component.py | 5 +++++ cms/djangoapps/contentstore/views/tests/test_item.py | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/cms/djangoapps/contentstore/views/component.py b/cms/djangoapps/contentstore/views/component.py index da15dc5c84dc..d20cab68d74a 100644 --- a/cms/djangoapps/contentstore/views/component.py +++ b/cms/djangoapps/contentstore/views/component.py @@ -538,6 +538,11 @@ def component_handler(request, usage_key_string, handler, suffix=''): """ usage_key = UsageKey.from_string(usage_key_string) + # Addendum: + # TNL 101-62 studio write permission is also checked for editing content. + + if handler == 'submit_studio_edits' and not has_course_author_access(request.user, usage_key.course_key): + raise PermissionDenied("No studio write Permissions") # Let the module handle the AJAX req = django_to_webob_request(request) diff --git a/cms/djangoapps/contentstore/views/tests/test_item.py b/cms/djangoapps/contentstore/views/tests/test_item.py index 055cea6401c2..cf7ef1ecc3a8 100644 --- a/cms/djangoapps/contentstore/views/tests/test_item.py +++ b/cms/djangoapps/contentstore/views/tests/test_item.py @@ -8,6 +8,7 @@ import ddt from django.conf import settings +from django.core.exceptions import PermissionDenied from django.http import Http404 from django.test import TestCase from django.test.client import RequestFactory @@ -2197,6 +2198,15 @@ def create_response(handler, request, suffix): # lint-amnesty, pylint: disable= self.assertEqual(component_handler(self.request, self.usage_key_string, 'dummy_handler').status_code, status_code) + def test_submit_studio_edits_checks_author_permission(self): + with self.assertRaises(PermissionDenied): + with patch( + 'common.djangoapps.student.auth.has_course_author_access', + return_value=False + ) as mocked_has_course_author_access: + component_handler(self.request, self.usage_key_string, 'submit_studio_edits') + assert mocked_has_course_author_access.called is True + @ddt.data((True, True), (False, False),) @ddt.unpack def test_aside(self, is_xblock_aside, is_get_aside_called): From 903ea00a124680100a96f91c9735a71f35cce065 Mon Sep 17 00:00:00 2001 From: Agrendalath Date: Mon, 28 Nov 2022 16:14:31 +0100 Subject: [PATCH 06/77] feat!: update Drag and Drop v2 XBlock to prevent XSS vulnerabilities BREAKING CHANGE: disallowed HTML tags (e.g.