diff --git a/app/assets/javascripts/content_editor/extensions/image.js b/app/assets/javascripts/content_editor/extensions/image.js
index 65849ec4d0d9f2dc5d219c364430c2c540073643..fc4c108b773d787077c8a9e1919fc9aa208c76d4 100644
--- a/app/assets/javascripts/content_editor/extensions/image.js
+++ b/app/assets/javascripts/content_editor/extensions/image.js
@@ -52,6 +52,22 @@ export default Image.extend({
           return img.getAttribute('title');
         },
       },
+      width: {
+        default: null,
+        parseHTML: (element) => {
+          const img = resolveImageEl(element);
+
+          return img.getAttribute('width');
+        },
+      },
+      height: {
+        default: null,
+        parseHTML: (element) => {
+          const img = resolveImageEl(element);
+
+          return img.getAttribute('height');
+        },
+      },
       isReference: {
         default: false,
         renderHTML: () => '',
@@ -76,6 +92,8 @@ export default Image.extend({
         src: HTMLAttributes.src,
         alt: HTMLAttributes.alt,
         title: HTMLAttributes.title,
+        width: HTMLAttributes.width,
+        height: HTMLAttributes.height,
       },
     ];
   },
diff --git a/app/assets/javascripts/content_editor/services/serialization_helpers.js b/app/assets/javascripts/content_editor/services/serialization_helpers.js
index 5ee9d66def1666899596226866a0e7c193706717..98f8ce518fe29b6c1a74f7e74c543424f7440da7 100644
--- a/app/assets/javascripts/content_editor/services/serialization_helpers.js
+++ b/app/assets/javascripts/content_editor/services/serialization_helpers.js
@@ -308,7 +308,7 @@ export function renderHardBreak(state, node, parent, index) {
 }
 
 export function renderImage(state, node) {
-  const { alt, canonicalSrc, src, title, isReference } = node.attrs;
+  const { alt, canonicalSrc, src, title, width, height, isReference } = node.attrs;
 
   if (isString(src) || isString(canonicalSrc)) {
     const quotedTitle = title ? ` ${state.quote(title)}` : '';
@@ -316,7 +316,17 @@ export function renderImage(state, node) {
       ? `[${canonicalSrc}]`
       : `(${state.esc(canonicalSrc || src)}${quotedTitle})`;
 
-    state.write(`![${state.esc(alt || '')}]${sourceExpression}`);
+    const sizeAttributes = [];
+    if (width) {
+      sizeAttributes.push(`width=${JSON.stringify(width)}`);
+    }
+    if (height) {
+      sizeAttributes.push(`height=${JSON.stringify(height)}`);
+    }
+
+    const attributes = sizeAttributes.length ? `{${sizeAttributes.join(' ')}}` : '';
+
+    state.write(`![${state.esc(alt || '')}]${sourceExpression}${attributes}`);
   }
 }
 
diff --git a/glfm_specification/input/gitlab_flavored_markdown/glfm_example_status.yml b/glfm_specification/input/gitlab_flavored_markdown/glfm_example_status.yml
index e986f5309e876b8b4d6ba77d119f945139c27ab7..501d06692ea19eb6b0bb2935fdcbe15084165f1f 100644
--- a/glfm_specification/input/gitlab_flavored_markdown/glfm_example_status.yml
+++ b/glfm_specification/input/gitlab_flavored_markdown/glfm_example_status.yml
@@ -78,3 +78,33 @@
   skip_running_conformance_wysiwyg_tests: Example currently fails. See https://gitlab.com/gitlab-org/gitlab/-/issues/383866
   skip_running_snapshot_wysiwyg_html_tests: Example currently fails. See https://gitlab.com/gitlab-org/gitlab/-/issues/383866
   skip_running_snapshot_prosemirror_json_tests: Example currently fails. See https://gitlab.com/gitlab-org/gitlab/-/issues/383866
+08_05_00__gitlab_internal_extension_markdown__image_attributes__001:
+  skip_update_example_snapshot_html_wysiwyg: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+  skip_update_example_snapshot_prosemirror_json: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+  skip_running_conformance_wysiwyg_tests: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+  skip_running_snapshot_wysiwyg_html_tests: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+  skip_running_snapshot_prosemirror_json_tests: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+08_05_00__gitlab_internal_extension_markdown__image_attributes__002:
+  skip_update_example_snapshot_html_wysiwyg: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+  skip_update_example_snapshot_prosemirror_json: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+  skip_running_conformance_wysiwyg_tests: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+  skip_running_snapshot_wysiwyg_html_tests: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+  skip_running_snapshot_prosemirror_json_tests: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+08_05_00__gitlab_internal_extension_markdown__image_attributes__003:
+  skip_update_example_snapshot_html_wysiwyg: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+  skip_update_example_snapshot_prosemirror_json: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+  skip_running_conformance_wysiwyg_tests: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+  skip_running_snapshot_wysiwyg_html_tests: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+  skip_running_snapshot_prosemirror_json_tests: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+08_05_00__gitlab_internal_extension_markdown__image_attributes__004:
+  skip_update_example_snapshot_html_wysiwyg: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+  skip_update_example_snapshot_prosemirror_json: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+  skip_running_conformance_wysiwyg_tests: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+  skip_running_snapshot_wysiwyg_html_tests: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+  skip_running_snapshot_prosemirror_json_tests: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+08_05_00__gitlab_internal_extension_markdown__image_attributes__005:
+  skip_update_example_snapshot_html_wysiwyg: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+  skip_update_example_snapshot_prosemirror_json: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+  skip_running_conformance_wysiwyg_tests: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+  skip_running_snapshot_wysiwyg_html_tests: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
+  skip_running_snapshot_prosemirror_json_tests: WYSYWIG and prosemirror examples not generated correctly. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106733#note_1206201340
diff --git a/glfm_specification/input/gitlab_flavored_markdown/glfm_internal_extensions.md b/glfm_specification/input/gitlab_flavored_markdown/glfm_internal_extensions.md
index 4d5b16b7ec070f2882a5648dd6404739118df326..63518a93f71f5d165a8122d3adc68e0ab2ab9d21 100644
--- a/glfm_specification/input/gitlab_flavored_markdown/glfm_internal_extensions.md
+++ b/glfm_specification/input/gitlab_flavored_markdown/glfm_internal_extensions.md
@@ -696,4 +696,54 @@ Fernstraßen<wbr>bau<wbr>privat<wbr>finanzierungs<wbr>gesetz
 .
 TODO: Write canonical HTML for this example
 ````````````````````````````````
+
+## Image Attributes
+
+See
+[Change the image dimensions](https://docs.gitlab.com/ee/user/markdown.html#change-the-image-dimensions)
+in the GitLab Flavored Markdown documentation.
+
+The `width` and `height` attributes for an image can be specified directly after
+the image markdown.
+
+General syntax conforms to the 
+[commonmark-hs attribute syntax](https://github.com/jgm/commonmark-hs/blob/master/commonmark-extensions/test/attributes.md)
+where it makes sense.
+
+```````````````````````````````` example gitlab
+![](https://gitlab.com/logo.png){width="100" height="100"}
+.
+<p><img src="https://gitlab.com/logo.png" width="100" height="100"></p>
+````````````````````````````````
+
+`%` and `px` units may also be specified.
+
+```````````````````````````````` example gitlab
+![](https://gitlab.com/logo.png){width="100%"}
+.
+<p><img src="https://gitlab.com/logo.png" width="100%"></p>
+````````````````````````````````
+
+```````````````````````````````` example gitlab
+![](https://gitlab.com/logo.png){height="100px"}
+.
+<p><img src="https://gitlab.com/logo.png" height="100px"></p>
+````````````````````````````````
+
+Whitespace is tolerated around the delimiters:
+
+```````````````````````````````` example gitlab
+![](https://gitlab.com/logo.png){ width="100" height="100" }
+.
+<p><img src="https://gitlab.com/logo.png" width="100" height="100"></p>
+````````````````````````````````
+
+Attributes must immediately follow the image markdown.
+
+```````````````````````````````` example gitlab
+![](https://gitlab.com/logo.png) {width="100" height="100"}
+.
+<p><img src="https://gitlab.com/logo.png"> {width="100" height="100"}</p>
+````````````````````````````````
+
 <!-- END TESTS -->
diff --git a/glfm_specification/output_example_snapshots/examples_index.yml b/glfm_specification/output_example_snapshots/examples_index.yml
index 934be77ebd56dd1b2f9695de4585741a13c5506a..d08f16c7313029fb75c2af67a8e232298bd47b56 100644
--- a/glfm_specification/output_example_snapshots/examples_index.yml
+++ b/glfm_specification/output_example_snapshots/examples_index.yml
@@ -2240,3 +2240,18 @@
 08_04_52__gitlab_internal_extension_markdown__migrated_golden_master_examples__word_break__001:
   spec_example_position: 749
   source_specification: gitlab
+08_05_00__gitlab_internal_extension_markdown__image_attributes__001:
+  spec_example_position: 750
+  source_specification: gitlab
+08_05_00__gitlab_internal_extension_markdown__image_attributes__002:
+  spec_example_position: 751
+  source_specification: gitlab
+08_05_00__gitlab_internal_extension_markdown__image_attributes__003:
+  spec_example_position: 752
+  source_specification: gitlab
+08_05_00__gitlab_internal_extension_markdown__image_attributes__004:
+  spec_example_position: 753
+  source_specification: gitlab
+08_05_00__gitlab_internal_extension_markdown__image_attributes__005:
+  spec_example_position: 754
+  source_specification: gitlab
diff --git a/glfm_specification/output_example_snapshots/html.yml b/glfm_specification/output_example_snapshots/html.yml
index c724f670bb516bfa01068a7e472e2b8b019ccc78..06e88ce4b817716ac4aff1120e7fb8cfa93e2aab 100644
--- a/glfm_specification/output_example_snapshots/html.yml
+++ b/glfm_specification/output_example_snapshots/html.yml
@@ -8625,3 +8625,28 @@
     <p data-sourcepos="1:1-1:60" dir="auto">Fernstraßen<wbr>bau<wbr>privat<wbr>finanzierungs<wbr>gesetz</wbr></wbr></wbr></wbr></p>
   wysiwyg: |-
     <p>Fernstraßenbauprivatfinanzierungsgesetz</p>
+08_05_00__gitlab_internal_extension_markdown__image_attributes__001:
+  canonical: |
+    <p><img src="https://gitlab.com/logo.png" width="100" height="100"></p>
+  static: |-
+    <p data-sourcepos="1:1-1:58" dir="auto"><a class="no-attachment-icon" href="https://gitlab.com/logo.png" target="_blank" rel="nofollow noreferrer noopener"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="" width="100" height="100" decoding="async" class="lazy" data-src="https://gitlab.com/logo.png"></a></p>
+08_05_00__gitlab_internal_extension_markdown__image_attributes__002:
+  canonical: |
+    <p><img src="https://gitlab.com/logo.png" width="100%"></p>
+  static: |-
+    <p data-sourcepos="1:1-1:46" dir="auto"><a class="no-attachment-icon" href="https://gitlab.com/logo.png" target="_blank" rel="nofollow noreferrer noopener"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="" width="100%" decoding="async" class="lazy" data-src="https://gitlab.com/logo.png"></a></p>
+08_05_00__gitlab_internal_extension_markdown__image_attributes__003:
+  canonical: |
+    <p><img src="https://gitlab.com/logo.png" height="100px"></p>
+  static: |-
+    <p data-sourcepos="1:1-1:48" dir="auto"><a class="no-attachment-icon" href="https://gitlab.com/logo.png" target="_blank" rel="nofollow noreferrer noopener"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="" height="100px" decoding="async" class="lazy" data-src="https://gitlab.com/logo.png"></a></p>
+08_05_00__gitlab_internal_extension_markdown__image_attributes__004:
+  canonical: |
+    <p><img src="https://gitlab.com/logo.png" width="100" height="100"></p>
+  static: |-
+    <p data-sourcepos="1:1-1:60" dir="auto"><a class="no-attachment-icon" href="https://gitlab.com/logo.png" target="_blank" rel="nofollow noreferrer noopener"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="" width="100" height="100" decoding="async" class="lazy" data-src="https://gitlab.com/logo.png"></a></p>
+08_05_00__gitlab_internal_extension_markdown__image_attributes__005:
+  canonical: |
+    <p><img src="https://gitlab.com/logo.png"> {width="100" height="100"}</p>
+  static: |-
+    <p data-sourcepos="1:1-1:59" dir="auto"><a class="no-attachment-icon" href="https://gitlab.com/logo.png" target="_blank" rel="nofollow noreferrer noopener"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="" decoding="async" class="lazy" data-src="https://gitlab.com/logo.png"></a> {width="100" height="100"}</p>
diff --git a/glfm_specification/output_example_snapshots/markdown.yml b/glfm_specification/output_example_snapshots/markdown.yml
index 29fce0bccfb3bfe318873487566730ab9210ff29..c5145803088ba4b2f3d614ba252342ccc07c08f5 100644
--- a/glfm_specification/output_example_snapshots/markdown.yml
+++ b/glfm_specification/output_example_snapshots/markdown.yml
@@ -2547,3 +2547,13 @@
   ![Sample Video](https://gitlab.com/gitlab.mp4)
 08_04_52__gitlab_internal_extension_markdown__migrated_golden_master_examples__word_break__001: |
   Fernstraßen<wbr>bau<wbr>privat<wbr>finanzierungs<wbr>gesetz
+08_05_00__gitlab_internal_extension_markdown__image_attributes__001: |
+  ![](https://gitlab.com/logo.png){width="100" height="100"}
+08_05_00__gitlab_internal_extension_markdown__image_attributes__002: |
+  ![](https://gitlab.com/logo.png){width="100%"}
+08_05_00__gitlab_internal_extension_markdown__image_attributes__003: |
+  ![](https://gitlab.com/logo.png){height="100px"}
+08_05_00__gitlab_internal_extension_markdown__image_attributes__004: |
+  ![](https://gitlab.com/logo.png){ width="100" height="100" }
+08_05_00__gitlab_internal_extension_markdown__image_attributes__005: |
+  ![](https://gitlab.com/logo.png) {width="100" height="100"}
diff --git a/glfm_specification/output_example_snapshots/prosemirror_json.yml b/glfm_specification/output_example_snapshots/prosemirror_json.yml
index a654cacfca61396c59b7eda427ad735784f3dc07..db5c14dcf985cc99836b10c37f7b983c0900fd01 100644
--- a/glfm_specification/output_example_snapshots/prosemirror_json.yml
+++ b/glfm_specification/output_example_snapshots/prosemirror_json.yml
@@ -14577,6 +14577,8 @@
               "title": "*",
               "uploading": false,
               "canonicalSrc": "foo",
+              "width": null,
+              "height": null,
               "isReference": false
             }
           }
@@ -15723,6 +15725,8 @@
               "title": null,
               "uploading": false,
               "canonicalSrc": "moon.jpg",
+              "width": null,
+              "height": null,
               "isReference": false
             },
             "marks": [
@@ -15851,6 +15855,8 @@
               "title": null,
               "uploading": false,
               "canonicalSrc": "uri3",
+              "width": null,
+              "height": null,
               "isReference": false
             }
           }
@@ -16265,6 +16271,8 @@
               "title": null,
               "uploading": false,
               "canonicalSrc": "moon.jpg",
+              "width": null,
+              "height": null,
               "isReference": false
             },
             "marks": [
@@ -18112,6 +18120,8 @@
               "title": "title",
               "uploading": false,
               "canonicalSrc": "/url",
+              "width": null,
+              "height": null,
               "isReference": false
             }
           }
@@ -18134,6 +18144,8 @@
               "title": "train & tracks",
               "uploading": false,
               "canonicalSrc": "foo *bar*",
+              "width": null,
+              "height": null,
               "isReference": true
             }
           }
@@ -18170,6 +18182,8 @@
               "title": null,
               "uploading": false,
               "canonicalSrc": "/url2",
+              "width": null,
+              "height": null,
               "isReference": false
             }
           }
@@ -18192,6 +18206,8 @@
               "title": null,
               "uploading": false,
               "canonicalSrc": "/url2",
+              "width": null,
+              "height": null,
               "isReference": false
             }
           }
@@ -18214,6 +18230,8 @@
               "title": "train & tracks",
               "uploading": false,
               "canonicalSrc": "foo *bar*",
+              "width": null,
+              "height": null,
               "isReference": true
             }
           }
@@ -18250,6 +18268,8 @@
               "title": "train & tracks",
               "uploading": false,
               "canonicalSrc": "foobar",
+              "width": null,
+              "height": null,
               "isReference": true
             }
           }
@@ -18286,6 +18306,8 @@
               "title": null,
               "uploading": false,
               "canonicalSrc": "train.jpg",
+              "width": null,
+              "height": null,
               "isReference": false
             }
           }
@@ -18312,6 +18334,8 @@
               "title": "title",
               "uploading": false,
               "canonicalSrc": "/path/to/train.jpg",
+              "width": null,
+              "height": null,
               "isReference": false
             }
           }
@@ -18334,6 +18358,8 @@
               "title": null,
               "uploading": false,
               "canonicalSrc": "url",
+              "width": null,
+              "height": null,
               "isReference": false
             }
           }
@@ -18356,6 +18382,8 @@
               "title": null,
               "uploading": false,
               "canonicalSrc": "/url",
+              "width": null,
+              "height": null,
               "isReference": false
             }
           }
@@ -18378,6 +18406,8 @@
               "title": null,
               "uploading": false,
               "canonicalSrc": "bar",
+              "width": null,
+              "height": null,
               "isReference": true
             }
           }
@@ -18414,6 +18444,8 @@
               "title": null,
               "uploading": false,
               "canonicalSrc": "bar",
+              "width": null,
+              "height": null,
               "isReference": true
             }
           }
@@ -18450,6 +18482,8 @@
               "title": "title",
               "uploading": false,
               "canonicalSrc": "foo",
+              "width": null,
+              "height": null,
               "isReference": true
             }
           }
@@ -18486,6 +18520,8 @@
               "title": "title",
               "uploading": false,
               "canonicalSrc": "*foo* bar",
+              "width": null,
+              "height": null,
               "isReference": true
             }
           }
@@ -18522,6 +18558,8 @@
               "title": "title",
               "uploading": false,
               "canonicalSrc": "foo",
+              "width": null,
+              "height": null,
               "isReference": true
             }
           }
@@ -18558,6 +18596,8 @@
               "title": "title",
               "uploading": false,
               "canonicalSrc": "foo",
+              "width": null,
+              "height": null,
               "isReference": true
             }
           },
@@ -18598,6 +18638,8 @@
               "title": "title",
               "uploading": false,
               "canonicalSrc": "foo",
+              "width": null,
+              "height": null,
               "isReference": true
             }
           }
@@ -18634,6 +18676,8 @@
               "title": "title",
               "uploading": false,
               "canonicalSrc": "*foo* bar",
+              "width": null,
+              "height": null,
               "isReference": true
             }
           }
@@ -18694,6 +18738,8 @@
               "title": "title",
               "uploading": false,
               "canonicalSrc": "foo",
+              "width": null,
+              "height": null,
               "isReference": true
             }
           }
@@ -21025,6 +21071,8 @@
               "title": null,
               "uploading": false,
               "canonicalSrc": "/uploads/aa45a38ec2cfe97433281b10bbff042c/test-file.png",
+              "width": null,
+              "height": null,
               "isReference": false
             }
           }
@@ -21047,6 +21095,8 @@
               "title": null,
               "uploading": false,
               "canonicalSrc": "/uploads/aa45a38ec2cfe97433281b10bbff042c/test-file.png",
+              "width": null,
+              "height": null,
               "isReference": false
             }
           }
@@ -21069,6 +21119,8 @@
               "title": null,
               "uploading": false,
               "canonicalSrc": "test-file.png",
+              "width": null,
+              "height": null,
               "isReference": false
             }
           }
@@ -22751,6 +22803,8 @@
               "title": null,
               "uploading": false,
               "canonicalSrc": "https://gitlab.com/logo.png",
+              "width": null,
+              "height": null,
               "isReference": false
             }
           }
diff --git a/glfm_specification/output_example_snapshots/snapshot_spec.html b/glfm_specification/output_example_snapshots/snapshot_spec.html
index 8e18c768c7d1dc8735d3aa401d1fffe5f785049a..080712d1b4ebcc832b8c0794564d6490dec69e5d 100644
--- a/glfm_specification/output_example_snapshots/snapshot_spec.html
+++ b/glfm_specification/output_example_snapshots/snapshot_spec.html
@@ -363,6 +363,7 @@
 <li><a href="#word_break">word_break</a></li>
 </ul>
 </li>
+<li><a href="#image-attributes">Image Attributes</a></li>
 </ul>
 </li>
 </ul>
@@ -13477,6 +13478,74 @@ also requires an EE license enabling the <code>group_wikis</code> feature:</p>
 <copy-code></copy-code>
 </div>
 </div>
+<h2 data-sourcepos="15072:1-15072:19" dir="auto">
+<a id="user-content-image-attributes" class="anchor" href="#image-attributes" aria-hidden="true"></a>Image Attributes</h2>
+<p data-sourcepos="15074:1-15076:46" dir="auto">See
+<a href="https://docs.gitlab.com/ee/user/markdown.html#change-the-image-dimensions" rel="nofollow noreferrer noopener" target="_blank">Change the image dimensions</a>
+in the GitLab Flavored Markdown documentation.</p>
+<p data-sourcepos="15078:1-15079:19" dir="auto">The <code>width</code> and <code>height</code> attributes for an image can be specified directly after
+the image markdown.</p>
+<p data-sourcepos="15081:1-15083:21" dir="auto">General syntax conforms to the
+<a href="https://github.com/jgm/commonmark-hs/blob/master/commonmark-extensions/test/attributes.md" rel="nofollow noreferrer noopener" target="_blank">commonmark-hs attribute syntax</a>
+where it makes sense.</p>
+<div>
+<div><a href="#example-750">Example 750</a></div>
+<div class="gl-relative markdown-code-block js-markdown-code">
+<pre data-sourcepos="15088:1-15090:32" lang="plaintext" class="code highlight js-syntax-highlight language-plaintext" data-canonical-lang="example" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">![](https://gitlab.com/logo.png){width="100" height="100"}</span></code></pre>
+<copy-code></copy-code>
+</div>
+<div class="gl-relative markdown-code-block js-markdown-code">
+<pre data-sourcepos="15092:1-15094:32" lang="plaintext" class="code highlight js-syntax-highlight language-plaintext" data-canonical-lang="" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">&lt;p&gt;&lt;img src="https://gitlab.com/logo.png" width="100" height="100"&gt;&lt;/p&gt;</span></code></pre>
+<copy-code></copy-code>
+</div>
+</div>
+<p data-sourcepos="15097:1-15097:41" dir="auto"><code>%</code> and <code>px</code> units may also be specified.</p>
+<div>
+<div><a href="#example-751">Example 751</a></div>
+<div class="gl-relative markdown-code-block js-markdown-code">
+<pre data-sourcepos="15102:1-15104:32" lang="plaintext" class="code highlight js-syntax-highlight language-plaintext" data-canonical-lang="example" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">![](https://gitlab.com/logo.png){width="100%"}</span></code></pre>
+<copy-code></copy-code>
+</div>
+<div class="gl-relative markdown-code-block js-markdown-code">
+<pre data-sourcepos="15106:1-15108:32" lang="plaintext" class="code highlight js-syntax-highlight language-plaintext" data-canonical-lang="" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">&lt;p&gt;&lt;img src="https://gitlab.com/logo.png" width="100%"&gt;&lt;/p&gt;</span></code></pre>
+<copy-code></copy-code>
+</div>
+</div>
+<div>
+<div><a href="#example-752">Example 752</a></div>
+<div class="gl-relative markdown-code-block js-markdown-code">
+<pre data-sourcepos="15114:1-15116:32" lang="plaintext" class="code highlight js-syntax-highlight language-plaintext" data-canonical-lang="example" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">![](https://gitlab.com/logo.png){height="100px"}</span></code></pre>
+<copy-code></copy-code>
+</div>
+<div class="gl-relative markdown-code-block js-markdown-code">
+<pre data-sourcepos="15118:1-15120:32" lang="plaintext" class="code highlight js-syntax-highlight language-plaintext" data-canonical-lang="" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">&lt;p&gt;&lt;img src="https://gitlab.com/logo.png" height="100px"&gt;&lt;/p&gt;</span></code></pre>
+<copy-code></copy-code>
+</div>
+</div>
+<p data-sourcepos="15123:1-15123:46" dir="auto">Whitespace is tolerated around the delimiters:</p>
+<div>
+<div><a href="#example-753">Example 753</a></div>
+<div class="gl-relative markdown-code-block js-markdown-code">
+<pre data-sourcepos="15128:1-15130:32" lang="plaintext" class="code highlight js-syntax-highlight language-plaintext" data-canonical-lang="example" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">![](https://gitlab.com/logo.png){ width="100" height="100" }</span></code></pre>
+<copy-code></copy-code>
+</div>
+<div class="gl-relative markdown-code-block js-markdown-code">
+<pre data-sourcepos="15132:1-15134:32" lang="plaintext" class="code highlight js-syntax-highlight language-plaintext" data-canonical-lang="" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">&lt;p&gt;&lt;img src="https://gitlab.com/logo.png" width="100" height="100"&gt;&lt;/p&gt;</span></code></pre>
+<copy-code></copy-code>
+</div>
+</div>
+<p data-sourcepos="15137:1-15137:54" dir="auto">Attributes must immediately follow the image markdown.</p>
+<div>
+<div><a href="#example-754">Example 754</a></div>
+<div class="gl-relative markdown-code-block js-markdown-code">
+<pre data-sourcepos="15142:1-15144:32" lang="plaintext" class="code highlight js-syntax-highlight language-plaintext" data-canonical-lang="example" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">![](https://gitlab.com/logo.png) {width="100" height="100"}</span></code></pre>
+<copy-code></copy-code>
+</div>
+<div class="gl-relative markdown-code-block js-markdown-code">
+<pre data-sourcepos="15146:1-15148:32" lang="plaintext" class="code highlight js-syntax-highlight language-plaintext" data-canonical-lang="" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">&lt;p&gt;&lt;img src="https://gitlab.com/logo.png"&gt; {width="100" height="100"}&lt;/p&gt;</span></code></pre>
+<copy-code></copy-code>
+</div>
+</div>
 
 </body>
 </html>
diff --git a/glfm_specification/output_example_snapshots/snapshot_spec.md b/glfm_specification/output_example_snapshots/snapshot_spec.md
index 8898857ba45ddab6d9174658dab52244e37a73c4..ccee9c1707e6a72cccb38427d7fc9762c63f5253 100644
--- a/glfm_specification/output_example_snapshots/snapshot_spec.md
+++ b/glfm_specification/output_example_snapshots/snapshot_spec.md
@@ -10576,3 +10576,53 @@ Fernstraßen<wbr>bau<wbr>privat<wbr>finanzierungs<wbr>gesetz
 .
 TODO: Write canonical HTML for this example
 ````````````````````````````````
+
+## Image Attributes
+
+See
+[Change the image dimensions](https://docs.gitlab.com/ee/user/markdown.html#change-the-image-dimensions)
+in the GitLab Flavored Markdown documentation.
+
+The `width` and `height` attributes for an image can be specified directly after
+the image markdown.
+
+General syntax conforms to the 
+[commonmark-hs attribute syntax](https://github.com/jgm/commonmark-hs/blob/master/commonmark-extensions/test/attributes.md)
+where it makes sense.
+
+```````````````````````````````` example gitlab
+![](https://gitlab.com/logo.png){width="100" height="100"}
+.
+<p><img src="https://gitlab.com/logo.png" width="100" height="100"></p>
+````````````````````````````````
+
+`%` and `px` units may also be specified.
+
+```````````````````````````````` example gitlab
+![](https://gitlab.com/logo.png){width="100%"}
+.
+<p><img src="https://gitlab.com/logo.png" width="100%"></p>
+````````````````````````````````
+
+```````````````````````````````` example gitlab
+![](https://gitlab.com/logo.png){height="100px"}
+.
+<p><img src="https://gitlab.com/logo.png" height="100px"></p>
+````````````````````````````````
+
+Whitespace is tolerated around the delimiters:
+
+```````````````````````````````` example gitlab
+![](https://gitlab.com/logo.png){ width="100" height="100" }
+.
+<p><img src="https://gitlab.com/logo.png" width="100" height="100"></p>
+````````````````````````````````
+
+Attributes must immediately follow the image markdown.
+
+```````````````````````````````` example gitlab
+![](https://gitlab.com/logo.png) {width="100" height="100"}
+.
+<p><img src="https://gitlab.com/logo.png"> {width="100" height="100"}</p>
+````````````````````````````````
+
diff --git a/spec/frontend/content_editor/services/markdown_serializer_spec.js b/spec/frontend/content_editor/services/markdown_serializer_spec.js
index a29678ff1bcf4a762277dec0194339199ac5cd52..90551065ee43914ca79d7d285e6ab1be9485cbd7 100644
--- a/spec/frontend/content_editor/services/markdown_serializer_spec.js
+++ b/spec/frontend/content_editor/services/markdown_serializer_spec.js
@@ -380,6 +380,26 @@ this is not really json but just trying out whether this case works or not
     );
   });
 
+  it.each`
+    width        | height       | outputAttributes
+    ${300}       | ${undefined} | ${'width=300'}
+    ${undefined} | ${300}       | ${'height=300'}
+    ${300}       | ${300}       | ${'width=300 height=300'}
+    ${'300%'}    | ${'300px'}   | ${'width="300%" height="300px"'}
+  `(
+    'correctly serializes an image with width and height attributes',
+    ({ width, height, outputAttributes }) => {
+      const imageAttrs = { src: 'img.jpg', alt: 'foo bar' };
+
+      if (width) imageAttrs.width = width;
+      if (height) imageAttrs.height = height;
+
+      expect(serialize(paragraph(image(imageAttrs)))).toBe(
+        `![foo bar](img.jpg){${outputAttributes}}`,
+      );
+    },
+  );
+
   it('does not serialize an image when src and canonicalSrc are empty', () => {
     expect(serialize(paragraph(image({})))).toBe('');
   });