Skip to content
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

Experimental: Add sandboxing levels #6546

Merged
merged 90 commits into from
Oct 13, 2021
Merged
Show file tree
Hide file tree
Changes from 56 commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
fb612c2
Add initial sandboxing levels
westonruter Aug 18, 2021
73869b6
Opt-in to new script sanitizer and allowing post forms even in level 3
westonruter Aug 18, 2021
c1f6a7e
Prevent service from running during unit tests (for now)
westonruter Aug 18, 2021
847b432
Fix AMP_Script_Sanitizer arg key
westonruter Aug 23, 2021
d615b57
Discontinue overloading data-ampdevmode in favor of specific flags fo…
westonruter Aug 23, 2021
7aa81d6
Default sandboxing to off, requiring filter to enable instead of WP_D…
westonruter Aug 24, 2021
e988c54
Set order for sanitizers to run in
westonruter Aug 25, 2021
bb3d682
Prefer bento from script sanitizer when custom scripts kept
westonruter Aug 25, 2021
a9bab8a
Move logic to set unvalidated attrs to base removal methods
westonruter Aug 25, 2021
cfcd5d8
Dynamically switch to Bento when non-valid document and when Bento co…
westonruter Aug 25, 2021
e4e2301
Remove bento as automatically triggering dev mode
westonruter Aug 26, 2021
a163249
Add todos to revisit in future
westonruter Aug 26, 2021
a840c88
Conditionally add document.write override only if amp-live-list is in…
westonruter Aug 26, 2021
7aa7d09
Introduce native_video_used arg for AMP_Video_Sanitizer
westonruter Aug 26, 2021
12da9c7
Introduce native_audio_used arg for AMP_Audio_Sanitizer
westonruter Aug 26, 2021
5570f16
Use native audio/video elements when custom scripts are kept
westonruter Aug 26, 2021
a6f2647
Indicate sandboxing level in AMP meta generator
westonruter Aug 27, 2021
793beb4
Use native iframes when custom scripts are kept
westonruter Aug 27, 2021
4fc05bc
Add test to ensure that the script sanitizer sets prefer_bento
westonruter Aug 27, 2021
f45aec6
Reduce code duplication
westonruter Aug 27, 2021
de4d94a
Initial success with comment reply links
westonruter Aug 28, 2021
d250f6f
Simplify state
westonruter Aug 28, 2021
bdc94ab
Focus on comment textarea when clicking on reply
westonruter Aug 28, 2021
e8f66e5
Remove commented-out code and add deprecations
westonruter Aug 28, 2021
6245411
Update comment
westonruter Aug 29, 2021
5d42136
Mark script output from wp_comment_form_unfiltered_html_nonce() as be…
westonruter Sep 1, 2021
758c53a
Run core theme sanitizer before script sanitizer
westonruter Sep 2, 2021
99893db
Greatly simplify thread_comments handling in comment sanitizer
westonruter Sep 2, 2021
0295046
Only unwrap noscripts when no PX-verified scripts present either
westonruter Sep 2, 2021
ca10637
Prevent removal of PX-validated custom tags
westonruter Sep 2, 2021
015bf10
Remove amp attribute from pages containing PX-verified attrs
westonruter Sep 2, 2021
f91fa9d
Rework form sanitizer to always leave POST forms alone or convert
westonruter Sep 2, 2021
cf2272b
Test keeping non-AMP custom elements and prevent double reporting
westonruter Sep 2, 2021
ade01cf
Remove completed todos
westonruter Sep 2, 2021
dad92a8
Fix typo in comments_live_list
westonruter Sep 2, 2021
a294249
Introduce ValidationExemption class to centralize AMP-unvalidated and…
westonruter Sep 2, 2021
80fb303
Invert logic
westonruter Sep 3, 2021
da5a3ff
Improve test coverage of sanitizers and theme-support
westonruter Sep 3, 2021
b035e62
Add tests for remove_invalid_attribute
westonruter Sep 3, 2021
a5e94b0
Rewrite comments sanitizer tests
westonruter Sep 3, 2021
8349c56
Add tests for AMP_Script_Sanitizer
westonruter Sep 3, 2021
b512764
Add coverage for replace_node_with_children_validation_errors
westonruter Sep 3, 2021
26d8606
Eliminate nodes_to_keep in favor of using data-amp-unvalidated-tag at…
westonruter Sep 3, 2021
8a1d3b5
Add tests for SandboxingLevels minus the add_hooks method
westonruter Sep 3, 2021
669da7e
Add tests for SandboxingLevels::add_hooks()
westonruter Sep 3, 2021
346867c
Add tests for ValidationExemption
westonruter Sep 3, 2021
13ad904
Fix test failures
westonruter Sep 3, 2021
0a24032
Remove obsolete arg from test
westonruter Sep 3, 2021
925cbe7
Improve conditionality of including comment-reply
westonruter Sep 4, 2021
8aab322
Tidy up script and comments sanitier changes
westonruter Sep 4, 2021
74b49a0
Update testing logic for changes in AMP_Comments_Sanitizer
westonruter Sep 4, 2021
6bf5c78
Remove dead code and improve structure of comments sanitizer
westonruter Sep 4, 2021
54f57b9
Only normalize form targets on non-native forms; fix form tests
westonruter Sep 4, 2021
2ac066c
Use native forms when PX-verified scripts are found as well as AMP-un…
westonruter Sep 4, 2021
fc63b82
Fix SandboxingLevelsTest and Test_AMP_Theme_Support
westonruter Sep 4, 2021
8be564f
Fix test_add_amp_live_list_comment_attributes for WP<5.2
westonruter Sep 4, 2021
4a81cc8
Merge branch 'develop' of github.com:ampproject/amp-wp into add/sandb…
westonruter Sep 21, 2021
a75b23d
Improve conditions for DOM objects
westonruter Sep 21, 2021
96a4c11
Optimize conditionals in ValidationExemption
westonruter Sep 21, 2021
826a564
Add note about temporalness of filter
westonruter Sep 21, 2021
8e137db
Rename SandboxingLevels to just Sandboxing
westonruter Sep 21, 2021
a561a2c
Remove redundant SANDBOXING prefix
westonruter Sep 21, 2021
dc2f88f
Annotate native markup as PX-verified not AMP-unvalidated
westonruter Sep 21, 2021
989af80
Merge branch 'develop' of github.com:ampproject/amp-wp into add/sandb…
westonruter Sep 21, 2021
19c3c12
Add PX-verified and AMP-unvalidated attributes based on !important qu…
westonruter Sep 22, 2021
98025a7
Fix covers tag
westonruter Sep 28, 2021
a73b84a
Remove needless looping over sanitizers
westonruter Sep 28, 2021
f99c56b
Bump parsed stylesheet cache group
westonruter Sep 22, 2021
5961514
Add allow_excessive_css argument to AMP_Style_Sanitizer
westonruter Sep 28, 2021
78684ae
Remove make_http_url_schemeless dead code
westonruter Sep 28, 2021
d651b45
Reset changes before calling tearDown
westonruter Sep 30, 2021
e1c7570
Merge branch 'develop' of github.com:ampproject/amp-wp into add/sandb…
westonruter Sep 30, 2021
fd32008
Use xpath instead of getElementById
westonruter Sep 30, 2021
4e5e4fd
Add covers phpdoc tag to test_ampify_threaded_comments
westonruter Sep 30, 2021
6c22fcd
Improve test coverage for AMP_Script_Sanitizer
westonruter Sep 30, 2021
7ac935a
Fix sanitization of keyframes outside of style[amp-keyframes]
westonruter Sep 30, 2021
d604e28
Improve test coverage for ValidationExemption
westonruter Sep 30, 2021
219c4f7
Merge branch 'develop' of github.com:ampproject/amp-wp into add/sandb…
westonruter Sep 30, 2021
9fbb876
Add test coverage for allowlisted properties in CSS declaration block
westonruter Sep 30, 2021
1a0454b
Add test coverage for invalid at-rule inside keyframes
westonruter Sep 30, 2021
85ace0f
Work around coverage decrease by adding covers tags for private metho…
westonruter Sep 30, 2021
707550a
Remove empty style attributes add style sanitizer test coverage
westonruter Sep 30, 2021
e1c81c2
Add additional covers tags for private methods in audio, iframe, and …
westonruter Sep 30, 2021
5b60903
Add test coverage for AMP_Validation_Error_Taxonomy::get_error_title_…
westonruter Oct 1, 2021
9b304e1
Add yet more covers tags for private methods in style sanitizer
westonruter Oct 1, 2021
c1dde99
Opt to disable stylesheet processing when in level 1
westonruter Oct 1, 2021
bd54a6f
Make ValidationExemption more DRY and performant
westonruter Oct 2, 2021
4cdaabb
Add effective sandboxing level to meta generator and admin bar
westonruter Oct 4, 2021
502873c
Fix grammar typos in comment
westonruter Oct 13, 2021
faaf295
Merge branch 'develop' of github.com:ampproject/amp-wp into add/sandb…
westonruter Oct 13, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .phpstorm.meta.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
'reader_theme_support_features' => \AmpProject\AmpWP\ReaderThemeSupportFeatures::class,
'rest.options_controller' => \AmpProject\AmpWP\OptionsRESTController::class,
'rest.validation_counts_controller' => \AmpProject\AmpWP\Validation\ValidationCountsRestController::class,
'sandboxing_levels' => \AmpProject\AmpWP\SandboxingLevels::class,
'save_post_validation_event' => \AmpProject\AmpWP\Validation\SavePostValidationEvent::class,
'server_timing' => \AmpProject\AmpWP\Instrumentation\ServerTiming::class,
'site_health_integration' => \AmpProject\AmpWP\Admin\SiteHealth::class,
Expand Down
67 changes: 65 additions & 2 deletions assets/src/settings-page/template-modes.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ function getReaderNotice( selected ) {
* @param {boolean} props.focusReaderThemes Whether the reader themes drawer should be opened and focused.
*/
export function TemplateModes( { focusReaderThemes } ) {
const { editedOptions } = useContext( Options );
const { editedOptions, updateOptions } = useContext( Options );
const { selectedTheme, templateModeWasOverridden } = useContext( ReaderThemes );

const { theme_support: themeSupport } = editedOptions;
const { theme_support: themeSupport, sandboxing_level: sandboxingLevel } = editedOptions;

const { readerNoticeSmall, readerNoticeLarge } = useMemo(
() => getReaderNotice( READER === themeSupport ),
Expand Down Expand Up @@ -138,6 +138,69 @@ export function TemplateModes( { focusReaderThemes } ) {
</AMPNotice>
)
}
{
sandboxingLevel && (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the template mode option drawer should initially be open if Standard mode is selected? Otherwise it might be hard for the user to find where these "Sandboxing Levels" are.

<fieldset>
<h4 className="title">
{ __( 'Sandboxing Level (Experimental)', 'amp' ) }
</h4>
<p>
{ __( 'Try out a more flexible AMP by generating pages that use AMP components without requiring AMP validity! By selecting a sandboxing level, you are indicating the minimum degree of sanitization. For example, if you selected level 1 but have a page without any POST form and no custom scripts, it will still be served as valid AMP, the same as if you had selected level 3.', 'amp' ) }
</p>
<ol>
<li>
<input
type="radio"
id="sandboxing-level-1"
checked={ 1 === sandboxingLevel }
onChange={ () => {
updateOptions( { sandboxing_level: 1 } );
} }
/>
<label htmlFor="sandboxing-level-1">
<strong>
{ __( 'Loose:', 'amp' ) }
</strong>
{ ' ' + __( 'Do not remove any AMP-invalid markup by default, including custom scripts. CSS tree-shaking is disabled.', 'amp' ) }
</label>
</li>
<li>
<input
type="radio"
id="sandboxing-level-2"
checked={ 2 === sandboxingLevel }
onChange={ () => {
updateOptions( { sandboxing_level: 2 } );
} }
/>
<label htmlFor="sandboxing-level-2">
<strong>
{ __( 'Moderate:', 'amp' ) }
</strong>
{ ' ' + __( 'Remove non-AMP markup, but allow POST forms. CSS tree shaking is enabled.', 'amp' ) }
</label>
</li>
<li>
<input
type="radio"
id="sandboxing-level-3"
checked={ 3 === sandboxingLevel }
onChange={ () => {
updateOptions( { sandboxing_level: 3 } );
} }
/>
<label htmlFor="sandboxing-level-3">
<strong>
{ __( 'Strict:', 'amp' ) }
</strong>
{ ' ' + __( 'Require valid AMP.', 'amp' ) }
</label>
</li>

</ol>
</fieldset>
)
}
</TemplateModeOption>
<TemplateModeOption
details={ __( 'In Transitional mode the active theme\'s templates are used to generate both the AMP and non-AMP versions of your content, allowing for each canonical URL to have a corresponding (paired) AMP URL. This mode is useful to progressively transition towards a fully AMP-compatible site. Depending on your themes/plugins, a varying level of development work may be required.', 'amp' ) }
Expand Down
89 changes: 48 additions & 41 deletions includes/amp-helper-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,16 @@ function amp_add_generator_metadata() {
$content .= sprintf( '; theme=%s', $reader_theme );
}

/**
* Filters content for the AMP meta generator tag.
*
* @since 2.2
* @internal
*
* @param string $content Content.
*/
$content = apply_filters( 'amp_meta_generator', $content );

printf( '<meta name="generator" content="%s">', esc_attr( $content ) );
}

Expand Down Expand Up @@ -1380,10 +1390,6 @@ function amp_is_dev_mode() {
( is_admin_bar_showing() && is_user_logged_in() )
||
is_customize_preview()
||
// Force dev mode for Bento since it currently requires the Bento experiment opt-in script.
// @todo Remove this once Bento no longer requires an experiment to opt-in. See <https://amp.dev/documentation/guides-and-tutorials/start/bento_guide/?format=websites#enable-bento-experiment>.
amp_is_bento_enabled()
)
);
}
Expand All @@ -1410,26 +1416,6 @@ function amp_is_native_img_used() {
return (bool) apply_filters( 'amp_native_img_used', false );
}

/**
* Determine whether to allow native `POST` forms without conversion to use the `action-xhr` attribute and use the amp-form component.
*
* @since 2.2
* @link https://github.com/ampproject/amphtml/issues/27638
*
* @return bool Whether to allow native `POST` forms.
*/
function amp_is_native_post_form_allowed() {
/**
* Filters whether to allow native `POST` forms without conversion to use the `action-xhr` attribute and use the amp-form component.
*
* @since 2.2
* @link https://github.com/ampproject/amphtml/issues/27638
*
* @param bool $use_native Whether to allow native `POST` forms.
*/
return (bool) apply_filters( 'amp_native_post_form_allowed', false );
}

/**
* Get content sanitizers.
*
Expand Down Expand Up @@ -1474,18 +1460,16 @@ function amp_get_content_sanitizers( $post = null ) {
AMP_Theme_Support::TRANSITIONAL_MODE_SLUG === AMP_Options_Manager::get_option( Option::THEME_SUPPORT )
);

$native_img_used = amp_is_native_img_used();
$native_post_forms_allowed = amp_is_native_post_form_allowed();
$native_img_used = amp_is_native_img_used();

$sanitizers = [
// The AMP_Script_Sanitizer runs first because based on whether it allows custom scripts
// to be kept, it may impact the behavior of other sanitizers. For example, if custom
// scripts are kept then this is a signal that tree shaking in AMP_Style_Sanitizer cannot be
// performed.
AMP_Script_Sanitizer::class => [],
// Embed sanitization must come first because it strips out custom scripts associated with embeds.
AMP_Embed_Sanitizer::class => [
'amp_to_amp_linking_enabled' => $amp_to_amp_linking_enabled,
],
AMP_O2_Player_Sanitizer::class => [],
AMP_Playbuzz_Sanitizer::class => [],

AMP_Core_Theme_Sanitizer::class => [
'template' => get_template(),
'stylesheet' => get_stylesheet(),
Expand All @@ -1494,21 +1478,25 @@ function amp_get_content_sanitizers( $post = null ) {
],
'native_img_used' => $native_img_used,
],

AMP_Comments_Sanitizer::class => [
'comments_live_list' => ! empty( $theme_support_args['comments_live_list'] ),
],

// The AMP_Script_Sanitizer runs here because based on whether it allows custom scripts
// to be kept, it may impact the behavior of other sanitizers. For example, if custom
// scripts are kept then this is a signal that tree shaking in AMP_Style_Sanitizer cannot be
// performed.
AMP_Script_Sanitizer::class => [],

AMP_Srcset_Sanitizer::class => [],
AMP_Img_Sanitizer::class => [
'align_wide_support' => current_theme_supports( 'align-wide' ),
'native_img_used' => $native_img_used,
],
AMP_Form_Sanitizer::class => [
'native_post_forms_allowed' => $native_post_forms_allowed,
],
AMP_Comments_Sanitizer::class => [
'comments_live_list' => ! empty( $theme_support_args['comments_live_list'] ),
],
AMP_Form_Sanitizer::class => [],
AMP_Video_Sanitizer::class => [],
AMP_O2_Player_Sanitizer::class => [],
AMP_Audio_Sanitizer::class => [],
AMP_Playbuzz_Sanitizer::class => [],
AMP_Object_Sanitizer::class => [],
AMP_Iframe_Sanitizer::class => [
'add_placeholder' => true,
Expand Down Expand Up @@ -1626,8 +1614,27 @@ function amp_get_content_sanitizers( $post = null ) {
*/
$sanitizers[ AMP_Style_Sanitizer::class ]['allow_transient_caching'] = apply_filters( 'amp_parsed_css_transient_caching_allowed', true );

// Force layout, style, meta, and validating sanitizers to be at the end.
foreach ( [ AMP_Layout_Sanitizer::class, AMP_Style_Sanitizer::class, AMP_Meta_Sanitizer::class, AMP_Tag_And_Attribute_Sanitizer::class ] as $class_name ) {
// Force core essential sanitizers to appear at the end at the end, with non-essential and third-party sanitizers appearing before.
$expected_final_sanitizer_order = [
AMP_Core_Theme_Sanitizer::class, // Must come before script sanitizer since onclick attributes are removed.
AMP_Script_Sanitizer::class, // Must come before sanitizers for images, videos, audios, comments, forms, and styles.
AMP_Form_Sanitizer::class, // Must come before comments sanitizer.
AMP_Comments_Sanitizer::class, // Also must come after the form sanitizer.
AMP_Srcset_Sanitizer::class,
AMP_Img_Sanitizer::class,
AMP_Video_Sanitizer::class,
AMP_Audio_Sanitizer::class,
AMP_Object_Sanitizer::class,
AMP_Iframe_Sanitizer::class,
AMP_Gallery_Block_Sanitizer::class,
AMP_Block_Sanitizer::class,
AMP_Accessibility_Sanitizer::class,
AMP_Layout_Sanitizer::class,
AMP_Style_Sanitizer::class,
AMP_Meta_Sanitizer::class,
AMP_Tag_And_Attribute_Sanitizer::class,
];
foreach ( $expected_final_sanitizer_order as $class_name ) {
if ( isset( $sanitizers[ $class_name ] ) ) {
$sanitizer = $sanitizers[ $class_name ];
unset( $sanitizers[ $class_name ] );
Expand Down
Loading