Repository navigation
Image block: $/\ in img alt or src corrupted in lightbox markup (preg_replace backreference) #79368
Description
Description
Description
block_core_image_render_lightbox() injects the lightbox trigger button by
calling:
$body_content = preg_replace( '/<img[^>]+>/', $button, $body_content );where $button begins with the matched <img> tag ($img[0]), which embeds
author/user-controlled attribute values (src, alt, title, class).
In a preg_replace() replacement string, the sequences $0, $1, ${1},
\0, \1, … are interpreted as backreferences. So when an image's alt text
or filename contains such a sequence, it is silently rewritten — a reference
to a non-existent capture group is replaced with an empty string — producing
broken alt/src in the rendered lightbox.
This is not XSS (output remains attribute-escaped), but it visibly mangles
legitimate content and is hard for site owners to diagnose.
Step-by-step reproduction
- Add an Image block to a post and enable its lightbox (Expand on click).
- Set the alt text to
Only $1 today(or use an image whose filename
contains$1, e.g.price-$1.jpg). - View the post on the front end.
- Inspect the rendered
<img>: the$1is gone, e.g.alt="Only today".
Expected behaviour
The alt text and src should render exactly as authored, regardless of any
$N/\N sequences they contain.
Actual behaviour
Any $N/\N sequence in an img attribute is stripped/corrupted in the
lightbox output because it is treated as a regex backreference.
Proposed fix
A core/image block contains exactly one <img>, so a literal replacement
is sufficient and safe:
if ( isset( $img[0] ) ) {
$body_content = str_replace( $img[0], $button, $body_content );
}(Alternatively, inject the button through the existing WP_HTML_Tag_Processor
flow instead of regex.)
Environment
- WordPress:
- Gutenberg: <version, if applicable>
- File:
wp-includes/blocks/image.php—block_core_image_render_lightbox()
Step-by-step reproduction instructions
- Add an Image block to a post and enable its lightbox (Expand on click).
- Set the alt text to
Only $1 today(or use an image whose filename
contains$1, e.g.price-$1.jpg). - View the post on the front end.
- Inspect the rendered
<img>: the$1is gone, e.g.alt="Only today".
Screenshots, screen recording, code snippet
No response
Environment info
No response
Please confirm that you have searched existing issues in the repo.
- Yes
Please confirm that you have tested with all plugins deactivated except Gutenberg.
- Yes
Please confirm which theme type you used for testing.
- Block
- Classic
- Hybrid (e.g. classic with theme.json)
- Not sure
Activity