-
Notifications
You must be signed in to change notification settings - Fork 0
Autorise le collage d'un code iframe dans l'éditeur #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e2ca50c
8afe4eb
2dddd7e
5615002
fdffb96
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,5 @@ | ||
| {} | ||
| { | ||
| "plugins": [ | ||
| "." | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,4 +11,9 @@ | |
| width: 100%; | ||
| height: 100%; | ||
| } | ||
|
|
||
| &:not(.has-aspect-ratio) { | ||
| aspect-ratio: 1; | ||
| min-height: unset; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,137 @@ | ||
| /** | ||
| * Utility functions for iframe attribute handling. | ||
| */ | ||
|
|
||
| /** | ||
| * Map HTML attribute names to React prop names. | ||
| * | ||
| * @param {string} attributeName - The HTML attribute name. | ||
| * @return {string} The React prop name. | ||
| */ | ||
| export function mapHtmlAttributeToReact( attributeName ) { | ||
| const attributeMap = { | ||
| allowfullscreen: 'allowFullScreen', | ||
| allowpaymentrequest: 'allowPaymentRequest', | ||
| referrerpolicy: 'referrerPolicy', | ||
| }; | ||
|
|
||
| return attributeMap[ attributeName.toLowerCase() ] || attributeName; | ||
| } | ||
|
|
||
| /** | ||
| * Check if an attribute is a boolean HTML attribute. | ||
| * | ||
| * @param {string} attributeName - The name of the attribute to check. | ||
| * @return {boolean} True if the attribute is boolean, false otherwise. | ||
| */ | ||
| export function isBooleanAttribute( attributeName ) { | ||
| const booleanAttrs = [ 'allowfullscreen', 'allowpaymentrequest' ]; | ||
|
|
||
| return booleanAttrs.includes( attributeName.toLowerCase() ); | ||
| } | ||
|
|
||
| /** | ||
| * Convert iframe attributes array to props object for React. | ||
| * Handles boolean attributes and React prop name mapping correctly. | ||
| * | ||
| * @param {Array} attributes - Array of {key, value} objects. | ||
| * @return {Object} Props object for React component. | ||
| */ | ||
| export function convertAttributesToProps( attributes ) { | ||
| return Object.fromEntries( | ||
| ( attributes || [] ).map( ( attr ) => { | ||
| // Map HTML attribute name to React prop name | ||
| const propName = mapHtmlAttributeToReact( attr.key ); | ||
|
|
||
| // Convert 'true' string to boolean for boolean attributes | ||
| const value = | ||
| isBooleanAttribute( attr.key ) && attr.value === 'true' | ||
| ? true | ||
| : attr.value; | ||
|
|
||
| return [ propName, value ]; | ||
| } ) | ||
| ); | ||
| } | ||
|
|
||
| /** | ||
| * Check if an iframe attribute should be excluded. | ||
| * | ||
| * @param {string} attributeName - The name of the attribute to check. | ||
| * @return {boolean} True if the attribute should be excluded, false otherwise. | ||
| */ | ||
| export function isExcludedIframeAttribute( attributeName ) { | ||
| const excludedAttrs = [ | ||
| 'src', // Managed separately | ||
| 'loading', // Managed by lazyload option | ||
| 'title', // Managed separately | ||
| 'width', // Managed by block dimension supports | ||
| 'height', // Managed by block dimension supports | ||
| 'style', // Requires object format in React, not string | ||
| 'frameborder', // Deprecated HTML attribute | ||
| 'marginwidth', // Deprecated HTML attribute | ||
| 'marginheight', // Deprecated HTML attribute | ||
| 'scrolling', // Deprecated HTML attribute | ||
| 'align', // Deprecated HTML attribute | ||
| 'longdesc', // Deprecated HTML attribute | ||
| 'name', // Can cause conflicts | ||
| ]; | ||
|
|
||
| return excludedAttrs.includes( attributeName.toLowerCase() ); | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfiltered iframe attributes allow potential XSS attacksHigh Severity The Additional Locations (1) |
||
|
|
||
| /** | ||
| * Parse iframe HTML code and extract src URL, title, and attributes. | ||
| * | ||
| * @param {string} value - The value that could be a URL or iframe HTML code. | ||
| * @return {Object|null} Object with url, title, and attributes array, or null if not an iframe. | ||
| */ | ||
| export function parseIframeCode( value ) { | ||
| // Check if the value contains iframe tag | ||
| const iframeRegex = /<iframe[^>]*>/i; | ||
| const match = value.match( iframeRegex ); | ||
|
|
||
| if ( ! match ) { | ||
| return null; | ||
| } | ||
|
|
||
| // Extract only the opening tag (ignore any content inside iframe) | ||
| const iframeTag = match[ 0 ]; | ||
|
|
||
| // Create a temporary DOM element to parse the HTML | ||
| // Use a self-closing iframe to avoid parsing issues with content | ||
| const tempDiv = document.createElement( 'div' ); | ||
| tempDiv.insertAdjacentHTML( 'beforeend', iframeTag + '</iframe>' ); | ||
| const iframeElement = tempDiv.querySelector( 'iframe' ); | ||
|
|
||
| if ( ! iframeElement ) { | ||
| return null; | ||
| } | ||
|
|
||
| // Extract src attribute | ||
| const src = iframeElement.getAttribute( 'src' ) || ''; | ||
|
|
||
| // Extract title attribute | ||
| const title = iframeElement.getAttribute( 'title' ) || ''; | ||
|
|
||
| // Extract all other attributes (excluding managed and deprecated ones) | ||
| const attributes = []; | ||
|
|
||
| for ( const attr of iframeElement.attributes ) { | ||
| if ( ! isExcludedIframeAttribute( attr.name ) ) { | ||
| // For boolean attributes, store 'true' as value if present | ||
| const value = isBooleanAttribute( attr.name ) ? 'true' : attr.value; | ||
|
|
||
| attributes.push( { | ||
| key: attr.name, | ||
| value, | ||
| } ); | ||
| } | ||
| } | ||
|
|
||
| return { | ||
| url: src, | ||
| title, | ||
| attributes, | ||
| }; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Editing URL clears previously extracted iframe attributes
Medium Severity
When iframe code is pasted, the URL is extracted and shown in the input field while
iframeAttributesstores the parsed attributes. If the user then modifies the URL in any way (even a small edit),handleUrlChangeno longer recognizes it as iframe code and setsiframeAttributes: [], silently discarding all previously extracted attributes likeallowfullscreenorallow. This causes unexpected loss of iframe functionality when users make minor URL corrections.