diff --git a/app/controllers/course/wiki.php b/app/controllers/course/wiki.php
index ddda49af86fb6dc6f4ad39017eb3d738eb19c188..6fbd7ce5e599bc7a1eaad212abeb8b73367394ac 100644
--- a/app/controllers/course/wiki.php
+++ b/app/controllers/course/wiki.php
@@ -1338,6 +1338,8 @@ class Course_WikiController extends AuthenticatedController
 
     private function validateWikiPage(WikiPage $page, Range $context, bool $for_edit = false): void
     {
+        $page->range_id = $page->range_id ?: $context->id;
+
         if (
             !$page->isNew()
             && $page->range_id !== $context->id
@@ -1349,7 +1351,11 @@ class Course_WikiController extends AuthenticatedController
         }
 
         if ($for_edit && !$page->isEditable()) {
-            throw new Exception(_('Sie dürfen diese Wikiseite nicht bearbeiten'));
+            if ($page->isNew()) {
+                throw new AccessDeniedException(_('Sie dürfen keine neue Wikiseite anlegen.'));
+            } else {
+                throw new AccessDeniedException(_('Sie dürfen diese Wikiseite nicht bearbeiten'));
+            }
         }
     }
 }
diff --git a/lib/classes/RangeFactory.php b/lib/classes/RangeFactory.php
index 8da592a28a18e8311d688440d4181d0eb8b217a0..f70e25a2aaba514941f753625617c1ec9bac1a8f 100644
--- a/lib/classes/RangeFactory.php
+++ b/lib/classes/RangeFactory.php
@@ -8,16 +8,24 @@
  */
 final class RangeFactory
 {
-    const TYPE_MAPPING = [
+    public const TYPE_MAPPING = [
         'sem'  => 'course',
         'user' => 'user',
         'inst' => 'institute',
         'fak'  => 'institute',
     ];
 
-    public static function find($id)
-    {
-        $type = get_object_type($id, ['sem', 'user', 'inst', 'fak']);
+    /**
+     * Finds a Range for a given id or false if there is no Range with the id.
+     * @param string $id   Range id
+     * @param array $search_types array can have values of 'sem', 'user', 'inst' and/or 'fak'
+     * @return Range|false
+     */
+    public static function find(
+        string $id,
+        array $search_types = ['sem', 'user', 'inst', 'fak']
+    ) {
+        $type = get_object_type($id, $search_types);
         if ($type === false) {
             return false;
         }
@@ -30,12 +38,10 @@ final class RangeFactory
      *
      * @param string $type Range type
      * @param mixed  $id   Range id
-     * @return mixed any of the supported range types
+     * @return Range any of the supported range types
      * @throws Exception when an invalid range type was given
-     *
-     * @todo Should this be more dynamic in case any more ranges are added?
      */
-    public static function createRange($type, $id)
+    public static function createRange(string $type, string $id): Range
     {
         if ($type === 'user') {
             return new User($id);
diff --git a/lib/models/WikiPage.php b/lib/models/WikiPage.php
index 6cb4c8a2cf98b4552ba8e7ce2c9f5a7c3738d3f5..57b9c891ccf33009d3468eb7467b7346c44a766d 100644
--- a/lib/models/WikiPage.php
+++ b/lib/models/WikiPage.php
@@ -191,6 +191,15 @@ class WikiPage extends SimpleORMap implements PrivacyObject
             return false;
         }
 
+        // Check create permission if page is new
+        if ($this->isNew()) {
+            $range = RangeFactory::find($this->range_id, ['sem', 'inst']);
+            $permission = $range->getConfiguration()->getValue('WIKI_CREATE_PERMISSION');
+            return $permission === 'all'
+                || $GLOBALS['perm']->have_studip_perm($permission, $this->range_id, $user_id);
+        }
+
+        // Otherwise check write permissions
         if ($this->write_permission === 'all') {
             return true;
         }