diff --git a/wagtail/admin/tests/test_editing_sessions.py b/wagtail/admin/tests/test_editing_sessions.py
index 5a817c1c25..0463e8f227 100644
--- a/wagtail/admin/tests/test_editing_sessions.py
+++ b/wagtail/admin/tests/test_editing_sessions.py
@@ -10,7 +10,7 @@ from django.utils import timezone
 from freezegun import freeze_time
 
 from wagtail.admin.models import EditingSession
-from wagtail.models import GroupPagePermission, Page
+from wagtail.models import GroupPagePermission, Page, Workflow, WorkflowContentType
 from wagtail.test.testapp.models import (
     Advert,
     AdvertWithCustomPrimaryKey,
@@ -1100,6 +1100,69 @@ class TestPingView(WagtailTestUtils, TestCase):
         )
         self.assertEqual(response.status_code, 404)
 
+    def test_moderator_without_explicit_edit_permission_on_snippet(self):
+        snippet = FullFeaturedSnippet.objects.create(text="Test snippet")
+        snippet.save_revision(user=self.other_user)
+
+        # Assign default workflow to the snippet model
+        snippet_content_type = ContentType.objects.get_for_model(FullFeaturedSnippet)
+        workflow = Workflow.objects.get()
+        WorkflowContentType.objects.create(
+            content_type=snippet_content_type,
+            workflow=workflow,
+        )
+
+        # submit snippet for moderation
+        workflow = snippet.get_workflow()
+        workflow.start(snippet, self.other_user)
+
+        # make user a moderator. The Moderators group has no explicit permission over the
+        # FullFeaturedSnippet model, and is only granted access to it via the workflow
+        moderators = Group.objects.get(name="Moderators")
+        self.user.is_superuser = False
+        self.user.save()
+        self.user.groups.add(moderators)
+
+        session = EditingSession.objects.create(
+            user=self.user,
+            content_type=ContentType.objects.get_for_model(FullFeaturedSnippet),
+            object_id=snippet.pk,
+            last_seen_at=TIMESTAMP_1,
+        )
+
+        # access to the ping endpoint should be granted
+        response = self.client.post(
+            reverse(
+                "wagtailadmin_editing_sessions:ping",
+                args=("tests", "fullfeaturedsnippet", snippet.id, session.id),
+            )
+        )
+        self.assertEqual(response.status_code, 200)
+
+    def test_locked_snippet(self):
+        snippet = FullFeaturedSnippet.objects.create(text="Test snippet")
+
+        snippet.locked = True
+        snippet.locked_by = self.other_user
+        snippet.locked_at = TIMESTAMP_PAST
+        snippet.save()
+
+        session = EditingSession.objects.create(
+            user=self.user,
+            content_type=ContentType.objects.get_for_model(FullFeaturedSnippet),
+            object_id=snippet.pk,
+            last_seen_at=TIMESTAMP_1,
+        )
+
+        # access to the ping endpoint should be granted
+        response = self.client.post(
+            reverse(
+                "wagtailadmin_editing_sessions:ping",
+                args=("tests", "fullfeaturedsnippet", snippet.id, session.id),
+            )
+        )
+        self.assertEqual(response.status_code, 200)
+
     def test_must_post(self):
         response = self.client.get(
             reverse(
diff --git a/wagtail/admin/views/editing_sessions.py b/wagtail/admin/views/editing_sessions.py
index c6a1aadcfb..f2ed2f9c88 100644
--- a/wagtail/admin/views/editing_sessions.py
+++ b/wagtail/admin/views/editing_sessions.py
@@ -11,7 +11,7 @@ from django.views.decorators.http import require_POST
 from wagtail.admin.models import EditingSession
 from wagtail.admin.ui.editing_sessions import EditingSessionsList
 from wagtail.admin.utils import get_user_display_name
-from wagtail.models import Page, Revision, RevisionMixin
+from wagtail.models import Page, Revision, RevisionMixin, WorkflowMixin
 
 
 @require_POST
@@ -34,10 +34,18 @@ def ping(request, app_label, model_name, object_id, session_id):
         except AttributeError:
             # model is neither a Page nor a snippet
             raise Http404
-        else:
-            can_edit = permission_policy.user_has_permission_for_instance(
-                request.user, "change", obj
-            )
+
+        can_edit = permission_policy.user_has_permission_for_instance(
+            request.user, "change", obj
+        )
+        if not can_edit and isinstance(obj, WorkflowMixin):
+            workflow = obj.get_workflow()
+            if workflow is not None:
+                current_workflow_task = obj.current_workflow_task
+                can_edit = (
+                    current_workflow_task
+                    and current_workflow_task.user_can_access_editor(obj, request.user)
+                )
 
     if not can_edit:
         raise Http404